summaryrefslogtreecommitdiffstats
path: root/usr.bin/timeout
diff options
context:
space:
mode:
authorbapt <bapt@FreeBSD.org>2015-01-06 23:40:39 +0000
committerbapt <bapt@FreeBSD.org>2015-01-06 23:40:39 +0000
commitd7969594c9a8a347e4914f5381da2436c1a93710 (patch)
tree1f6579e5d9cc7170a6ea3bad9ac2e3590a78d8d3 /usr.bin/timeout
parent5e9fc2975a63c2815a769089f1293763b6021834 (diff)
downloadFreeBSD-src-d7969594c9a8a347e4914f5381da2436c1a93710.zip
FreeBSD-src-d7969594c9a8a347e4914f5381da2436c1a93710.tar.gz
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
Diffstat (limited to 'usr.bin/timeout')
-rw-r--r--usr.bin/timeout/timeout.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/usr.bin/timeout/timeout.c b/usr.bin/timeout/timeout.c
index 214ab13..06dc086 100644
--- a/usr.bin/timeout/timeout.c
+++ b/usr.bin/timeout/timeout.c
@@ -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))
OpenPOWER on IntegriCloud