On Wed, Jun 23, 2010 at 12:08:20PM +0200, Werner Fink wrote: > > Yet an other version of the patch to avoid trouble with the > coproc builtin tested out in tests/coproc.tests. There is one > difference more with tests/redir.tests at > > exit 3 | $EXIT > $TMPDIR/null-redir-e > echo $? -- ${pipestat...@]} > testf $TMPDIR/null-redir-e > > exit 4 | > $TMPDIR/null-redir-f > echo $? -- ${pipestat...@]} > testf $TMPDIR/null-redir-f > > which now reports > > 0 -- 3 0 > 0 -- 4 0 > > instead of > > 0 -- 0 > 0 -- 0 > > but seems to me ok.
One change more is required for an interactive bash that is that building pipes used for pgrps synchronization should be stop for the last command as this last one is now the parent its self. Werner -- "Having a smoking section in a restaurant is like having a peeing section in a swimming pool." -- Edward Burr
--- execute_cmd.c +++ execute_cmd.c 2010-06-24 09:18:46.858925084 +0200 @@ -1525,7 +1525,7 @@ static struct cpelement *cpl_search __P( static struct cpelement *cpl_searchbyname __P((char *)); static void cpl_prune __P((void)); -Coproc sh_coproc = { 0, NO_PID, -1, -1, 0, 0 }; +Coproc sh_coproc = { 0, NO_PID, -1, -1, 0, 0, 0, 0 }; cplist_t coproc_list = {0, 0, 0}; @@ -2047,13 +2047,19 @@ execute_coproc (command, pipe_in, pipe_o } #endif +static void restore_stdin(int lstdin) +{ + dup2(lstdin, 0); + close(lstdin); +} + static int execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close) COMMAND *command; int asynchronous, pipe_in, pipe_out; struct fd_bitmap *fds_to_close; { - int prev, fildes[2], new_bitmap_size, dummyfd, ignore_return, exec_result; + int lstdin, prev, fildes[2], new_bitmap_size, dummyfd, ignore_return, exec_result; COMMAND *cmd; struct fd_bitmap *fd_bitmap; @@ -2148,11 +2154,37 @@ execute_pipeline (command, asynchronous, /* Now execute the rightmost command in the pipeline. */ if (ignore_return && cmd) cmd->flags |= CMD_IGNORE_RETURN; + + begin_unwind_frame ("pipe-file-descriptors"); + lstdin = -1; + if (!asynchronous && pipe_out == NO_PIPE && prev > 0) + { + lstdin = move_to_high_fd(0, 0, 255); + if (lstdin > 0) + { + dup2(prev, 0); + close(prev); + prev = NO_PIPE; + stop_pipeline (0, (COMMAND *)NULL); + add_unwind_protect (restore_stdin, lstdin); + } + } + if (prev >= 0) + add_unwind_protect (close, prev); + exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close); + if (lstdin > 0) + { + dup2(lstdin, 0); + close(lstdin); + } + if (prev >= 0) close (prev); + discard_unwind_frame ("pipe-file-descriptors"); + #if defined (JOB_CONTROL) UNBLOCK_CHILD (oset); #endif