--- execute_cmd.c +++ execute_cmd.c 2010-08-16 15:40:41.975126155 +0200 @@ -256,6 +256,8 @@ int match_ignore_case = 0; struct stat SB; /* used for debugging */ +extern void addjstatus(COMMAND *, int); + static int special_builtin_failed; static COMMAND *currently_executing_command; @@ -1525,7 +1527,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 +2049,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,15 +2156,52 @@ 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 1 + if (!asynchronous && pipe_out == NO_PIPE && prev > 0 + && cmd->type != cm_subshell && ((cmd->flags & CMD_WANT_SUBSHELL) == 0)) + { + lstdin = move_to_high_fd(0, 0, 255); + if (lstdin > 0) + { + dup2(prev, 0); + close(prev); + prev = NO_PIPE; + cmd->flags |= CMD_SYNC_PIPE; + add_process((char*)0, getpid()); + stop_pipeline (0, cmd); + add_unwind_protect (restore_stdin, lstdin); + } + } +#endif + 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 + if (cmd->flags & CMD_SYNC_PIPE) + { + addjstatus(cmd, exec_result); + cmd->flags &= ~CMD_SYNC_PIPE; + } + QUIT; return (exec_result); } --- jobs.c +++ jobs.c 2010-08-16 15:48:19.479125702 +0200 @@ -260,7 +260,6 @@ static int processes_in_job __P((int)); static void realloc_jobs_list __P((void)); static int compact_jobs_list __P((int)); static int discard_pipeline __P((PROCESS *)); -static void add_process __P((char *, pid_t)); static void print_pipeline __P((PROCESS *, int, int, FILE *)); static void pretty_print_job __P((int, int, FILE *)); static void set_current_job __P((int)); @@ -1065,7 +1064,7 @@ nohup_job (job_index) if (js.j_jobslots == 0) return; - if (temp = jobs[job_index]) + if ((temp = jobs[job_index])) temp->flags |= J_NOHUP; } @@ -1095,7 +1094,7 @@ discard_pipeline (chain) /* Add this process to the chain being built in the_pipeline. NAME is the command string that will be exec'ed later. PID is the process id of the child. */ -static void +void add_process (name, pid) char *name; pid_t pid; @@ -3396,6 +3395,34 @@ setjstatus (j) #endif } + +void +addjstatus(COMMAND *deferred, int status) +{ +#if defined (ARRAY_VARS) + int i; + JOB *j; + for (j = jobs[(i = 0)]; j && j->deferred != deferred; j = jobs[(++i)]) + ; + if (!j || !j->deferred) + return; + j->deferred = (COMMAND*)0; + if (status) + { + PROCESS *p, *l; + p = j->pipe; + do + { + l = p; + p = p->next; + } + while (p != j->pipe); + l->status = status << 8; + } + setjstatus(i); +#endif +} + void run_sigchld_trap (nchild) int nchild; --- jobs.h +++ jobs.h 2010-08-16 15:47:22.463125472 +0200 @@ -177,6 +177,8 @@ extern void save_pipeline __P((int)); extern void restore_pipeline __P((int)); extern void start_pipeline __P((void)); extern int stop_pipeline __P((int, COMMAND *)); +extern void add_process __P((char *, pid_t)); +extern void addjstatus __P((COMMAND *, int)); extern void delete_job __P((int, int)); extern void nohup_job __P((int));