kill: implement killall5. OpenWRT folks will be happy. However their code was unusably different from sysvinit original. Run tested.
This commit was genuinely broken at the time (not related to our build system): scripts/config/mkconfigs.c (2005-08-01 - 2006-10-05 arasi) uretilen bbconfigopts.h icine .config satirlarini kacissiz, ham newline'larla gömüyordu - gecerli C degildi, busybox'un kendi bb_mkdep araci bile parse edemiyordu (7d219aab7 ile duzeltildi, mkconfigs shell scripte cevrildi)
No binary (build failed)
—
(log yok)
| @@ -159,6 +159,7 @@ USE_IPROUTE(APPLET(iproute, _BB_DIR_BIN, _BB_SUID_NEVER)) | |
| USE_IPTUNNEL(APPLET(iptunnel, _BB_DIR_BIN, _BB_SUID_NEVER)) | |
| USE_KILL(APPLET(kill, _BB_DIR_BIN, _BB_SUID_NEVER)) | |
| USE_KILLALL(APPLET_ODDNAME(killall, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall)) | |
| + | USE_KILLALL5(APPLET_ODDNAME(killall5, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall5)) |
| USE_KLOGD(APPLET(klogd, _BB_DIR_SBIN, _BB_SUID_NEVER)) | |
| USE_LASH(APPLET(lash, _BB_DIR_BIN, _BB_SUID_NEVER)) | |
| USE_LAST(APPLET(last, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | |
| @@ -1485,9 +1485,9 @@ USE_FEATURE_DATE_ISOFMT( \ | |
| "\t\t\t[ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]" | |
| #define kill_trivial_usage \ | |
| - | "[-signal] process-id [process-id ...]" |
| + | "[-l] [-signal] process-id [process-id ...]" |
| #define kill_full_usage \ | |
| - | "Send a signal (default is SIGTERM) to the specified process(es).\n\n" \ |
| + | "Send a signal (default is TERM) to the specified process(es).\n\n" \ |
| "Options:\n" \ | |
| "\t-l\tList all signal names and numbers" | |
| #define kill_example_usage \ | |
| @@ -1501,15 +1501,22 @@ USE_FEATURE_DATE_ISOFMT( \ | |
| "$ kill 252\n" | |
| #define killall_trivial_usage \ | |
| - | "[-q] [-signal] process-name [process-name ...]" |
| + | "[-l] [-q] [-signal] process-name [process-name ...]" |
| #define killall_full_usage \ | |
| - | "Send a signal (default is SIGTERM) to the specified process(es).\n\n" \ |
| + | "Send a signal (default is TERM) to the specified process(es).\n\n" \ |
| "Options:\n" \ | |
| "\t-l\tList all signal names and numbers\n" \ | |
| "\t-q\tDo not complain if no processes were killed" | |
| #define killall_example_usage \ | |
| "$ killall apache\n" | |
| + | #define killall5_trivial_usage \ |
| + | "[-l] [-signal]" |
| + | #define killall5_full_usage \ |
| + | "Send a signal (default is TERM) to all processes outside current session.\n\n" \ |
| + | "Options:\n" \ |
| + | "\t-l\tList all signal names and numbers\n" \ |
| + | |
| #define klogd_trivial_usage \ | |
| "[-c n] [-n]" | |
| #define klogd_full_usage \ | |
| @@ -38,6 +38,11 @@ config CONFIG_KILLALL | |
| specified commands. If no signal name is specified, SIGTERM is | |
| sent. | |
| + | config CONFIG_KILLALL5 |
| + | bool "killall5" |
| + | default n |
| + | depends on CONFIG_KILL |
| + | |
| config CONFIG_PIDOF | |
| bool "pidof" | |
| default n | |
| @@ -13,17 +13,18 @@ | |
| int kill_main(int argc, char **argv) | |
| { | |
| char *arg; | |
| - | int killall, signo = SIGTERM, errors = 0, quiet = 0; |
| - | |
| - | killall = (ENABLE_KILLALL && bb_applet_name[4]=='a') ? 1 : 0; |
| + | pid_t pid; |
| + | int signo = SIGTERM, errors = 0, quiet = 0; |
| + | const int killall = (ENABLE_KILLALL && bb_applet_name[4]=='a' |
| + | && (!ENABLE_KILLALL5 || bb_applet_name[7]!='5')); |
| + | const int killall5 = (ENABLE_KILLALL5 && bb_applet_name[4]=='a' |
| + | && (!ENABLE_KILLALL || bb_applet_name[7]=='5')); |
| /* Parse any options */ | |
| argc--; | |
| arg = *++argv; | |
| - | if (argc<1) |
| - | bb_show_usage(); |
| - | if (arg[0]!='-') { |
| + | if (argc<1 || arg[0]!='-') { |
| goto do_it_now; | |
| } | |
| @@ -79,42 +80,48 @@ int kill_main(int argc, char **argv) | |
| do_it_now: | |
| - | /* Pid or name required */ |
| - | if (argc<1) |
| - | bb_show_usage(); |
| - | |
| - | if (!killall) { |
| - | /* Looks like they want to do a kill. Do that */ |
| - | while (arg) { |
| - | int pid; |
| - | |
| - | if (!isdigit(arg[0]) && arg[0]!='-') |
| - | bb_error_msg_and_die("bad pid '%s'", arg); |
| - | pid = strtol(arg, NULL, 0); |
| - | if (kill(pid, signo)!=0) { |
| - | bb_perror_msg("cannot kill pid %d", pid); |
| - | errors++; |
| - | } |
| - | arg = *++argv; |
| + | if (killall5) { |
| + | pid_t sid; |
| + | procps_status_t* p; |
| + | |
| + | /* kill(-1, sig) on Linux (at least 2.1.x) |
| + | * might send signal to the calling process too */ |
| + | signal(SIGTERM, SIG_IGN); |
| + | /* Now stop all processes */ |
| + | kill(-1, SIGSTOP); |
| + | /* Find out our own session id */ |
| + | pid = getpid(); |
| + | sid = getsid(pid); |
| + | /* Now kill all processes except our session */ |
| + | while ((p = procps_scan(0))!=0) { |
| + | if (getsid(p->pid)!=sid && p->pid!=pid && p->pid!=1) |
| + | kill(p->pid, signo); |
| } | |
| + | /* And let them continue */ |
| + | kill(-1, SIGCONT); |
| + | return 0; |
| + | } |
| - | } else { |
| - | pid_t myPid = getpid(); |
| + | /* Pid or name required for kill/killall */ |
| + | if (argc<1) |
| + | bb_show_usage(); |
| + | if (killall) { |
| /* Looks like they want to do a killall. Do that */ | |
| + | pid = getpid(); |
| while (arg) { | |
| long* pidList; | |
| pidList = find_pid_by_name(arg); | |
| if (!pidList || *pidList<=0) { | |
| errors++; | |
| - | if (quiet==0) |
| + | if (!quiet) |
| bb_error_msg("%s: no process killed", arg); | |
| } else { | |
| long *pl; | |
| - | for (pl = pidList; *pl!=0 ; pl++) { |
| - | if (*pl==myPid) |
| + | for (pl = pidList; *pl!=0; pl++) { |
| + | if (*pl==pid) |
| continue; | |
| if (kill(*pl, signo)!=0) { | |
| errors++; | |
| @@ -126,7 +133,20 @@ do_it_now: | |
| free(pidList); | |
| arg = *++argv; | |
| } | |
| + | return errors; |
| } | |
| + | /* Looks like they want to do a kill. Do that */ |
| + | while (arg) { |
| + | if (!isdigit(arg[0]) && arg[0]!='-') |
| + | bb_error_msg_and_die("bad pid '%s'", arg); |
| + | pid = strtol(arg, NULL, 0); |
| + | /* FIXME: better overflow check? */ |
| + | if (kill(pid, signo)!=0) { |
| + | bb_perror_msg("cannot kill pid %ld", (long)pid); |
| + | errors++; |
| + | } |
| + | arg = *++argv; |
| + | } |
| return errors; | |
| } | |