Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Jan 2015 23:40:39 +0000 (UTC)
From:      Baptiste Daroussin <bapt@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r276771 - head/usr.bin/timeout
Message-ID:  <201501062340.t06Ned3H006835@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bapt
Date: Tue Jan  6 23:40:39 2015
New Revision: 276771
URL: https://svnweb.freebsd.org/changeset/base/276771

Log:
  Use the new process reaper functionality
  
  When not using the --foreground option timeout(1) is supported to signal all
  command children hierarchy, timeout(1) now acquire the reaper to ensure this
  really happens and no children process can escaper from timeout(1) control

Modified:
  head/usr.bin/timeout/timeout.c

Modified: head/usr.bin/timeout/timeout.c
==============================================================================
--- head/usr.bin/timeout/timeout.c	Tue Jan  6 23:08:47 2015	(r276770)
+++ head/usr.bin/timeout/timeout.c	Tue Jan  6 23:40:39 2015	(r276771)
@@ -28,6 +28,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/procctl.h>
 #include <sys/time.h>
 #include <sys/wait.h>
 
@@ -166,12 +167,14 @@ main(int argc, char **argv)
 	int foreground, preserve;
 	int error, pstat, status;
 	int killsig = SIGTERM;
-	pid_t pgid, pid, cpid;
+	pid_t pid, cpid;
 	double first_kill;
 	double second_kill;
 	bool timedout = false;
 	bool do_second_kill = false;
 	struct sigaction signals;
+	struct procctl_reaper_status info;
+	struct procctl_reaper_kill killemall;
 	int signums[] = {
 		-1,
 		SIGTERM,
@@ -185,7 +188,6 @@ main(int argc, char **argv)
 	foreground = preserve = 0;
 	second_kill = 0;
 	cpid = -1;
-	pgid = -1;
 
 	const struct option longopts[] = {
 		{ "preserve-status", no_argument,       &preserve,    1 },
@@ -225,10 +227,9 @@ main(int argc, char **argv)
 	argv++;
 
 	if (!foreground) {
-		pgid = setpgid(0,0);
-
-		if (pgid == -1)
-			err(EX_OSERR, "setpgid()");
+		/* Aquire a reaper */
+		if (procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) == -1)
+			err(EX_OSERR, "Fail to acquire the reaper");
 	}
 
 	memset(&signals, 0, sizeof(signals));
@@ -285,15 +286,27 @@ main(int argc, char **argv)
 
 			if (cpid == pid) {
 				pstat = status;
-				break;
+				if (!foreground)
+					break;
+			}
+			if (!foreground) {
+				procctl(P_PID, getpid(), PROC_REAP_STATUS,
+				    &info);
+				if (info.rs_children == 0) {
+					cpid = pid;
+					break;
+				}
 			}
 		} else if (sig_alrm) {
 			sig_alrm = 0;
 
 			timedout = true;
-			if (!foreground)
-				killpg(pgid, killsig);
-			else
+			if (!foreground) {
+				killemall.rk_sig = killsig;
+				killemall.rk_flags = 0;
+				procctl(P_PID, getpid(), PROC_REAP_KILL,
+				    &killemall);
+			} else
 				kill(pid, killsig);
 
 			if (do_second_kill) {
@@ -305,9 +318,12 @@ main(int argc, char **argv)
 				break;
 
 		} else if (sig_term) {
-			if (!foreground)
-				killpg(pgid, killsig);
-			else
+			if (!foreground) {
+				killemall.rk_sig = sig_term;
+				killemall.rk_flags = 0;
+				procctl(P_PID, getpid(), PROC_REAP_KILL,
+				    &killemall);
+			} else
 				kill(pid, sig_term);
 
 			if (do_second_kill) {
@@ -325,6 +341,9 @@ main(int argc, char **argv)
 			err(EX_OSERR, "waitpid()");
 	}
 
+	if (!foreground)
+		procctl(P_PID, getpid(), PROC_REAP_RELEASE, NULL);
+
 	if (WEXITSTATUS(pstat))
 		pstat = WEXITSTATUS(pstat);
 	else if(WIFSIGNALED(pstat))



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501062340.t06Ned3H006835>