Message ID | 20180505160243.t5rujv3eifiust5a@gondor.apana.org.au (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Herbert Xu |
Headers | show |
Herbert Xu <herbert@gondor.apana.org.au> writes: > Leah Neukirchen <leah@vuxu.org> wrote: >> Hi, >> >> as of dash 0.5.10, this script waits for the sleep to terminate before >> executing the last line, which no other /bin/sh does. >> dash 0.5.9.1 worked fine. >> >> >> #!/bin/sh >> sleep 3 & >> echo first in main shell >> ( echo in subshell; ) >> echo back to main shell >> >> >> Found by users of the Void Linux project: >> https://github.com/voidlinux/void-packages/issues/14123 > > Thanks for the report! > > This patch should fix the problem: It indeed seems to. Thanks for the quick help,
On Sun, May 06, 2018 at 12:02:43AM +0800, Herbert Xu wrote: > Subject: jobs - Do not block when waiting on SIGCHLD > Because of the nature of SIGCHLD, the process may have already been > waited on and therefore we must be prepared for the case that wait > may block. So ensure that it doesn't by using WNOHANG. > Fixes: 03876c0743a5 ("eval: Reap zombies after built-in...") > Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> > diff --git a/src/jobs.c b/src/jobs.c > index 1a97c54..6dc555f 100644 > --- a/src/jobs.c > +++ b/src/jobs.c > @@ -975,8 +975,8 @@ waitforjob(struct job *jp) > int st; > > TRACE(("waitforjob(%%%d) called\n", jp ? jobno(jp) : 0)); > - while ((jp && jp->state == JOBRUNNING) || gotsigchld) > - dowait(DOWAIT_BLOCK, jp); > + while (jp ? jp->state == JOBRUNNING : gotsigchld) > + dowait(jp ? DOWAIT_BLOCK : DOWAIT_NORMAL, jp); > if (!jp) > return exitstatus; > st = getstatus(jp); Now each of the first four executable lines of waitforjob() does something different for jp == NULL and jp != NULL. It probably makes more sense to separate the jp == NULL case into a new function.
diff --git a/src/jobs.c b/src/jobs.c index 1a97c54..6dc555f 100644 --- a/src/jobs.c +++ b/src/jobs.c @@ -975,8 +975,8 @@ waitforjob(struct job *jp) int st; TRACE(("waitforjob(%%%d) called\n", jp ? jobno(jp) : 0)); - while ((jp && jp->state == JOBRUNNING) || gotsigchld) - dowait(DOWAIT_BLOCK, jp); + while (jp ? jp->state == JOBRUNNING : gotsigchld) + dowait(jp ? DOWAIT_BLOCK : DOWAIT_NORMAL, jp); if (!jp) return exitstatus; st = getstatus(jp);