summaryrefslogtreecommitdiffstats
path: root/Src/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/exec.c')
-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: