Add new variable called $PIPESTAT, which contains return codes
of all processes from last executed command pipeline.
This was inspired by $PIPESTATUS array from bash, but since ash
does not have arrays, this is merely a string separated by IFS.
However the name $PIPESTATUS was not used to avoid confusion.

Example:

$ true | true | true | false | true | false
$ echo $PIPESTAT
0 0 0 256 0 256

Signed-off-by: Tomas Mudrunka <[email protected]>
---
 shell/ash.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index bbd730770..fa1a6fa3d 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -4602,6 +4602,8 @@ getstatus(struct job *job)
        int status;
        int retval;
        struct procstat *ps;
+       char pipestat[job->nprocs*24] = {};
+       size_t pipestat_offset = 0;
 
        /* Fetch last member's status */
        ps = job->ps + job->nprocs - 1;
@@ -4612,6 +4614,17 @@ getstatus(struct job *job)
                        status = ps->ps_status;
        }
 
+       /* Set $PIPESTAT */
+       ps = job->ps;
+       for (ps = job->ps ; ps < job->ps+job->nprocs; ps++) {
+               pipestat_offset += snprintf(pipestat+pipestat_offset,
+                       sizeof(pipestat)-pipestat_offset, "%d%c",
+                       ps->ps_status, *(ifsset() ? ifsval() : defifs));
+       }
+       if(pipestat_offset > 0)
+               pipestat[pipestat_offset-1]=0;
+       setvar0("PIPESTAT", pipestat);
+
        retval = WEXITSTATUS(status);
        if (!WIFEXITED(status)) {
 #if JOBS
@@ -4628,8 +4641,8 @@ getstatus(struct job *job)
                }
                retval |= 128;
        }
-       TRACE(("getstatus: job %d, nproc %d, status 0x%x, retval 0x%x\n",
-               jobno(job), job->nprocs, status, retval));
+       TRACE(("getstatus: job %d, nproc %d, status 0x%x, retval 0x%x, pipestat 
%s\n",
+               jobno(job), job->nprocs, status, retval, pipestat));
        return retval;
 }
 
@@ -5373,6 +5386,7 @@ static int
 waitforjob(struct job *jp)
 {
        int st;
+       char pipestat[24];
 
        TRACE(("waitforjob(%%%d) called\n", jp ? jobno(jp) : 0));
 
@@ -5407,6 +5421,10 @@ waitforjob(struct job *jp)
         * $ _
         */
        dowait(jp ? DOWAIT_BLOCK : DOWAIT_NONBLOCK, jp);
+
+       snprintf(pipestat, sizeof(pipestat), "%d", exitstatus);
+       setvar0("PIPESTAT", pipestat);
+
        if (!jp)
                return exitstatus;
 
-- 
2.48.1

_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox

Reply via email to