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
This commit is contained in:
Baptiste Daroussin 2015-01-06 23:40:39 +00:00
parent 814e92e9d8
commit ff7c6d42f3

View File

@ -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;
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))