const char *
u_signal_names(const char *str_sig, int *signo, int startnum)
{
	static char retstr[16];
	const struct signal_name *s = signames;
	static const char prefix[] = "SIG";
	const char *sptr;

	if(startnum)
		s++;
	if(str_sig==NULL) {
		while (s->name != 0) {
			if(s->number == *signo)
				break;
			s++;
		}
	} else {
		if (isdigit(((unsigned char)*str_sig))) {
			char *endp;
			long int sn = strtol(str_sig, &endp, 10);
			/* test correct and overflow */
			if(*endp == 0 && sn >= 0 && sn < NSIG) {
				*signo = (int)sn;
				/* test for unnamed */
				sptr = u_signal_names(0, signo, 0);
				if(sptr==NULL)
					return NULL;
				if(sn!=0)
					sptr += 3;
				return sptr;
			}
		} else {
			sptr = str_sig;
			while (s->name != 0) {
				if (strcasecmp(s->name, sptr) == 0) {
					*signo = s->number;
					if(startnum<0) {
						sprintf(retstr, "%d", *signo);
						return retstr;
					}
					break;
				}
				if(s!=signames && sptr == str_sig &&
						strncasecmp(sptr, prefix, 3) == 0) {
					sptr += 3;      /* strlen(prefix) */
					continue;
				}
				sptr = str_sig;
				s++;
			}
		}
	}
	if(s->name==0)
		return NULL;
	if(s!=signames)
		strcpy(retstr, prefix);
	 else
		retstr[0] = 0;
	return strcat(retstr, s->name);
}
Exemple #2
0
extern int kill_main(int argc, char **argv)
{
	int whichApp, sig = SIGTERM, quiet, errors;
	const char *name;

#ifdef BB_KILLALL
	/* Figure out what we are trying to do here */
	whichApp = (strcmp(applet_name, "killall") == 0)? KILLALL : KILL; 
#else
	whichApp = KILL;
#endif

	errors=0;
	quiet=0;
	argc--;
	argv++;
	/* Parse any options */
	if (argc < 1)
		show_usage();

	while (argc > 0 && **argv == '-') {
		while (*++(*argv)) {
			switch (**argv) {
#ifdef BB_KILLALL
				case 'q':
					quiet++;
					break;
#endif
				case 'l':
					if(argc>1) {
						for(argv++; *argv; argv++) {
							name = u_signal_names(*argv, &sig, -1);
							if(name!=NULL)
								printf("%s\n", name);
						}
					} else {
						int col = 0;
						for(sig=1; sig < NSIG; sig++) {
							name = u_signal_names(0, &sig, 1);
							if(name==NULL)  /* unnamed */
								continue;
							col += printf("%2d) %-16s", sig, name);
							if (col > 60) {
								printf("\n");
								col = 0;
							}
						}
						printf("\n");
					}
					return EXIT_SUCCESS;
				case '-':
					show_usage();
				default:
					name = u_signal_names(*argv, &sig, 0);
					if(name==NULL)
						error_msg_and_die( "bad signal name: %s", *argv);
					argc--;
					argv++;
					goto do_it_now;
			}
			argc--;
			argv++;
		}
	}

do_it_now:

	if (whichApp == KILL) {
		/* Looks like they want to do a kill. Do that */
		while (--argc >= 0) {
			int pid;

			if (!isdigit(**argv))
				perror_msg_and_die( "Bad PID");
			pid = strtol(*argv, NULL, 0);
			if (kill(pid, sig) != 0) {
				perror_msg( "Could not kill pid '%d'", pid);
				errors++;
			}
			argv++;
		}
	} 
#ifdef BB_KILLALL
	else {
		pid_t myPid=getpid();
		/* Looks like they want to do a killall.  Do that */
		while (--argc >= 0) {
			long* pidList;

			pidList = find_pid_by_name(*argv);
			if (!pidList || *pidList<=0) {
				errors++;
				if (!quiet)
					error_msg( "%s: no process killed", *argv);
			} else {
				for(; *pidList!=0; pidList++) {
					if (*pidList==myPid)
						continue;
					if (kill(*pidList, sig) != 0) {
						errors++;
						if (!quiet)
							perror_msg( "Could not kill pid '%d'", *pidList);
					}
				}
			}

			/* Note that we don't bother to free the memory
			 * allocated in find_pid_by_name().  It will be freed
			 * upon exit, so we can save a byte or two */
			argv++;
		}
	}
#endif

	return errors;
}
extern int kill_main(int argc, char **argv)
{
	int whichApp, signo = SIGTERM, quiet = 0;
	const char *name;
	int errors = 0;

#ifdef CONFIG_KILLALL
	/* Figure out what we are trying to do here */
	whichApp = (strcmp(bb_applet_name, "killall") == 0)? KILLALL : KILL;
#else
	whichApp = KILL;
#endif

	/* Parse any options */
	if (argc < 2)
		bb_show_usage();

	if(argv[1][0] != '-'){
		argv++;
		argc--;
		goto do_it_now;
	}

	/* The -l option, which prints out signal names. */
	if(argv[1][1]=='l' && argv[1][2]=='\0'){
		if(argc==2) {
			/* Print the whole signal list */
			int col = 0;
			for(signo=1; signo < NSIG; signo++) {
				name = u_signal_names(0, &signo, 1);
				if(name==NULL)  /* unnamed */
					continue;
				col += printf("%2d) %-16s", signo, name);
				if (col > 60) {
					printf("\n");
					col = 0;
				}
			}
			printf("\n");

		} else {
			for(argv++; *argv; argv++) {
				name = u_signal_names(*argv, &signo, -1);
				if(name!=NULL)
					printf("%s\n", name);
			}
		}
		/* If they specified -l, were all done */
		return EXIT_SUCCESS;
	}

	/* The -q quiet option */
	if(argv[1][1]=='q' && argv[1][2]=='\0'){
		quiet++;
		argv++;
		argc--;
		if(argc<2 || argv[1][0] != '-'){
			goto do_it_now;
		}
	}

	if(!u_signal_names(argv[1]+1, &signo, 0))
		bb_error_msg_and_die( "bad signal name '%s'", argv[1]+1);
	argv+=2;
	argc-=2;

do_it_now:

	if (whichApp == KILL) {
		/* Looks like they want to do a kill. Do that */
		while (--argc >= 0) {
			int pid;

			if (!isdigit(**argv))
				bb_error_msg_and_die( "Bad PID '%s'", *argv);
			pid = strtol(*argv, NULL, 0);
			if (kill(pid, signo) != 0) {
				bb_perror_msg( "Could not kill pid '%d'", pid);
				errors++;
			}
			argv++;
		}

	}
#ifdef CONFIG_KILLALL
	else {
		pid_t myPid=getpid();
		/* Looks like they want to do a killall.  Do that */
		while (--argc >= 0) {
			long* pidList;

			pidList = find_pid_by_name(*argv);
			if (!pidList || *pidList<=0) {
				errors++;
				if (quiet==0)
					bb_error_msg( "%s: no process killed", *argv);
			} else {
				long *pl;

				for(pl = pidList; *pl !=0 ; pl++) {
					if (*pl==myPid)
						continue;
					if (kill(*pl, signo) != 0) {
						errors++;
						if (quiet==0)
							bb_perror_msg( "Could not kill pid '%ld'", *pl);
					}
				}
			}
			free(pidList);
			argv++;
		}
	}
#endif
	return errors;
}