aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-04-29 23:42:54 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-04-29 23:42:54 +0000
commit6f9a6375e52b169fc0a0ce7e4ac71fd10af3041d (patch)
tree4fc060596d599d6ac86bc964970c466496f67954
parente844cd1c557e78d2d1b67d63a8f21e8c5406c335 (diff)
downloadbusybox-w32-6f9a6375e52b169fc0a0ce7e4ac71fd10af3041d.tar.gz
busybox-w32-6f9a6375e52b169fc0a0ce7e4ac71fd10af3041d.tar.bz2
busybox-w32-6f9a6375e52b169fc0a0ce7e4ac71fd10af3041d.zip
ash,kill: use common code for kill applet/builtin
# make bloatcheck function old new delta evaltreenr 644 654 +10 evaltree 644 654 +10 parse_conf 1440 1444 +4 dpkg_deb_main 426 429 +3 ed_main 3319 3321 +2 passwd_main 2093 2091 -2 kill_main 830 826 -4 singlemount 4609 4601 -8 find_command 962 954 -8 get_lcm 123 105 -18 .rodata 132243 132147 -96 killcmd 449 120 -329 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 5/7 up/down: 29/-465) Total: -436 bytes # size busybox_old busybox_unstripped text data bss dec hex filename 723901 2940 27504 754345 b82a9 busybox_old 723457 2940 27504 753901 b80ed busybox_unstripped git-svn-id: svn://busybox.net/trunk/busybox@18532 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--include/libbb.h1
-rw-r--r--procps/Kbuild1
-rw-r--r--procps/kill.c95
-rw-r--r--shell/ash.c119
4 files changed, 86 insertions, 130 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 9950c61f2..be51f2520 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -636,6 +636,7 @@ extern void bb_vinfo_msg(const char *s, va_list p);
636int bb_cat(char** argv); 636int bb_cat(char** argv);
637int bb_echo(char** argv); 637int bb_echo(char** argv);
638int bb_test(int argc, char** argv); 638int bb_test(int argc, char** argv);
639int kill_main(int argc, char **argv);
639#if ENABLE_ROUTE 640#if ENABLE_ROUTE
640void bb_displayroutes(int noresolve, int netstatfmt); 641void bb_displayroutes(int noresolve, int netstatfmt);
641#endif 642#endif
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;
diff --git a/shell/ash.c b/shell/ash.c
index 16818cfc9..4b37f403c 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -3519,91 +3519,22 @@ setjobctl(int on)
3519static int 3519static int
3520killcmd(int argc, char **argv) 3520killcmd(int argc, char **argv)
3521{ 3521{
3522 int signo = -1; 3522 if (argv[1] && strcmp(argv[1], "-l") != 0) {
3523 int list = 0; 3523 int i = 1;
3524 int i; 3524 do {
3525 pid_t pid; 3525 if (argv[i][0] == '%') {
3526 struct job *jp; 3526 struct job *jp = getjob(argv[i], 0);
3527 3527 unsigned pid = jp->ps[0].pid;
3528 if (argc <= 1) { 3528 /* Enough space for ' -NNN<nul>' */
3529 usage: 3529 argv[i] = alloca(sizeof(int)*3 + 3);
3530 ash_msg_and_raise_error( 3530 /* kill_main has matching code to expect
3531"usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n" 3531 * leading space. Needed to not confuse
3532"kill -l [exitstatus]" 3532 * negative pids with "kill -SIGNAL_NO" syntax */
3533 ); 3533 sprintf(argv[i], " -%u", pid);
3534 }
3535
3536 if (**++argv == '-') {
3537 signo = get_signum(*argv + 1);
3538 if (signo < 0) {
3539 int c;
3540
3541 while ((c = nextopt("ls:")) != '\0') {
3542 switch (c) {
3543 default:
3544#if DEBUG
3545 abort();
3546#endif
3547 case 'l':
3548 list = 1;
3549 break;
3550 case 's':
3551 signo = get_signum(optionarg);
3552 if (signo < 0) {
3553 ash_msg_and_raise_error(
3554 "invalid signal number or name: %s",
3555 optionarg
3556 );
3557 }
3558 break;
3559 }
3560 }
3561 argv = argptr;
3562 } else
3563 argv++;
3564 }
3565
3566 if (!list && signo < 0)
3567 signo = SIGTERM;
3568
3569 if ((signo < 0 || !*argv) ^ list) {
3570 goto usage;
3571 }
3572
3573 if (list) {
3574 const char *name;
3575
3576 if (!*argv) {
3577 for (i = 1; i < NSIG; i++) {
3578 name = get_signame(i);
3579 if (!isdigit(*name))
3580 out1fmt(snlfmt, name);
3581 } 3534 }
3582 return 0; 3535 } while (argv[++i]);
3583 }
3584 name = get_signame(signo);
3585 if (!isdigit(*name))
3586 ash_msg_and_raise_error("invalid signal number or exit status: %s", *argptr);
3587 out1fmt(snlfmt, name);
3588 return 0;
3589 } 3536 }
3590 3537 return kill_main(argc, argv);
3591 i = 0;
3592 do {
3593 if (**argv == '%') {
3594 jp = getjob(*argv, 0);
3595 pid = -jp->ps[0].pid;
3596 } else {
3597 pid = **argv == '-' ?
3598 -number(*argv + 1) : number(*argv);
3599 }
3600 if (kill(pid, signo) != 0) {
3601 ash_msg("(%d) - %m", pid);
3602 i = 1;
3603 }
3604 } while (*++argv);
3605
3606 return i;
3607} 3538}
3608 3539
3609static void 3540static void
@@ -3642,7 +3573,8 @@ restartjob(struct job *jp, int mode)
3642 if (WIFSTOPPED(ps->status)) { 3573 if (WIFSTOPPED(ps->status)) {
3643 ps->status = -1; 3574 ps->status = -1;
3644 } 3575 }
3645 } while (ps++, --i); 3576 ps++;
3577 } while (--i);
3646 out: 3578 out:
3647 status = (mode == FORK_FG) ? waitforjob(jp) : 0; 3579 status = (mode == FORK_FG) ? waitforjob(jp) : 0;
3648 INT_ON; 3580 INT_ON;
@@ -5070,8 +5002,9 @@ esclen(const char *start, const char *p)
5070static char * 5002static char *
5071_rmescapes(char *str, int flag) 5003_rmescapes(char *str, int flag)
5072{ 5004{
5005 static const char qchars[] = { CTLESC, CTLQUOTEMARK, '\0' };
5006
5073 char *p, *q, *r; 5007 char *p, *q, *r;
5074 static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 };
5075 unsigned inquotes; 5008 unsigned inquotes;
5076 int notescaped; 5009 int notescaped;
5077 int globbing; 5010 int globbing;
@@ -11117,13 +11050,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
11117 return; 11050 return;
11118 } 11051 }
11119 11052
11120#if ENABLE_FEATURE_SH_STANDALONE 11053/* #if ENABLE_FEATURE_SH_STANDALONE... moved after builtin check */
11121 if (find_applet_by_name(name)) {
11122 entry->cmdtype = CMDNORMAL;
11123 entry->u.index = -1;
11124 return;
11125 }
11126#endif
11127 11054
11128 updatetbl = (path == pathval()); 11055 updatetbl = (path == pathval());
11129 if (!updatetbl) { 11056 if (!updatetbl) {
@@ -11173,6 +11100,14 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
11173 } 11100 }
11174 } 11101 }
11175 11102
11103#if ENABLE_FEATURE_SH_STANDALONE
11104 if (find_applet_by_name(name)) {
11105 entry->cmdtype = CMDNORMAL;
11106 entry->u.index = -1;
11107 return;
11108 }
11109#endif
11110
11176 /* We have to search path. */ 11111 /* We have to search path. */
11177 prev = -1; /* where to start */ 11112 prev = -1; /* where to start */
11178 if (cmdp && cmdp->rehash) { /* doing a rehash */ 11113 if (cmdp && cmdp->rehash) { /* doing a rehash */