summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--src/jobs.c6
-rw-r--r--src/trap.c8
-rw-r--r--src/trap.h1
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);