aboutsummaryrefslogtreecommitdiff
path: root/coreutils/timeout.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-05-14 12:33:03 +0100
committerRon Yorston <rmy@pobox.com>2024-05-14 12:33:03 +0100
commit569de936abb90f4c7cdca9da111a6ea780b135bf (patch)
treef1965765683e09ca780b39340abac90f349e47a4 /coreutils/timeout.c
parentbb128070e590234f8b63fb1d67f7621a1b4b3ff3 (diff)
downloadbusybox-w32-569de936abb90f4c7cdca9da111a6ea780b135bf.tar.gz
busybox-w32-569de936abb90f4c7cdca9da111a6ea780b135bf.tar.bz2
busybox-w32-569de936abb90f4c7cdca9da111a6ea780b135bf.zip
kill: killing a zombie process should fail
A process which has exited may still have its process handle held open by its children. Such a process doesn't appear in the process table. It is thus similar to a zombie process in UNIX. Using kill(1) to interact with such a process was seen to succeed, contrary to expectation. The code for "ordinary" signals in kill(2) did check if the process was still active but didn't treat an attempt to kill an inactive process as an error. Furthermore, sending SIGKILL or the fake signal 0 to a process didn't even check if the process was still active. Rearrange the implementation of kill(2) so that an attempt to signal an inactive process is treated as an error. This also consolidates handling of SIGKILL and signal 0 with "ordinary" signals. Saves 96 bytes. (GitHub issue #416)
Diffstat (limited to 'coreutils/timeout.c')
-rw-r--r--coreutils/timeout.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/coreutils/timeout.c b/coreutils/timeout.c
index ff58a753a..802ddfc07 100644
--- a/coreutils/timeout.c
+++ b/coreutils/timeout.c
@@ -54,7 +54,9 @@ static HANDLE child = INVALID_HANDLE_VALUE;
54static void kill_child(void) 54static void kill_child(void)
55{ 55{
56 if (child != INVALID_HANDLE_VALUE) { 56 if (child != INVALID_HANDLE_VALUE) {
57 kill_signal_by_handle(child, SIGTERM); 57 pid_t pid = (pid_t)GetProcessId(child);
58 if (pid)
59 kill(pid, SIGTERM);
58 } 60 }
59} 61}
60 62
@@ -206,13 +208,15 @@ int timeout_main(int argc UNUSED_PARAM, char **argv)
206 status = signo == SIGKILL ? 137 : 124; 208 status = signo == SIGKILL ? 137 : 124;
207 209
208 pid = (pid_t)GetProcessId(child); 210 pid = (pid_t)GetProcessId(child);
209 kill(pid, signo); 211 if (pid) {
212 kill(pid, signo);
210 213
211 if (kill_timeout > 0) { 214 if (kill_timeout > 0) {
212 if (timeout_wait(kill_timeout, child, &status)) 215 if (timeout_wait(kill_timeout, child, &status))
213 goto finish; 216 goto finish;
214 kill(pid, SIGKILL); 217 kill(pid, SIGKILL);
215 status = 137; 218 status = 137;
219 }
216 } 220 }
217 finish: 221 finish:
218 CloseHandle(child); 222 CloseHandle(child);