Re: [PATCH v2] ash: fix wait -n behavior for multiple PIDs and pipe jobs
"Roberto A. Foglietta via busybox" <[email protected]> Wed, 1 Apr 2026 13:23:19 +0200
| Newsgroups | gmane.linux.busybox |
|---|---|
| Message-ID | <CAJGKYO6uwjc0M-ZmKnUC=GaTdFvMzca+40zf5o_55ZnZPks13g@mail.gmail.com> |
On Wed, 1 Apr 2026 at 02:18, Roberto A. Foglietta <[email protected]> wrote: > > On Wed, 1 Apr 2026 at 01:29, Luiz Angelo Daros de Luca > <[email protected]> wrote: > > > > > Please, create a patch file (otherwise space and tab can mixup) on the > > > top of the HEAD of this branch: > > > > > > - https://github.com/robang74/busybox/tree/bugfixes > > > > > > and I am going to transfer your patch to that branch as well. > > > Contributions of others before your patch (especially when already > > > tested) are not going to be removed but integrated unless your patch > > > provides sensitive benefits like a relevant size reduction or > > > complexity. > > > > > > Best regards, R- > > > > Hi Roberto, > > > > At this moment, my main goal is to have this patch reviewed and merged > > directly into the official BusyBox upstream. Since the patch was > > developed and tested against the official master branch, I would > > prefer to keep the focus there for now. > > https://github.com/robang74/busybox/tree/ashfix2 > Two patches can be interesting for the m-list: the first is a size reduction, the second seems to be a necessary bug fixing. https://github.com/robang74/busybox/tree/bugfixes Best regards, R- _______________________________________________ busybox mailing list [email protected] https://lists.busybox.net/mailman/listinfo/busybox
0001-robang74-bugfixes-addons-patches.patch
(text/x-patch, 3.1 KB)
commit 779a9b7d0bd72bdacb3bfe2d57008cf606449169 Author: Roberto A. Foglietta <[email protected]> Date: Wed Apr 1 11:04:42 2026 +0200 ash: waitcmd() more readeability and smaller size, same tests results text data bss dec hex filename 1105644 16915 1856 1124415 11283f busybox 1105619 16915 1856 1124390 112826 busybox (-25 bytes) for i in shell/ash_test/ash-misc/wait*.tests ; do ./busybox ash $i; done Wait 1 returned: 42. (expects 42) p1 active: 1 (expects 0) p2 active: 1 (expects 1) Wait 2 returned: 41 (expects 41) Wait 3 returned: 41 (expects 41) Wait 4 returned: 127 (expects 127) Wait 5 returned: 42 (expects 42) Wait 6 returned: 42 (expects 42) Wait 7 returned: 42 (expects 42) Wait 8 returned: 42 (expects 42) Wait 9 returned: 42 (expects 42) Wait 10 returned: 42 (expects 42) Wait 11 returned: 127 (expects 127) Wait 12 returned: 42 (expects 42) p7 active: 0 (expects 0) Wait 13 returned: 127 (expects 127) P1 done P2 done Wait returned: 0 First wait -n returned: 42 (expects 42) Second wait -n returned: 43 (expects 41) Third wait -n returned: 43 (expects 43) Three:3 Zero:0 Three:3 0 3 Background1 Ok:0 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) wait -n from USR1 prints after USR1 wait from USR1 prints after USR1 (2) Signed-off-by: Roberto A. Foglietta <[email protected]> diff --git a/shell/ash.c b/shell/ash.c index 99cd9d984..1e8d5657c 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -4282,6 +4282,9 @@ sprint_status48(char *os, int status, int sigonly) return s - os; } +#define joblstidx(p) ((p)->nprocs - 1) +#define joblstjob(p) ({ struct job *_p=(p); _p->ps[joblstidx(_p)]; }) + /* Called only on finished or stopped jobs (no members are running) */ static int getstatus(struct job *job) @@ -4291,7 +4294,7 @@ getstatus(struct job *job) struct procstat *ps; /* Fetch last member's status */ - ps = job->ps + job->nprocs - 1; + ps = job->ps + joblstidx(job); status = ps->ps_status; if (pipefail) { /* "set -o pipefail" mode: use last _nonzero_ status */ @@ -4867,11 +4870,8 @@ waitcmd(int argc UNUSED_PARAM, char **argv) */ oneout: jp->waited = 1; - status = jp->ps[jp->nprocs - 1].ps_status; - if (status != -1 && !WIFSTOPPED(status)) { - retval = WEXITSTATUS(status); - if (WIFSIGNALED(status)) - retval = 128 | WTERMSIG(status); + if (!WIFSTOPPED(joblstjob(jp).ps_status)) { + retval = getstatus(jp); goto ret; } } @@ -4887,7 +4887,7 @@ oneout: while (1) { if (!job) goto repeat; - if (job->ps[job->nprocs - 1].ps_pid == pid) + if (joblstjob(job).ps_pid == pid) break; job = job->prev_job; } ________________________________________________________________________ files in commited: shell/ash.c
0002-robang74-bugfixes-addons-patches.patch
(text/x-patch, 856 B)
commit 980d370456f115332efe132315448d539ade7340 Author: Roberto A. Foglietta <[email protected]> Date: Wed Apr 1 13:16:24 2026 +0200 ash: prevents waitone() returns after INTOFF before INTON Requires thisjob = NULL (ok) set explicetely or INTON; return NULL; Signed-off-by: Roberto A. Foglietta <[email protected]> diff --git a/shell/ash.c b/shell/ash.c index 1e8d5657c..9c6a00614 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -4403,7 +4403,7 @@ static struct job *waitone(int block, struct job *job) pid = waitproc(block, &status); TRACE(("wait returns pid %d, status=%d\n", pid, status)); if (pid <= 0) - return NULL; + goto out; for (jp = curjob; jp; jp = jp->prev_job) { int jobstate; ________________________________________________________________________ files in commited: shell/ash.c