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

Re: "echo | ps -j $(:) | cat | cat | cat" runs components in different process groups

On Mar 23,  4:36pm, Bart Schaefer wrote:
} Zsh wants to use "echo" as the group leader because it was the first to
} fork, but because $(:) delayed the execution of "ps" the "echo" process
} has already exited and cannot be made group leader.  As the fallback the
} other processes each get made into its own process group.
} So it's a race condition, adding the process substitution just happens
} to expose it.

It may be this easy?

It fixes the specific example in the subject by causing the zsh parent
shell to re-assume job leader for all subsequent processes in the pipeline
if the current leader is dead.  However, I'm concerned that if the first
leader is reaped after a few processes in a long pipeline are created,
there may still be a new process group asserted for remaining processes.

On the other hand I haven't found an example where that occurs, instead
I get jobs where the process group ID is the PID of the now-dead leader.
It could be I just haven't constructed the right test.   

In any case "make check" still passes and this appears to be better than
the previous situation.

diff --git a/Src/exec.c b/Src/exec.c
index 35b0bb1..52b0eb4 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -3455,6 +3455,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 	if (type == WC_SUBSH && !(how & Z_ASYNC))
 	    flags |= ESUB_JOB_CONTROL;
 	filelist = jobtab[thisjob].filelist;
+	list_pipe_child = list_pipe;
 	forked = 1;

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