diff options
author | Elliott Hughes <enh@google.com> | 2017-12-13 11:47:08 -0800 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2017-12-19 14:49:25 -0600 |
commit | 9356adb28dd8d541a67270e202c7bf6f5a67fc82 (patch) | |
tree | 89fa4d02ed5205084d8a69f9de37bcd89f330041 | |
parent | bf1f0e357b6b1e7bd677ca41fc04ae3c5c5e6e70 (diff) | |
download | toybox-9356adb28dd8d541a67270e202c7bf6f5a67fc82.tar.gz |
killall should kill scripts too.
Found running LTP file system tests on Android.
Bug: http://b/70627145
-rw-r--r-- | lib/lib.c | 28 | ||||
-rw-r--r-- | tests/killall.test | 14 |
2 files changed, 33 insertions, 9 deletions
@@ -1010,6 +1010,12 @@ char *getbasename(char *name) return name; } +static int argv0_match(char *cmd, char *name) +{ + return (*name == '/' ? !strcmp(cmd, name) + : !strcmp(getbasename(cmd), getbasename(name))); +} + // Execute a callback for each PID that matches a process name from a list. void names_to_pid(char **names, int (*callback)(pid_t pid, char *name)) { @@ -1020,17 +1026,21 @@ void names_to_pid(char **names, int (*callback)(pid_t pid, char *name)) while ((entry = readdir(dp))) { unsigned u; - char *cmd, **curname; + char *cmd, *comm, **cur; if (!(u = atoi(entry->d_name))) continue; - sprintf(libbuf, "/proc/%u/cmdline", u); - if (!(cmd = readfile(libbuf, libbuf, sizeof(libbuf)))) continue; - - for (curname = names; *curname; curname++) - if (**curname == '/' ? !strcmp(cmd, *curname) - : !strcmp(getbasename(cmd), getbasename(*curname))) - if (callback(u, *curname)) break; - if (*curname) break; + + // For a script, comm and argv[1] will match (argv[0] will be the interp). + sprintf(libbuf, "/proc/%u/comm", u); + if (!(comm = readfile(libbuf, libbuf, sizeof(libbuf)))) continue; + sprintf(libbuf+16, "/proc/%u/cmdline", u); + if (!(cmd = readfile(libbuf+16, libbuf+16, sizeof(libbuf)-16))) continue; + + for (cur = names; *cur; cur++) + if (argv0_match(cmd, *cur) || + (!strncmp(comm, *cur, 15) && argv0_match(cmd+strlen(cmd)+1, *cur))) + if (callback(u, *cur)) break; + if (*cur) break; } closedir(dp); } diff --git a/tests/killall.test b/tests/killall.test new file mode 100644 index 00000000..100ac7ca --- /dev/null +++ b/tests/killall.test @@ -0,0 +1,14 @@ +#!/bin/bash + +[ -f testing.sh ] && . testing.sh + +#testing "name" "command" "result" "infile" "stdin" + +echo "#!/bin/sh +yes > /dev/null" > toybox.killall.test.script +chmod a+x toybox.killall.test.script + +./toybox.killall.test.script & +testing "script" "killall toybox.killall.test.script && echo killed ; pgrep -l toybox.killall.test.script || echo really" "killed\nreally\n" "" "" + +rm -f toybox.killall.test.script |