diff options
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | src/jobs.c | 6 | ||||
-rw-r--r-- | src/trap.c | 8 | ||||
-rw-r--r-- | src/trap.h | 1 |
4 files changed, 13 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog index 164eb2e..54d2972 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,7 @@ * Do not poplocalvars prematurely on regular utilities. * Move null redirect checks into caller. * Fix popredir on abnormal exit from built-in. + * Fix wait regression where it does not wait for all jobs. 2010-05-26 Herbert Xu <herbert@gondor.apana.org.au> diff --git a/src/jobs.c b/src/jobs.c index a4fada0..060187c 100644 --- a/src/jobs.c +++ b/src/jobs.c @@ -1124,7 +1124,6 @@ waitproc(int block, int *status) sigset_t mask, oldmask; int flags = block == DOWAIT_BLOCK ? 0 : WNOHANG; int err; - int sig; #if JOBS if (jobctl) @@ -1132,6 +1131,7 @@ waitproc(int block, int *status) #endif do { + gotsigchld = 0; err = wait3(status, flags, NULL); if (err || !block) break; @@ -1141,11 +1141,11 @@ waitproc(int block, int *status) sigfillset(&mask); sigprocmask(SIG_SETMASK, &mask, &oldmask); - while (!(sig = pendingsigs)) + while (!gotsigchld && !pendingsigs) sigsuspend(&oldmask); sigclearmask(); - } while (sig == SIGCHLD); + } while (gotsigchld); return err; } diff --git a/src/trap.c b/src/trap.c index ba32da6..7bd60ab 100644 --- a/src/trap.c +++ b/src/trap.c @@ -78,6 +78,8 @@ char sigmode[NSIG - 1]; static char gotsig[NSIG - 1]; /* last pending signal */ volatile sig_atomic_t pendingsigs; +/* received SIGCHLD */ +int gotsigchld; extern char *signal_names[]; @@ -284,6 +286,12 @@ ignoresig(int signo) void onsig(int signo) { + if (signo == SIGCHLD) { + gotsigchld = 1; + if (!trap[SIGCHLD]) + return; + } + gotsig[signo - 1] = 1; pendingsigs = signo; diff --git a/src/trap.h b/src/trap.h index 50fc3ed..bdd7944 100644 --- a/src/trap.h +++ b/src/trap.h @@ -39,6 +39,7 @@ extern int trapcnt; extern char sigmode[]; extern volatile sig_atomic_t pendingsigs; +extern int gotsigchld; int trapcmd(int, char **); void clear_traps(void); |