aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/killall.test4
-rw-r--r--toys/lsb/killall.c25
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);
+ }
}