git: 086f17853677 - main - timeout(1): Enhance send_sig() and prepare for later updates

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

URL: https://cgit.FreeBSD.org/src/commit/?id=086f17853677d072b8c5f4b2440f9e3a9aea7bdf

commit 086f17853677d072b8c5f4b2440f9e3a9aea7bdf
Author:     Aaron LI <aly@aaronly.me>
AuthorDate: 2025-04-02 15:51:47 +0000
Commit:     Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2025-04-16 19:45:38 +0000

    timeout(1): Enhance send_sig() and prepare for later updates
    
    Enhance send_sig() to better encapsulate the signal sending for
    both foreground and non-foreground modes.  This also fixes the issue
    that the latter mode was missing verbose messages.
    
    In addition, improve the verbose logging for signals.
    
    Obtained-from: DragonFly BSD
---
 bin/timeout/timeout.c | 46 ++++++++++++++++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/bin/timeout/timeout.c b/bin/timeout/timeout.c
index 7e4009f8ac8a..8f933f509407 100644
--- a/bin/timeout/timeout.c
+++ b/bin/timeout/timeout.c
@@ -34,6 +34,7 @@
 #include <errno.h>
 #include <getopt.h>
 #include <signal.h>
+#include <stdarg.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -63,6 +64,19 @@ usage(void)
 	exit(EXIT_FAILURE);
 }
 
+static void
+logv(const char *fmt, ...)
+{
+	va_list ap;
+
+	if (!verbose)
+		return;
+
+	va_start(ap, fmt);
+	vwarnx(fmt, ap);
+	va_end(ap);
+}
+
 static double
 parse_duration(const char *duration)
 {
@@ -146,13 +160,25 @@ sig_handler(int signo)
 }
 
 static void
-send_sig(pid_t pid, int signo)
+send_sig(pid_t pid, int signo, bool foreground)
 {
-	if (verbose) {
-		warnx("sending signal %s(%d) to command '%s'",
-		      sys_signame[signo], signo, command);
+	struct procctl_reaper_kill rk;
+
+	logv("sending signal %s(%d) to command '%s'",
+	     sys_signame[signo], signo, command);
+	if (foreground) {
+		if (kill(pid, signo) == -1)
+			warnx("kill(%d, %s)", (int)pid, sys_signame[signo]);
+	} else {
+		memset(&rk, 0, sizeof(rk));
+		rk.rk_sig = signo;
+		if (procctl(P_PID, getpid(), PROC_REAP_KILL, &rk) == -1)
+			warnx("procctl(PROC_REAP_KILL)");
+		else if (rk.rk_fpid > 0)
+			warnx("failed to signal some processes: first pid=%d",
+			      (int)rk.rk_fpid);
+		logv("signaled %u processes", rk.rk_killed);
 	}
-	kill(pid, signo);
 }
 
 static void
@@ -188,7 +214,6 @@ main(int argc, char **argv)
 	bool child_done = false;
 	struct sigaction signals;
 	struct procctl_reaper_status info;
-	struct procctl_reaper_kill killemall;
 	int signums[] = {
 		-1,
 		SIGTERM,
@@ -329,14 +354,7 @@ main(int argc, char **argv)
 				sig_term = 0;
 			}
 
-			if (foreground) {
-				send_sig(pid, sig);
-			} else {
-				killemall.rk_sig = sig;
-				killemall.rk_flags = 0;
-				procctl(P_PID, getpid(), PROC_REAP_KILL,
-					&killemall);
-			}
+			send_sig(pid, sig, foreground);
 
 			if (do_second_kill) {
 				set_interval(second_kill);