This patch ensures that waitcmd never blocks unless there are
outstanding jobs.  This could otherwise trigger a hang if children
were created prior to the shell coming into existence, or if
there are backgrounded children of other kinds (e.g., a here-
document).

Fixes: 6c691b3e5099 ("jobs: Only clear gotsigchld when waiting...")
Reported-by: Michael Biebl <bi...@debian.org>
Signed-off-by: Herbert Xu <herb...@gondor.apana.org.au>

diff --git a/src/jobs.c b/src/jobs.c
index 3417633..516786f 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -81,6 +81,7 @@
 #define DOWAIT_NONBLOCK 0
 #define DOWAIT_BLOCK 1
 #define DOWAIT_WAITCMD 2
+#define DOWAIT_WAITCMD_ALL 4
 
 /* array of jobs */
 static struct job *jobtab;
@@ -615,7 +616,7 @@ waitcmd(int argc, char **argv)
                                jp->waited = 1;
                                jp = jp->prev_job;
                        }
-                       if (!dowait(DOWAIT_WAITCMD, 0))
+                       if (!dowait(DOWAIT_WAITCMD_ALL, 0))
                                goto sigout;
                }
        }
@@ -1138,6 +1139,7 @@ static int dowait(int block, struct job *jp)
                pid = waitone(block, jp);
                rpid &= !!pid;
 
+               block &= ~DOWAIT_WAITCMD_ALL;
                if (!pid || (jp && jp->state != JOBRUNNING))
                        block = DOWAIT_NONBLOCK;
        } while (pid >= 0);
-- 
Email: Herbert Xu <herb...@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

Reply via email to