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 | } |