diff options
-rw-r--r-- | tests/killall.test | 4 | ||||
-rw-r--r-- | toys/lsb/killall.c | 25 |
2 files changed, 25 insertions, 4 deletions
diff --git a/tests/killall.test b/tests/killall.test index 8302a574..b15dbf0f 100644 --- a/tests/killall.test +++ b/tests/killall.test @@ -13,12 +13,12 @@ cp toybox.killall.test.script toybox.test tst=toybox.test ./$tst & -testing "short name" "killall $tst && echo killed ; sleep 0.1 ; \ +testing "short name" "killall -w $tst && echo killed ; \ pgrep -l $tst || echo really" "killed\nreally\n" "" "" tst=toybox.killall.test.script ./$tst & -testing "long name" "killall $tst && echo killed ; sleep 0.1 ; \ +testing "long name" "killall -w $tst && echo killed ; \ pgrep -l $tst || echo really" "killed\nreally\n" "" "" rm -f toybox.killall.test.script toybox.test diff --git a/toys/lsb/killall.c b/toys/lsb/killall.c index c81360b1..d3546a05 100644 --- a/toys/lsb/killall.c +++ b/toys/lsb/killall.c @@ -4,7 +4,7 @@ * * http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/killall.html -USE_KILLALL(NEWTOY(killall, "?s:lqvi", TOYFLAG_USR|TOYFLAG_BIN)) +USE_KILLALL(NEWTOY(killall, "?s:ilqvw", TOYFLAG_USR|TOYFLAG_BIN)) config KILLALL bool "killall" @@ -19,6 +19,7 @@ config KILLALL -q Don't print any warnings or error messages -s Send SIGNAL instead of SIGTERM -v Report if the signal was successfully sent + -w Wait until all signaled processes are dead */ #define FOR_killall @@ -31,6 +32,7 @@ GLOBALS( pid_t cur_pid; char **names; short *err; + struct int_list { struct int_list *next; int val; } *pids; ) static int kill_process(pid_t pid, char *name) @@ -46,6 +48,12 @@ static int kill_process(pid_t pid, char *name) errno = 0; kill(pid, TT.signum); + if (FLAG(w)) { + struct int_list *new = xmalloc(sizeof(*TT.pids)); + new->val = pid; + new->next = TT.pids; + TT.pids = new; + } for (;;) { if (TT.names[offset] == name) { TT.err[offset] = errno; @@ -97,5 +105,18 @@ void killall_main(void) perror_msg_raw(TT.names[i]); } } - if (CFG_TOYBOX_FREE) free(TT.err); + if (FLAG(w)) { + for (;;) { + struct int_list *p = TT.pids; + int c = 0; + + for (; p; p=p->next) if (kill(p->val, 0) != -1 || errno != ESRCH) ++c; + if (!c) break; + sleep(1); + } + } + if (CFG_TOYBOX_FREE) { + free(TT.err); + llist_traverse(TT.pids, free); + } } |