diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-09-27 14:25:33 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-09-27 14:25:33 +0000 |
| commit | 0bb628f4f3fbd0fc0a96d257830fcbbb14db2bd1 (patch) | |
| tree | fd0cff9651bdffc5f4b8ed5bfaee7b2671384e08 | |
| parent | a77947f5bb9ef38b0f1fc6a2a5b500fa6ade601e (diff) | |
| download | busybox-w32-0bb628f4f3fbd0fc0a96d257830fcbbb14db2bd1.tar.gz busybox-w32-0bb628f4f3fbd0fc0a96d257830fcbbb14db2bd1.tar.bz2 busybox-w32-0bb628f4f3fbd0fc0a96d257830fcbbb14db2bd1.zip | |
kill: implement killall5. OpenWRT folks will be happy.
However their code was unusably different from sysvinit original.
Run tested.
| -rw-r--r-- | include/applets.h | 1 | ||||
| -rw-r--r-- | include/usage.h | 15 | ||||
| -rw-r--r-- | procps/Config.in | 5 | ||||
| -rw-r--r-- | procps/kill.c | 76 |
4 files changed, 65 insertions, 32 deletions
diff --git a/include/applets.h b/include/applets.h index c75866dde..e12f6027c 100644 --- a/include/applets.h +++ b/include/applets.h | |||
| @@ -159,6 +159,7 @@ USE_IPROUTE(APPLET(iproute, _BB_DIR_BIN, _BB_SUID_NEVER)) | |||
| 159 | USE_IPTUNNEL(APPLET(iptunnel, _BB_DIR_BIN, _BB_SUID_NEVER)) | 159 | USE_IPTUNNEL(APPLET(iptunnel, _BB_DIR_BIN, _BB_SUID_NEVER)) |
| 160 | USE_KILL(APPLET(kill, _BB_DIR_BIN, _BB_SUID_NEVER)) | 160 | USE_KILL(APPLET(kill, _BB_DIR_BIN, _BB_SUID_NEVER)) |
| 161 | USE_KILLALL(APPLET_ODDNAME(killall, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall)) | 161 | USE_KILLALL(APPLET_ODDNAME(killall, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall)) |
| 162 | USE_KILLALL5(APPLET_ODDNAME(killall5, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall5)) | ||
| 162 | USE_KLOGD(APPLET(klogd, _BB_DIR_SBIN, _BB_SUID_NEVER)) | 163 | USE_KLOGD(APPLET(klogd, _BB_DIR_SBIN, _BB_SUID_NEVER)) |
| 163 | USE_LASH(APPLET(lash, _BB_DIR_BIN, _BB_SUID_NEVER)) | 164 | USE_LASH(APPLET(lash, _BB_DIR_BIN, _BB_SUID_NEVER)) |
| 164 | USE_LAST(APPLET(last, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 165 | USE_LAST(APPLET(last, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
diff --git a/include/usage.h b/include/usage.h index da176d156..8b8d64e84 100644 --- a/include/usage.h +++ b/include/usage.h | |||
| @@ -1485,9 +1485,9 @@ USE_FEATURE_DATE_ISOFMT( \ | |||
| 1485 | "\t\t\t[ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]" | 1485 | "\t\t\t[ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]" |
| 1486 | 1486 | ||
| 1487 | #define kill_trivial_usage \ | 1487 | #define kill_trivial_usage \ |
| 1488 | "[-signal] process-id [process-id ...]" | 1488 | "[-l] [-signal] process-id [process-id ...]" |
| 1489 | #define kill_full_usage \ | 1489 | #define kill_full_usage \ |
| 1490 | "Send a signal (default is SIGTERM) to the specified process(es).\n\n" \ | 1490 | "Send a signal (default is TERM) to the specified process(es).\n\n" \ |
| 1491 | "Options:\n" \ | 1491 | "Options:\n" \ |
| 1492 | "\t-l\tList all signal names and numbers" | 1492 | "\t-l\tList all signal names and numbers" |
| 1493 | #define kill_example_usage \ | 1493 | #define kill_example_usage \ |
| @@ -1501,15 +1501,22 @@ USE_FEATURE_DATE_ISOFMT( \ | |||
| 1501 | "$ kill 252\n" | 1501 | "$ kill 252\n" |
| 1502 | 1502 | ||
| 1503 | #define killall_trivial_usage \ | 1503 | #define killall_trivial_usage \ |
| 1504 | "[-q] [-signal] process-name [process-name ...]" | 1504 | "[-l] [-q] [-signal] process-name [process-name ...]" |
| 1505 | #define killall_full_usage \ | 1505 | #define killall_full_usage \ |
| 1506 | "Send a signal (default is SIGTERM) to the specified process(es).\n\n" \ | 1506 | "Send a signal (default is TERM) to the specified process(es).\n\n" \ |
| 1507 | "Options:\n" \ | 1507 | "Options:\n" \ |
| 1508 | "\t-l\tList all signal names and numbers\n" \ | 1508 | "\t-l\tList all signal names and numbers\n" \ |
| 1509 | "\t-q\tDo not complain if no processes were killed" | 1509 | "\t-q\tDo not complain if no processes were killed" |
| 1510 | #define killall_example_usage \ | 1510 | #define killall_example_usage \ |
| 1511 | "$ killall apache\n" | 1511 | "$ killall apache\n" |
| 1512 | 1512 | ||
| 1513 | #define killall5_trivial_usage \ | ||
| 1514 | "[-l] [-signal]" | ||
| 1515 | #define killall5_full_usage \ | ||
| 1516 | "Send a signal (default is TERM) to all processes outside current session.\n\n" \ | ||
| 1517 | "Options:\n" \ | ||
| 1518 | "\t-l\tList all signal names and numbers\n" \ | ||
| 1519 | |||
| 1513 | #define klogd_trivial_usage \ | 1520 | #define klogd_trivial_usage \ |
| 1514 | "[-c n] [-n]" | 1521 | "[-c n] [-n]" |
| 1515 | #define klogd_full_usage \ | 1522 | #define klogd_full_usage \ |
diff --git a/procps/Config.in b/procps/Config.in index 2183fab9a..2d4ad3bd4 100644 --- a/procps/Config.in +++ b/procps/Config.in | |||
| @@ -38,6 +38,11 @@ config CONFIG_KILLALL | |||
| 38 | specified commands. If no signal name is specified, SIGTERM is | 38 | specified commands. If no signal name is specified, SIGTERM is |
| 39 | sent. | 39 | sent. |
| 40 | 40 | ||
| 41 | config CONFIG_KILLALL5 | ||
| 42 | bool "killall5" | ||
| 43 | default n | ||
| 44 | depends on CONFIG_KILL | ||
| 45 | |||
| 41 | config CONFIG_PIDOF | 46 | config CONFIG_PIDOF |
| 42 | bool "pidof" | 47 | bool "pidof" |
| 43 | default n | 48 | default n |
diff --git a/procps/kill.c b/procps/kill.c index 654467ac1..fe9b24200 100644 --- a/procps/kill.c +++ b/procps/kill.c | |||
| @@ -13,17 +13,18 @@ | |||
| 13 | int kill_main(int argc, char **argv) | 13 | int kill_main(int argc, char **argv) |
| 14 | { | 14 | { |
| 15 | char *arg; | 15 | char *arg; |
| 16 | int killall, signo = SIGTERM, errors = 0, quiet = 0; | 16 | pid_t pid; |
| 17 | 17 | int signo = SIGTERM, errors = 0, quiet = 0; | |
| 18 | killall = (ENABLE_KILLALL && bb_applet_name[4]=='a') ? 1 : 0; | 18 | const int killall = (ENABLE_KILLALL && bb_applet_name[4]=='a' |
| 19 | && (!ENABLE_KILLALL5 || bb_applet_name[7]!='5')); | ||
| 20 | const int killall5 = (ENABLE_KILLALL5 && bb_applet_name[4]=='a' | ||
| 21 | && (!ENABLE_KILLALL || bb_applet_name[7]=='5')); | ||
| 19 | 22 | ||
| 20 | /* Parse any options */ | 23 | /* Parse any options */ |
| 21 | argc--; | 24 | argc--; |
| 22 | arg = *++argv; | 25 | arg = *++argv; |
| 23 | if (argc<1) | ||
| 24 | bb_show_usage(); | ||
| 25 | 26 | ||
| 26 | if (arg[0]!='-') { | 27 | if (argc<1 || arg[0]!='-') { |
| 27 | goto do_it_now; | 28 | goto do_it_now; |
| 28 | } | 29 | } |
| 29 | 30 | ||
| @@ -79,42 +80,48 @@ int kill_main(int argc, char **argv) | |||
| 79 | 80 | ||
| 80 | do_it_now: | 81 | do_it_now: |
| 81 | 82 | ||
| 82 | /* Pid or name required */ | 83 | if (killall5) { |
| 83 | if (argc<1) | 84 | pid_t sid; |
| 84 | bb_show_usage(); | 85 | procps_status_t* p; |
| 85 | 86 | ||
| 86 | if (!killall) { | 87 | /* kill(-1, sig) on Linux (at least 2.1.x) |
| 87 | /* Looks like they want to do a kill. Do that */ | 88 | * might send signal to the calling process too */ |
| 88 | while (arg) { | 89 | signal(SIGTERM, SIG_IGN); |
| 89 | int pid; | 90 | /* Now stop all processes */ |
| 90 | 91 | kill(-1, SIGSTOP); | |
| 91 | if (!isdigit(arg[0]) && arg[0]!='-') | 92 | /* Find out our own session id */ |
| 92 | bb_error_msg_and_die("bad pid '%s'", arg); | 93 | pid = getpid(); |
| 93 | pid = strtol(arg, NULL, 0); | 94 | sid = getsid(pid); |
| 94 | if (kill(pid, signo)!=0) { | 95 | /* Now kill all processes except our session */ |
| 95 | bb_perror_msg("cannot kill pid %d", pid); | 96 | while ((p = procps_scan(0))!=0) { |
| 96 | errors++; | 97 | if (getsid(p->pid)!=sid && p->pid!=pid && p->pid!=1) |
| 97 | } | 98 | kill(p->pid, signo); |
| 98 | arg = *++argv; | ||
| 99 | } | 99 | } |
| 100 | /* And let them continue */ | ||
| 101 | kill(-1, SIGCONT); | ||
| 102 | return 0; | ||
| 103 | } | ||
| 100 | 104 | ||
| 101 | } else { | 105 | /* Pid or name required for kill/killall */ |
| 102 | pid_t myPid = getpid(); | 106 | if (argc<1) |
| 107 | bb_show_usage(); | ||
| 103 | 108 | ||
| 109 | if (killall) { | ||
| 104 | /* Looks like they want to do a killall. Do that */ | 110 | /* Looks like they want to do a killall. Do that */ |
| 111 | pid = getpid(); | ||
| 105 | while (arg) { | 112 | while (arg) { |
| 106 | long* pidList; | 113 | long* pidList; |
| 107 | 114 | ||
| 108 | pidList = find_pid_by_name(arg); | 115 | pidList = find_pid_by_name(arg); |
| 109 | if (!pidList || *pidList<=0) { | 116 | if (!pidList || *pidList<=0) { |
| 110 | errors++; | 117 | errors++; |
| 111 | if (quiet==0) | 118 | if (!quiet) |
| 112 | bb_error_msg("%s: no process killed", arg); | 119 | bb_error_msg("%s: no process killed", arg); |
| 113 | } else { | 120 | } else { |
| 114 | long *pl; | 121 | long *pl; |
| 115 | 122 | ||
| 116 | for (pl = pidList; *pl!=0 ; pl++) { | 123 | for (pl = pidList; *pl!=0; pl++) { |
| 117 | if (*pl==myPid) | 124 | if (*pl==pid) |
| 118 | continue; | 125 | continue; |
| 119 | if (kill(*pl, signo)!=0) { | 126 | if (kill(*pl, signo)!=0) { |
| 120 | errors++; | 127 | errors++; |
| @@ -126,7 +133,20 @@ do_it_now: | |||
| 126 | free(pidList); | 133 | free(pidList); |
| 127 | arg = *++argv; | 134 | arg = *++argv; |
| 128 | } | 135 | } |
| 136 | return errors; | ||
| 129 | } | 137 | } |
| 130 | 138 | ||
| 139 | /* Looks like they want to do a kill. Do that */ | ||
| 140 | while (arg) { | ||
| 141 | if (!isdigit(arg[0]) && arg[0]!='-') | ||
| 142 | bb_error_msg_and_die("bad pid '%s'", arg); | ||
| 143 | pid = strtol(arg, NULL, 0); | ||
| 144 | /* FIXME: better overflow check? */ | ||
| 145 | if (kill(pid, signo)!=0) { | ||
| 146 | bb_perror_msg("cannot kill pid %ld", (long)pid); | ||
| 147 | errors++; | ||
| 148 | } | ||
| 149 | arg = *++argv; | ||
| 150 | } | ||
| 131 | return errors; | 151 | return errors; |
| 132 | } | 152 | } |
