aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2010-05-27 21:37:14 +1000
committermaximilian attems <max@stro.at>2011-06-03 18:44:12 +0200
commitb47bda0656e7ebf2cbb763f03455a407800063ea (patch)
treed15faa1ace1e2f3cdedc7659e549a13ecb97cf99
parentf2b5fb829c5620f51beea565c6aa24a99253fe13 (diff)
downloadklibc-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.c6
-rw-r--r--usr/dash/trap.c8
-rw-r--r--usr/dash/trap.h1
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);