Date: Mon, 9 Jun 2025 23:53:21 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 81ef00125056 - main - timeout(1): pass full 32bit error return code from the exited child Message-ID: <202506092353.559NrLOa006855@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=81ef00125056a68ca3bba1424d6cb13533bf474c commit 81ef00125056a68ca3bba1424d6cb13533bf474c Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2025-06-09 03:20:16 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2025-06-09 23:52:34 +0000 timeout(1): pass full 32bit error return code from the exited child Switch to use waitid(2) to receive siginfo_t with the complete error code from the exited process. Tested by: pho Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D50752 --- bin/timeout/timeout.c | 58 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/bin/timeout/timeout.c b/bin/timeout/timeout.c index f47976aa27df..58a5797f3eaf 100644 --- a/bin/timeout/timeout.c +++ b/bin/timeout/timeout.c @@ -277,12 +277,25 @@ kill_self(int signo) sys_signame[signo], signo); } +static void +log_termination(const char *name, const siginfo_t *si) +{ + if (si->si_code == CLD_EXITED) { + logv("%s: pid=%d, exit=%d", name, si->si_pid, si->si_status); + } else if (si->si_code == CLD_DUMPED || si->si_code == CLD_KILLED) { + logv("%s: pid=%d, sig=%d", name, si->si_pid, si->si_status); + } else { + logv("%s: pid=%d, reason=%d, status=%d", si->si_pid, + si->si_code, si->si_status); + } +} + int main(int argc, char **argv) { - int ch, status, sig; + int ch, sig; int pstat = 0; - pid_t pid, cpid; + pid_t pid; int pp[2], error; char c; double first_kill; @@ -295,6 +308,7 @@ main(int argc, char **argv) sigset_t zeromask, allmask, oldmask; struct sigaction sa; struct procctl_reaper_status info; + siginfo_t si, child_si; const char optstr[] = "+fhk:ps:v"; const struct option longopts[] = { @@ -414,26 +428,27 @@ main(int argc, char **argv) if (sig_chld) { sig_chld = 0; - while ((cpid = waitpid(-1, &status, WNOHANG)) != 0) { - if (cpid < 0) { + for (;;) { + memset(&si, 0, sizeof(si)); + error = waitid(P_ALL, -1, &si, WEXITED | + WNOHANG); + if (error == -1) { if (errno != EINTR) break; - } else if (cpid == pid) { - pstat = status; + } else if (si.si_pid == pid) { + child_si = si; child_done = true; - logv("child terminated: pid=%d, " - "exit=%d, signal=%d", - (int)pid, WEXITSTATUS(status), - WTERMSIG(status)); - } else { + log_termination("child terminated", + &child_si); + } else if (si.si_pid != 0) { /* * Collect grandchildren zombies. * Only effective if we're a reaper. */ - logv("collected zombie: pid=%d, " - "exit=%d, signal=%d", - (int)cpid, WEXITSTATUS(status), - WTERMSIG(status)); + log_termination("collected zombie", + &si); + } else /* si.si_pid == 0 */ { + break; } } if (child_done) { @@ -482,13 +497,14 @@ main(int argc, char **argv) if (timedout && !preserve) { pstat = EXIT_TIMEOUT; + } else if (child_si.si_code == CLD_DUMPED || + child_si.si_code == CLD_KILLED) { + kill_self(child_si.si_status); + /* NOTREACHED */ + } else if (child_si.si_code == CLD_EXITED) { + pstat = child_si.si_status; } else { - if (WIFSIGNALED(pstat)) - kill_self(WTERMSIG(pstat)); - /* NOTREACHED */ - - if (WIFEXITED(pstat)) - pstat = WEXITSTATUS(pstat); + pstat = EXIT_FAILURE; } return (pstat);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202506092353.559NrLOa006855>