aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/timeout/timeout.c
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2015-01-06 23:40:39 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2015-01-06 23:40:39 +0000
commitff7c6d42f33a0ccfa690c48b62e7381721317cc3 (patch)
tree1f6579e5d9cc7170a6ea3bad9ac2e3590a78d8d3 /usr.bin/timeout/timeout.c
parent814e92e9d860fd4a8c50c2a70126853db6a9b2e2 (diff)
Notes
Diffstat (limited to 'usr.bin/timeout/timeout.c')
-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 214ab138d393c..06dc086462bf1 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))