From: Dominique Martinet <[email protected]> wait -n would only return 127 if there is no job, not if there is no job not accounted for.
quick test: sh -c 'false & true & wait -n; echo $?; wait -n; echo $?; wait -n; echo $?' should print 1 0 127 This comes at a slight size increase: function old new delta waitcmd 334 397 +63 waitone 449 399 -50 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 63/-50) Total: 13 bytes Tested-by: Wolfgang Zekoll <[email protected]> Signed-off-by: Dominique Martinet <[email protected]> --- v1 -> v2: - apply Wolfgang's suggestion for test wording, add his tested-by shell/ash.c | 46 ++++++++++++++++------------- shell/ash_test/ash-misc/wait8.right | 2 ++ shell/ash_test/ash-misc/wait8.tests | 14 +++++++++ 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 4f5ca0d02fb7..877e09bf88d7 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -4463,7 +4463,7 @@ waitproc(int block, int *status) return err; } -static int waitone(int block, struct job *job) +static struct job *waitone(int block, struct job *job) { int pid; int status; @@ -4494,7 +4494,7 @@ static int waitone(int block, struct job *job) pid = waitproc(block, &status); TRACE(("wait returns pid %d, status=%d\n", pid, status)); if (pid <= 0) - return pid; + return NULL; for (jp = curjob; jp; jp = jp->prev_job) { int jobstate; @@ -4559,33 +4559,29 @@ static int waitone(int block, struct job *job) } } - status = INT_MAX; - if (thisjob && thisjob->state == JOBDONE) - status = thisjob->ps[thisjob->nprocs - 1].ps_status; - - return status; + return thisjob; } -static int dowait_status(void) +static struct job *dowait_status(void) { - int status, rstatus = -ENOENT; + struct job *jp, *rjp = NULL; int block = DOWAIT_CHILD_OR_SIG; do { - status = waitone(block, NULL); - if (status >= 0 && status < INT_MAX) { - rstatus = status; + jp = waitone(block, NULL); + if (jp && jp->state == JOBDONE) { + rjp = jp; block = DOWAIT_NONBLOCK; } - } while (status >= 0); + } while (jp || !rjp); - return rstatus; + return rjp; } static void dowait(int block, struct job *jp) { smallint gotchld = *(volatile smallint *)&gotsigchld; - int status; + struct job *rjp; if (jp && jp->state != JOBRUNNING) block = DOWAIT_NONBLOCK; @@ -4594,11 +4590,11 @@ static void dowait(int block, struct job *jp) return; do { - status = waitone(block, jp); + rjp = waitone(block, jp); - if (!status || (jp && jp->state != JOBRUNNING)) + if (!rjp || (jp && jp->state != JOBRUNNING)) block = DOWAIT_NONBLOCK; - } while (status >= 0); + } while (block != DOWAIT_NONBLOCK || rjp); } #if JOBS @@ -4780,12 +4776,17 @@ waitcmd(int argc UNUSED_PARAM, char **argv) if (!argv[0]) { /* wait for all jobs / one job if -n */ for (;;) { - jp = curjob; #if BASH_WAIT_N - if (one && !jp) + if (one) { + for (jp = curjob; jp; jp = jp->prev_job) { + if (jp->state == JOBDONE && !jp->waited) + goto oneout; + } /* exitcode of "wait -n" with nothing to wait for is 127, not 0 */ retval = 127; + } #endif + jp = curjob; while (1) { if (!jp) /* no running procs */ goto ret; @@ -4802,7 +4803,7 @@ waitcmd(int argc UNUSED_PARAM, char **argv) * the trap is executed." */ #if BASH_WAIT_N - status = dowait_status(); + jp = dowait_status(); #else dowait(DOWAIT_CHILD_OR_SIG, NULL); #endif @@ -4818,6 +4819,9 @@ waitcmd(int argc UNUSED_PARAM, char **argv) * date; sleep 3 & sleep 2 | sleep 1 & wait -n; date * should wait for 2 seconds. Not 1 or 3. */ +oneout: + jp->waited = 1; + status = jp->ps[jp->nprocs - 1].ps_status; if (status != -1 && !WIFSTOPPED(status)) { retval = WEXITSTATUS(status); if (WIFSIGNALED(status)) diff --git a/shell/ash_test/ash-misc/wait8.right b/shell/ash_test/ash-misc/wait8.right index 5d29b8cc7dbf..e3ebde532ab8 100644 --- a/shell/ash_test/ash-misc/wait8.right +++ b/shell/ash_test/ash-misc/wait8.right @@ -2,3 +2,5 @@ Test1 (wait with zero exit status of bg process) Test2 (wait with non-zero exit status of bg process) Test3 (pipeline wait for whole job) Ok:0 +Test4 (wait exit code with signal) +Test5 (wait -n exits 127 if nothing to wait for) diff --git a/shell/ash_test/ash-misc/wait8.tests b/shell/ash_test/ash-misc/wait8.tests index d29490260001..453f30a62156 100755 --- a/shell/ash_test/ash-misc/wait8.tests +++ b/shell/ash_test/ash-misc/wait8.tests @@ -45,3 +45,17 @@ fi kill $bg echo Ok:$? + +echo "Test4 (wait exit code with signal)" +wait -n +rc=$? +if [ "$rc" != 143 ]; then + echo "Test4 exit code was not 143 (128+SIGTERM): $rc" +fi + +echo "Test5 (wait -n exits 127 if nothing to wait for)" +wait -n +rc=$? +if [ "$rc" != 127 ]; then + echo "wait -n with nothing to wait was not 127: $rc" +fi -- 2.47.3 _______________________________________________ busybox mailing list [email protected] https://lists.busybox.net/mailman/listinfo/busybox
