git: 8eaa6be80d6a - main - daemon(8): handle case of waitpid() returning without exited child
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 20 Mar 2024 01:07:13 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=8eaa6be80d6aef6a118fa854a860bfdaeb7ed753 commit 8eaa6be80d6aef6a118fa854a860bfdaeb7ed753 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2024-03-18 08:44:39 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2024-03-20 01:07:00 +0000 daemon(8): handle case of waitpid() returning without exited child Not checking for either WIFEXITED(status) or zero result results in never finishing the loop. PR: 277764 Reviewed by: kevans (previous version) Discussed with: Daniel Tameling Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D44401 --- usr.sbin/daemon/daemon.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/usr.sbin/daemon/daemon.c b/usr.sbin/daemon/daemon.c index 6cde194cf16e..bce215af75d1 100644 --- a/usr.sbin/daemon/daemon.c +++ b/usr.sbin/daemon/daemon.c @@ -755,18 +755,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;