git: 06c74693c286 - main - timeout(1): Also send SIGCONT because the child may be stopped

From: Baptiste Daroussin <bapt_at_FreeBSD.org>
Date: Wed, 16 Apr 2025 19:46:32 UTC
The branch main has been updated by bapt:

URL: https://cgit.FreeBSD.org/src/commit/?id=06c74693c286185f299410afcd312fc54a96a052

commit 06c74693c286185f299410afcd312fc54a96a052
Author:     Aaron LI <aly@aaronly.me>
AuthorDate: 2025-04-02 16:01:17 +0000
Commit:     Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2025-04-16 19:45:38 +0000

    timeout(1): Also send SIGCONT because the child may be stopped
    
    The POSIX.1-2024 says:
    
    "If the subsequent wait status of the child process shows that it was
    stopped by a signal, a SIGCONT signal shall also be sent in the same
    manner as the first signal; otherwise, a SIGCONT signal may be sent in
    the same manner."
    
    As it's allowed by the standard, we just always send the SIGCONT signal
    to the child process regardless of its stop state, so that timeout could
    terminate a stopped child.
    
    Obtained-from: DragonFly BSD
    Reference: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/timeout.html
---
 bin/timeout/timeout.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/bin/timeout/timeout.c b/bin/timeout/timeout.c
index 8f933f509407..e702803a25c2 100644
--- a/bin/timeout/timeout.c
+++ b/bin/timeout/timeout.c
@@ -179,6 +179,24 @@ send_sig(pid_t pid, int signo, bool foreground)
 			      (int)rk.rk_fpid);
 		logv("signaled %u processes", rk.rk_killed);
 	}
+
+	/*
+	 * If the child process was stopped by a signal, POSIX.1-2024
+	 * requires to send a SIGCONT signal.  However, the standard also
+	 * allows to send a SIGCONT regardless of the stop state, as we
+	 * are doing here.
+	 */
+	if (signo != SIGKILL && signo != SIGSTOP && signo != SIGCONT) {
+		logv("sending signal %s(%d) to command '%s'",
+		     sys_signame[SIGCONT], SIGCONT, command);
+		if (foreground) {
+			kill(pid, SIGCONT);
+		} else {
+			memset(&rk, 0, sizeof(rk));
+			rk.rk_sig = SIGCONT;
+			procctl(P_PID, getpid(), PROC_REAP_KILL, &rk);
+		}
+	}
 }
 
 static void