diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2024-03-18 08:44:39 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2024-03-27 08:27:23 +0000 |
commit | daefc4bda7c5a9728ec62eddcfd9af492531a7f8 (patch) | |
tree | c7e6ed6fcea3796d769187f002c3e6d3abe28047 | |
parent | 365887828521752217bf19e8ab095da8cde0632e (diff) | |
download | src-daefc4bda7c5a9728ec62eddcfd9af492531a7f8.tar.gz src-daefc4bda7c5a9728ec62eddcfd9af492531a7f8.zip |
daemon(8): handle case of waitpid() returning without exited child
PR: 277764
(cherry picked from commit 8eaa6be80d6aef6a118fa854a860bfdaeb7ed753)
-rw-r--r-- | usr.sbin/daemon/daemon.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/usr.sbin/daemon/daemon.c b/usr.sbin/daemon/daemon.c index 65e6bb7ca190..da8e4895e19b 100644 --- a/usr.sbin/daemon/daemon.c +++ b/usr.sbin/daemon/daemon.c @@ -743,18 +743,22 @@ daemon_terminate(struct daemon_state *state) } /* - * Returns true if SIGCHILD came from state->pid - * This function could hang if SIGCHILD was emittied for a reason other than - * child dying (e.g., ptrace attach). + * Returns true if SIGCHILD came from state->pid due to its exit. */ static bool daemon_is_child_dead(struct daemon_state *state) { + int status; + for (;;) { - int who = waitpid(-1, NULL, WNOHANG); - if (state->pid == who) { + int who = waitpid(-1, &status, WNOHANG); + if (state->pid == who && (WIFEXITED(status) || + WIFSIGNALED(status))) { return true; } + if (who == 0) { + return false; + } if (who == -1 && errno != EINTR) { warn("waitpid"); return false; |