From owner-svn-src-all@FreeBSD.ORG Tue Jan 6 23:40:40 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 3E7D4D56; Tue, 6 Jan 2015 23:40:40 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1F5FA6433B; Tue, 6 Jan 2015 23:40:40 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t06Nedom006836; Tue, 6 Jan 2015 23:40:39 GMT (envelope-from bapt@FreeBSD.org) Received: (from bapt@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t06Ned3H006835; Tue, 6 Jan 2015 23:40:39 GMT (envelope-from bapt@FreeBSD.org) Message-Id: <201501062340.t06Ned3H006835@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: bapt set sender to bapt@FreeBSD.org using -f From: Baptiste Daroussin Date: Tue, 6 Jan 2015 23:40:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r276771 - head/usr.bin/timeout X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 06 Jan 2015 23:40:40 -0000 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 __FBSDID("$FreeBSD$"); +#include #include #include @@ -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))