Currently dash does not reap dead children after built-in commands
or functions.  This means that if you construct a loop consisting
of solely built-in commands and functions, then zombies can hang
around indefinitely.

This patch fixes this by reaping when necessary after each built-in
command and function.

Reported-by: Denys Vlasenko <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>

diff --git a/src/eval.c b/src/eval.c
index 7498f9d..19e06ec 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -848,6 +848,8 @@ bail:
                goto out;
        }
 
+       jp = NULL;
+
        /* Execute the command. */
        switch (cmdentry.cmdtype) {
        default:
@@ -856,7 +858,6 @@ bail:
                        INTOFF;
                        jp = makejob(cmd, 1);
                        if (forkshell(jp, cmd, FORK_FG) != 0) {
-                               status = waitforjob(jp);
                                INTON;
                                break;
                        }
@@ -875,22 +876,22 @@ bail:
                if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
                        if (exception == EXERROR && spclbltin <= 0) {
                                FORCEINTON;
-                               goto readstatus;
+                               break;
                        }
 raise:
                        longjmp(handler->loc, 1);
                }
-               goto readstatus;
+               break;
 
        case CMDFUNCTION:
                poplocalvars(1);
                if (evalfun(cmdentry.u.func, argc, argv, flags))
                        goto raise;
-readstatus:
-               status = exitstatus;
                break;
        }
 
+       status = waitforjob(jp);
+
 out:
        if (cmd->ncmd.redirect)
                popredir(execcmd);
diff --git a/src/jobs.c b/src/jobs.c
index f0d34ab..1a97c54 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -53,6 +53,7 @@
 #include <termios.h>
 #undef CEOF                    /* syntax.h redefines this */
 #endif
+#include "eval.h"
 #include "redir.h"
 #include "show.h"
 #include "main.h"
@@ -973,10 +974,11 @@ waitforjob(struct job *jp)
 {
        int st;
 
-       TRACE(("waitforjob(%%%d) called\n", jobno(jp)));
-       while (jp->state == JOBRUNNING) {
+       TRACE(("waitforjob(%%%d) called\n", jp ? jobno(jp) : 0));
+       while ((jp && jp->state == JOBRUNNING) || gotsigchld)
                dowait(DOWAIT_BLOCK, jp);
-       }
+       if (!jp)
+               return exitstatus;
        st = getstatus(jp);
 #if JOBS
        if (jp->jobctl) {
-- 
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line "unsubscribe dash" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to