Performing a wait on the pid of a co-process fails in the following
circumstance:
    #! /bin/ksh

    ls -l |&
    pid=$!

    tee -a /tmp/out <&p

    wait $pid
    print $?

The wait's return value is always 127.  It does not matter whether the
co-process exits with a successful value (e.g., "ls -l") or an
unsuccessful value (e.g., "ls -l does-not-exist"); 127 is always
returned.

POSIX documentation on wait(1)
(http://pubs.opengroup.org/onlinepubs/009695399/utilities/wait.html)
states "If one or more pid operands are specified that represent
unknown process IDs, wait shall treat them as if they were known
process IDs that exited with exit status 127" and later on (in "Exit
Status") indicates that 127 is returned only if "[t]he command
identified by the last pid operand specified is unknown."

The sample code works correctly under the Korn shell (ksh88) supplied
by recent versions of AIX, HP-UX, and Solaris.  It also works
correctly under the pdksh-5.2.14-30.6 distributed with RHEL 4.8.

I've compiled a number of versions of ksh93 to identify when this bug
was introduced; it appears to have cropped up between
ast-ksh.2008-12-12 and ast-ksh.2009-05-01.

By examining the diffs and subsequent trial and error, I found that
the following is responsible for the failure:
--- 2008-12-12/src/cmd/ksh93/sh/jobs.c  2008-12-10 07:56:00.000000000 -0600
+++ 2009-05-01/src/cmd/ksh93/sh/jobs.c  2009-04-29 17:07:32.000000000 -0500
@@ -1176,7 +1177,8 @@
        job.pwlist = pw;
        pw->p_env = sh.curenv;
        pw->p_pid = pid;
-       pw->p_flag = P_EXITSAVE;
+       if(!sh.outpipe || sh_isoption(SH_PIPEFAIL))
+               pw->p_flag = P_EXITSAVE;
        pw->p_exitmin = sh.xargexit;
        pw->p_exit = 0;
        if(sh_isstate(SH_MONITOR))

I speculate wildly that this code change corresponds to the following
in the Changelog:
    09-01-28  A bug in which a command substitution could return an exit status
              of 127 when the pipefail option is enabled has been fixed.

By commenting out the "if" and leaving an unconditional initialization
of pw->p_flag, my specific bug is fixed (presumably at the expense of
the bug fix which prompted the addition of this code).  I have
verified that this holds true for ast-ksh.2011-02-08 as well:
--- 2011-02-08/src/cmd/ksh93/sh/jobs.c--orig    2011-07-28
13:33:32.000000000 -0500
+++ 2011-02-08/src/cmd/ksh93/sh/jobs.c  2011-07-28 13:33:50.000000000 -0500
@@ -1346,7 +1346,7 @@
        pw->p_shp = shp;
        pw->p_env = shp->curenv;
        pw->p_pid = pid;
-       if(!shp->outpipe || (sh_isoption(SH_PIPEFAIL) && job.waitall))
+       /*if(!shp->outpipe || (sh_isoption(SH_PIPEFAIL) && job.waitall))*/
                pw->p_flag = P_EXITSAVE;
        pw->p_exitmin = shp->xargexit;
        pw->p_exit = 0;

_______________________________________________
ast-developers mailing list
[email protected]
https://mailman.research.att.com/mailman/listinfo/ast-developers

Reply via email to