about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/exec.c79
1 files changed, 16 insertions, 63 deletions
diff --git a/Src/exec.c b/Src/exec.c
index 6ed0af6e2..e853affeb 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -1878,8 +1878,6 @@ static void
 execpline2(Estate state, wordcode pcode,
 	   int how, int input, int output, int last1)
 {
-    pid_t pid;
-    int pipes[2];
     struct execcmd_params eparams;
 
     if (breaks || retflag)
@@ -1900,65 +1898,21 @@ execpline2(Estate state, wordcode pcode,
     }
     if (WC_PIPE_TYPE(pcode) == WC_PIPE_END) {
 	execcmd_analyse(state, &eparams);
-	execcmd_exec(state, &eparams, input, output, how, last1 ? 1 : 2);
+	execcmd_exec(state, &eparams, input, output, how, last1 ? 1 : 2, -1);
     } else {
+	int pipes[2];
 	int old_list_pipe = list_pipe;
-	int subsh_close = -1;
-	Wordcode next = state->pc + (*state->pc), start_pc;
+	Wordcode next = state->pc + (*state->pc);
 
-	start_pc = ++state->pc;
+	++state->pc;
 	execcmd_analyse(state, &eparams);
 
 	if (mpipe(pipes) < 0) {
 	    /* FIXME */
 	}
 
-	/* if we are doing "foo | bar" where foo is a current *
-	 * shell command, do foo in a subshell and do the     *
-	 * rest of the pipeline in the current shell.         */
-	if ((eparams.type >= WC_CURSH || !eparams.args)
-	    && (how & Z_SYNC)) {
-	    int synch[2];
-	    struct timeval bgtime;
-
-	    if (pipe(synch) < 0) {
-		zerr("pipe failed: %e", errno);
-		lastval = 1;
-		errflag |= ERRFLAG_ERROR;
-		return;
-	    } else if ((pid = zfork(&bgtime)) == -1) {
-		close(synch[0]);
-		close(synch[1]);
-		lastval = 1;
-		errflag |= ERRFLAG_ERROR;
-		return;
-	    } else if (pid) {
-		char dummy, *text;
-
-		text = getjobtext(state->prog, start_pc);
-		addproc(pid, text, 0, &bgtime);
-		close(synch[1]);
-		read_loop(synch[0], &dummy, 1);
-		close(synch[0]);
-	    } else {
-		zclose(pipes[0]);
-		close(synch[0]);
-		entersubsh(((how & Z_ASYNC) ? ESUB_ASYNC : 0)
-			   | ESUB_PGRP | ESUB_KEEPTRAP);
-		close(synch[1]);
-		if (sigtrapped[SIGEXIT])
-		{
-		    unsettrap(SIGEXIT);
-		}
-		execcmd_exec(state, &eparams, input, pipes[1], how, 1);
-		_exit(lastval);
-	    }
-	} else {
-	    /* otherwise just do the pipeline normally. */
-	    addfilelist(NULL, pipes[0]);
-	    subsh_close = pipes[0];
-	    execcmd_exec(state, &eparams, input, pipes[1], how, 0);
-	}
+	addfilelist(NULL, pipes[0]);
+	execcmd_exec(state, &eparams, input, pipes[1], how, 0, pipes[0]);
 	zclose(pipes[1]);
 	state->pc = next;
 
@@ -1969,8 +1923,6 @@ execpline2(Estate state, wordcode pcode,
 	execpline2(state, *state->pc++, how, pipes[0], output, last1);
 	list_pipe = old_list_pipe;
 	cmdpop();
-	if (subsh_close != pipes[0])
-	    zclose(pipes[0]);
     }
 }
 
@@ -2710,7 +2662,8 @@ static void execcmd_getargs(LinkList preargs, LinkList args, int expand)
 /**/
 static int
 execcmd_fork(Estate state, int how, int type, Wordcode varspc,
-	     LinkList *filelistp, char *text, int oautocont)
+	     LinkList *filelistp, char *text, int oautocont,
+	     int close_if_forked)
 {
     pid_t pid;
     int synch[2], flags;
@@ -2766,6 +2719,7 @@ execcmd_fork(Estate state, int how, int type, Wordcode varspc,
     *filelistp = jobtab[thisjob].filelist;
     entersubsh(flags);
     close(synch[1]);
+    zclose(close_if_forked);
 
     if (sigtrapped[SIGINT] & ZSIG_IGNORED)
 	holdintr();
@@ -2786,7 +2740,7 @@ execcmd_fork(Estate state, int how, int type, Wordcode varspc,
 /**/
 static void
 execcmd_exec(Estate state, Execcmd_params eparams,
-	     int input, int output, int how, int last1)
+	     int input, int output, int how, int last1, int close_if_forked)
 {
     HashNode hn = NULL;
     LinkList filelist = NULL;
@@ -2863,19 +2817,18 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 	    pushnode(args, dupstring("fg"));
     }
 
-    if ((how & Z_ASYNC) || (output && !last1)) {
+    if ((how & Z_ASYNC) || output) {
 	/*
 	 * If running in the background, or not the last command in a
-	 * pipeline and not already forked, we don't need any of
-	 * the rest of this function to affect the state in the
-	 * main shell, so fork immediately.
+	 * pipeline, we don't need any of the rest of this function to
+	 * affect the state in the main shell, so fork immediately.
 	 *
 	 * In other cases we may need to process the command line
 	 * a bit further before we make the decision.
 	 */
 	text = getjobtext(state->prog, eparams->beg);
 	switch (execcmd_fork(state, how, type, varspc, &filelist,
-			     text, oautocont)) {
+			     text, oautocont, close_if_forked)) {
 	case -1:
 	    goto fatal;
 	case 0:
@@ -2883,7 +2836,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 	default:
 	    return;
 	}
-	forked = 1;
+	last1 = forked = 1;
     } else
 	text = NULL;
 
@@ -3525,7 +3478,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 	     (!is_cursh && (last1 != 1 || nsigtrapped || havefiles() ||
 			    fdtable_flocks)))) {
 	    switch (execcmd_fork(state, how, type, varspc, &filelist,
-				 text, oautocont)) {
+				 text, oautocont, close_if_forked)) {
 	    case -1:
 		goto fatal;
 	    case 0: