Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Subshell with multios causes hang



Hi, since upgrading from 2.4.5 to 2.4.6 I find that one of my functions
which uses a multios redirect on a subshell list is hanging. I tried
4.3.4 as well with no luck.

Essentially I run the equivalent of:

   ( echo hello ) >| /tmp/out >| /tmp/out2

and in an interactive shell (or any with job control) this hangs.

Digging a little I find the change between 2.4.5 and 2.4.6 which causes
this was the fix to clearjobtab() in jobs.c to make it actually clear
the job table. What happens is this:

    entersubsh() calls clearjobtab() which clears the job table.
        Note thisjob == 1 at this point.

    The multios are applied, starting a subprocess in closemn().

    closemn() registers the pid of the subprocess with addproc()
       This updates the auxprocs list for thisjob (still == 1).
       Note that the stat of thisjob is 0 (not in use), since the jobtab
       was cleared, so this seems wrong.

    execpline is called to run the subshell list, and calls initjob().
       The new job is given number 1, since this is the first free slot.
       Note that the pid for the multios is still in the auxprocs list
       for job 1, this seems very wrong.

    When the echo has finished, execpline() proceeds to wait for the
    auxproc pid, since this is listed against the current job. This
    hangs, since the multios process is still reading the unclosed
    pipe.

All of the following fixes solve this problem, but I don't know what
else they break:

    Not clearing the job table in clearjobtab() - works, but just seems
wrong, and a step backwards.

    Preserving the entry for "thisjob" in clearjobtab() - not much
better, it might be a subjob and it's parent is no longer there, and
it's pid lists might not be valid.

    Setting thisjob = -1 in clearjobtab(), since there is no current
job, and making addproc() ignore the addition of aux processes if
thisjob == -1. This also seems wrong, as we are completely loosing the
pid information for the multios, so for example we can't kill it.

    Setting thisjob = 1 in clearjobtab (if it was >= 0), and setting
jobtab[thisjob].stat = STAT_INUSE after clearing jobtab. This is what I
ended up with, but is it a valid thing to do ?

Thanks for any help, and for reading this stupidly long post...



Messages sorted by: Reverse Date, Date, Thread, Author