Skip site navigation (1)Skip section navigation (2)
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>