aboutsummaryrefslogtreecommitdiff
path: root/toys/lsb
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2019-07-25 15:28:03 -0700
committerRob Landley <rob@landley.net>2019-07-25 21:41:03 -0500
commit903f06c7780880ca07036d0ff9ea6c2e28dfdb00 (patch)
tree3dda042c4875f2c9e791bcd1d9059283289c8026 /toys/lsb
parent90ba72902d5f65a398d6954b20bb10042de57270 (diff)
downloadtoybox-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.c25
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);
+ }
}