diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2010-05-27 21:37:14 +1000 |
---|---|---|
committer | maximilian attems <max@stro.at> | 2011-06-03 18:44:12 +0200 |
commit | b47bda0656e7ebf2cbb763f03455a407800063ea (patch) | |
tree | d15faa1ace1e2f3cdedc7659e549a13ecb97cf99 | |
parent | f2b5fb829c5620f51beea565c6aa24a99253fe13 (diff) | |
download | klibc-b47bda0656e7ebf2cbb763f03455a407800063ea.tar.gz |
[klibc] [JOBS] Fix wait regression where it does not wait for all
jobs
The sigsuspend patch broke wait by making it return after just
one job has completed. This is because we rely on pendingsigs
to signal work and never clear it until waitcmd finishes.
This patch adds a separate gotsigchld for this purpose so we
can clear it before we start waiting.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
[ fixup trap.c merge -maks ]
Signed-off-by: maximilian attems <max@stro.at>
-rw-r--r-- | usr/dash/jobs.c | 6 | ||||
-rw-r--r-- | usr/dash/trap.c | 8 | ||||
-rw-r--r-- | usr/dash/trap.h | 1 |
3 files changed, 12 insertions, 3 deletions
diff --git a/usr/dash/jobs.c b/usr/dash/jobs.c index bf770ddfc67ae..f429912b98830 100644 --- a/usr/dash/jobs.c +++ b/usr/dash/jobs.c @@ -1123,7 +1123,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) @@ -1131,6 +1130,7 @@ waitproc(int block, int *status) #endif do { + gotsigchld = 0; err = wait3(status, flags, NULL); if (err || !block) break; @@ -1140,11 +1140,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/usr/dash/trap.c b/usr/dash/trap.c index 6116cffe5426b..67fda1ddfd58b 100644 --- a/usr/dash/trap.c +++ b/usr/dash/trap.c @@ -79,6 +79,8 @@ char sigmode[NSIG - 1]; static char gotsig[NSIG - 1]; /* last pending signal */ volatile sig_atomic_t pendingsigs; +/* received SIGCHLD */ +int gotsigchld; #ifdef mkinit INCLUDE "trap.h" @@ -283,6 +285,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/usr/dash/trap.h b/usr/dash/trap.h index a3b190ae12e0c..f98520fa40aeb 100644 --- a/usr/dash/trap.h +++ b/usr/dash/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); |