From 903f06c7780880ca07036d0ff9ea6c2e28dfdb00 Mon Sep 17 00:00:00 2001
From: Elliott Hughes <enh@google.com>
Date: Thu, 25 Jul 2019 15:28:03 -0700
Subject: 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.
---
 toys/lsb/killall.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

(limited to 'toys/lsb')

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);
+  }
 }
-- 
cgit v1.2.3