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:52 +0000 |
commit | 1d2a587ef9f8310da6a9203bd1fff43d61ca66f7 (patch) | |
tree | 61825f532fbbac4977d97e3c8f5029bc0ce6ebc5 | |
parent | 285f941478d83b04fbbc53ee4003705cd41199b3 (diff) | |
download | src-1d2a587ef9f8310da6a9203bd1fff43d61ca66f7.tar.gz src-1d2a587ef9f8310da6a9203bd1fff43d61ca66f7.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; |