diff options
author | Elliott Hughes <enh@google.com> | 2019-07-25 15:28:03 -0700 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2019-07-25 21:41:03 -0500 |
commit | 903f06c7780880ca07036d0ff9ea6c2e28dfdb00 (patch) | |
tree | 3dda042c4875f2c9e791bcd1d9059283289c8026 /toys/lsb | |
parent | 90ba72902d5f65a398d6954b20bb10042de57270 (diff) | |
download | toybox-903f06c7780880ca07036d0ff9ea6c2e28dfdb00.tar.gz |
killall: implement -w.
This isn't currently used in AOSP, but it is used in some of the other
codebases I can easily search, and it's a better fix for test flakiness
than inserting a sleep.
Diffstat (limited to 'toys/lsb')
-rw-r--r-- | toys/lsb/killall.c | 25 |
1 files changed, 23 insertions, 2 deletions
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); + } } |