bash-custom-action/bash-4.1-pipe.dif
2010-08-16 13:55:39 +00:00

179 lines
4.6 KiB
Plaintext

--- command.h
+++ command.h 2010-08-13 16:48:35.739125676 +0200
@@ -168,6 +168,7 @@ typedef struct element {
#define CMD_STDIN_REDIR 0x400 /* async command needs implicit </dev/null */
#define CMD_COMMAND_BUILTIN 0x0800 /* command executed by `command' builtin */
#define CMD_COPROC_SUBSHELL 0x1000
+#define CMD_SYNC_PIPE 0x2000
/* What a command looks like. */
typedef struct command {
--- 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));