aboutsummaryrefslogtreecommitdiff
path: root/procps
diff options
context:
space:
mode:
Diffstat (limited to 'procps')
-rw-r--r--procps/Kbuild1
-rw-r--r--procps/kill.c95
2 files changed, 58 insertions, 38 deletions
diff --git a/procps/Kbuild b/procps/Kbuild
index 6a9a86637..33f616fc2 100644
--- a/procps/Kbuild
+++ b/procps/Kbuild
@@ -7,6 +7,7 @@
7lib-y:= 7lib-y:=
8lib-$(CONFIG_FREE) += free.o 8lib-$(CONFIG_FREE) += free.o
9lib-$(CONFIG_KILL) += kill.o 9lib-$(CONFIG_KILL) += kill.o
10lib-$(CONFIG_ASH) += kill.o # used for built-in kill by ash
10lib-$(CONFIG_PIDOF) += pidof.o 11lib-$(CONFIG_PIDOF) += pidof.o
11lib-$(CONFIG_PS) += ps.o 12lib-$(CONFIG_PS) += ps.o
12lib-$(CONFIG_RENICE) += renice.o 13lib-$(CONFIG_RENICE) += renice.o
diff --git a/procps/kill.c b/procps/kill.c
index 9a6e93665..e2b029d20 100644
--- a/procps/kill.c
+++ b/procps/kill.c
@@ -10,16 +10,30 @@
10 10
11#include "busybox.h" 11#include "busybox.h"
12 12
13/* Note: kill_main is directly called from shell in order to implement
14 * kill built-in. Shell substitutes job ids with process groups first.
15 *
16 * This brings some complications:
17 *
18 * + we can't use xfunc here
19 * + we can't use applet_name
20 * + we can't use bb_show_usage
21 * (Above doesn't apply for killall[5] cases)
22 *
23 * kill %n gets translated into kill ' -<process group>' by shell (note space!)
24 * This is needed to avoid collision with kill -9 ... syntax
25 */
26
13int kill_main(int argc, char **argv); 27int kill_main(int argc, char **argv);
14int kill_main(int argc, char **argv) 28int kill_main(int argc, char **argv)
15{ 29{
16 char *arg; 30 char *arg;
17 pid_t pid; 31 pid_t pid;
18 int signo = SIGTERM, errors = 0, quiet = 0; 32 int signo = SIGTERM, errors = 0, quiet = 0;
19 const int killall = (ENABLE_KILLALL && applet_name[4] == 'a' 33 const int killall = (ENABLE_KILLALL && argv[0][4] == 'a'
20 && (!ENABLE_KILLALL5 || applet_name[7] != '5')); 34 && (!ENABLE_KILLALL5 || argv[0][7] != '5'));
21 const int killall5 = (ENABLE_KILLALL5 && applet_name[4] == 'a' 35 const int killall5 = (ENABLE_KILLALL5 && argv[0][4] == 'a'
22 && (!ENABLE_KILLALL || applet_name[7] == '5')); 36 && (!ENABLE_KILLALL || argv[0][7] == '5'));
23 37
24 /* Parse any options */ 38 /* Parse any options */
25 argc--; 39 argc--;
@@ -29,34 +43,38 @@ int kill_main(int argc, char **argv)
29 goto do_it_now; 43 goto do_it_now;
30 } 44 }
31 45
32 /* The -l option, which prints out signal names. */ 46 /* The -l option, which prints out signal names.
47 * Intended usage in shell:
48 * echo "Died of SIG`kill -l $?`"
49 * We try to mimic what kill from coreutils-6.8 does */
33 if (arg[1] == 'l' && arg[2] == '\0') { 50 if (arg[1] == 'l' && arg[2] == '\0') {
34 const char *name;
35 if (argc == 1) { 51 if (argc == 1) {
36 /* Print the whole signal list */ 52 /* Print the whole signal list */
37 int col = 0;
38 for (signo = 1; signo < 32; signo++) { 53 for (signo = 1; signo < 32; signo++) {
39 name = get_signame(signo); 54 puts(get_signame(signo));
40 if (isdigit(name[0])) continue;
41 if (col > 66) {
42 puts("");
43 col = 0;
44 }
45 col += printf("%2d) %-6s", signo, name);
46 } 55 }
47 puts("");
48 } else { /* -l <sig list> */ 56 } else { /* -l <sig list> */
49 while ((arg = *++argv)) { 57 while ((arg = *++argv)) {
50 if (isdigit(arg[0])) { 58 if (isdigit(arg[0])) {
51 signo = xatoi_u(arg); 59 signo = bb_strtou(arg, NULL, 10);
52 name = get_signame(signo); 60 if (errno) {
61 bb_error_msg("unknown signal '%s'", arg);
62 return EXIT_FAILURE;
63 }
64 /* Exitcodes >= 0x80 are to be treated
65 * as "killed by signal (exitcode & 0x7f)" */
66 puts(get_signame(signo & 0x7f));
67 /* TODO: 'bad' signal# - coreutils says:
68 * kill: 127: invalid signal
69 * we just print "127" instead */
53 } else { 70 } else {
54 signo = get_signum(arg); 71 signo = get_signum(arg);
55 if (signo < 0) 72 if (signo < 0) {
56 bb_error_msg_and_die("unknown signal '%s'", arg); 73 bb_error_msg("unknown signal '%s'", arg);
57 name = get_signame(signo); 74 return EXIT_FAILURE;
75 }
76 printf("%d\n", signo);
58 } 77 }
59 printf("%2d) %s\n", signo, name);
60 } 78 }
61 } 79 }
62 /* If they specified -l, we are all done */ 80 /* If they specified -l, we are all done */
@@ -74,8 +92,10 @@ int kill_main(int argc, char **argv)
74 92
75 /* -SIG */ 93 /* -SIG */
76 signo = get_signum(&arg[1]); 94 signo = get_signum(&arg[1]);
77 if (signo < 0) 95 if (signo < 0) { /* || signo > MAX_SIGNUM ? */
78 bb_error_msg_and_die("bad signal name '%s'", &arg[1]); 96 bb_error_msg("bad signal name '%s'", &arg[1]);
97 return EXIT_FAILURE;
98 }
79 arg = *++argv; 99 arg = *++argv;
80 argc--; 100 argc--;
81 101
@@ -85,10 +105,6 @@ do_it_now:
85 pid_t sid; 105 pid_t sid;
86 procps_status_t* p = NULL; 106 procps_status_t* p = NULL;
87 107
88// Cannot happen anyway? We don't TERM ourself, we STOP
89// /* kill(-1, sig) on Linux (at least 2.1.x)
90// * might send signal to the calling process too */
91// signal(SIGTERM, SIG_IGN);
92 /* Now stop all processes */ 108 /* Now stop all processes */
93 kill(-1, SIGSTOP); 109 kill(-1, SIGSTOP);
94 /* Find out our own session id */ 110 /* Find out our own session id */
@@ -104,9 +120,11 @@ do_it_now:
104 return 0; 120 return 0;
105 } 121 }
106 122
107 /* Pid or name required for kill/killall */ 123 /* Pid or name is required for kill/killall */
108 if (argc < 1) 124 if (argc < 1) {
109 bb_show_usage(); 125 puts("You need to specify whom to kill");
126 return EXIT_FAILURE;
127 }
110 128
111 if (killall) { 129 if (killall) {
112 /* Looks like they want to do a killall. Do that */ 130 /* Looks like they want to do a killall. Do that */
@@ -140,14 +158,15 @@ do_it_now:
140 158
141 /* Looks like they want to do a kill. Do that */ 159 /* Looks like they want to do a kill. Do that */
142 while (arg) { 160 while (arg) {
143 /* Huh? 161 /* Support shell 'space' trick */
144 if (!isdigit(arg[0]) && arg[0] != '-') 162 if (arg[0] == ' ')
145 bb_error_msg_and_die("bad pid '%s'", arg); 163 arg++;
146 */ 164 pid = bb_strtoi(arg, NULL, 10);
147 pid = xatou(arg); 165 if (errno) {
148 /* FIXME: better overflow check? */ 166 bb_error_msg("bad pid '%s'", arg);
149 if (kill(pid, signo) != 0) { 167 errors++;
150 bb_perror_msg("cannot kill pid %u", (unsigned)pid); 168 } else if (kill(pid, signo) != 0) {
169 bb_perror_msg("cannot kill pid %d", (int)pid);
151 errors++; 170 errors++;
152 } 171 }
153 arg = *++argv; 172 arg = *++argv;