summaryrefslogtreecommitdiffstats
path: root/usr.bin/timeout/timeout.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/timeout/timeout.c')
-rw-r--r--usr.bin/timeout/timeout.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/usr.bin/timeout/timeout.c b/usr.bin/timeout/timeout.c
index 06dc086..a682dde 100644
--- a/usr.bin/timeout/timeout.c
+++ b/usr.bin/timeout/timeout.c
@@ -172,6 +172,7 @@ main(int argc, char **argv)
double second_kill;
bool timedout = false;
bool do_second_kill = false;
+ bool child_done = false;
struct sigaction signals;
struct procctl_reaper_status info;
struct procctl_reaper_kill killemall;
@@ -187,7 +188,6 @@ main(int argc, char **argv)
foreground = preserve = 0;
second_kill = 0;
- cpid = -1;
const struct option longopts[] = {
{ "preserve-status", no_argument, &preserve, 1 },
@@ -281,20 +281,26 @@ main(int argc, char **argv)
if (sig_chld) {
sig_chld = 0;
- while (((cpid = wait(&status)) < 0) && errno == EINTR)
- continue;
- if (cpid == pid) {
- pstat = status;
- if (!foreground)
- break;
+ while ((cpid = waitpid(-1, &status, WNOHANG)) != 0) {
+ if (cpid < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ break;
+ } else if (cpid == pid) {
+ pstat = status;
+ child_done = true;
+ }
}
- if (!foreground) {
- procctl(P_PID, getpid(), PROC_REAP_STATUS,
- &info);
- if (info.rs_children == 0) {
- cpid = pid;
+ if (child_done) {
+ if (foreground) {
break;
+ } else {
+ procctl(P_PID, getpid(),
+ PROC_REAP_STATUS, &info);
+ if (info.rs_children == 0)
+ break;
}
}
} else if (sig_alrm) {
@@ -336,7 +342,7 @@ main(int argc, char **argv)
}
}
- while (cpid != pid && wait(&pstat) == -1) {
+ while (!child_done && wait(&pstat) == -1) {
if (errno != EINTR)
err(EX_OSERR, "waitpid()");
}
OpenPOWER on IntegriCloud