diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | Src/exec.c | 5 | ||||
-rw-r--r-- | Src/jobs.c | 10 | ||||
-rw-r--r-- | Test/D03procsubst.ztst | 15 |
4 files changed, 28 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog index 0b9df519c..dbdb22319 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2015-07-23 Peter Stephenson <p.stephenson@samsung.com> + * 35849: Src/exec.c, Src/jobs.c, Test/D03procsubst.ztst: close + file descriptors from process substitution in parent after + fork. + * 35854: Stc/hist.c: ensure character unget doesn't cause infinite recursion. diff --git a/Src/exec.c b/Src/exec.c index 4eee82bf1..7612d4303 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -3047,6 +3047,7 @@ execcmd(Estate state, int input, int output, int how, int last1) addproc(pid, text, 0, &bgtime); if (oautocont >= 0) opts[AUTOCONTINUE] = oautocont; + pipecleanfilelist(jobtab[thisjob].filelist, 1); return; } /* pid == 0 */ @@ -3492,7 +3493,7 @@ execcmd(Estate state, int input, int output, int how, int last1) if (is_shfunc) { /* It's a shell function */ - pipecleanfilelist(filelist); + pipecleanfilelist(filelist, 0); execshfunc((Shfunc) hn, args); } else { /* It's a builtin */ @@ -3682,7 +3683,7 @@ execcmd(Estate state, int input, int output, int how, int last1) DPUTS(varspc, "BUG: assignment before complex command"); list_pipe = 0; - pipecleanfilelist(filelist); + pipecleanfilelist(filelist, 0); /* If we're forked (and we should be), no need to return */ DPUTS(last1 != 1 && !forked, "BUG: not exiting?"); DPUTS(type != WC_SUBSH, "Not sure what we're doing."); diff --git a/Src/jobs.c b/Src/jobs.c index 948f61b01..a71df6838 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1179,7 +1179,7 @@ addfilelist(const char *name, int fd) /**/ void -pipecleanfilelist(LinkList filelist) +pipecleanfilelist(LinkList filelist, int proc_subst_only) { LinkNode node; @@ -1188,7 +1188,9 @@ pipecleanfilelist(LinkList filelist) node = firstnode(filelist); while (node) { Jobfile jf = (Jobfile)getdata(node); - if (jf->is_fd) { + if (jf->is_fd && + (!proc_subst_only || + fdtable[jf->u.fd] == FDT_PROC_SUBST)) { LinkNode next = nextnode(node); zclose(jf->u.fd); (void)remnode(filelist, node); @@ -1433,7 +1435,7 @@ zwaitjob(int job, int wait_cmd) * we can't deadlock on the fact that those still exist, so * that's not a problem. */ - pipecleanfilelist(jn->filelist); + pipecleanfilelist(jn->filelist, 0); } while (!errflag && jn->stat && !(jn->stat & STAT_DONE) && @@ -1623,7 +1625,7 @@ spawnjob(void) deletejob(jobtab + thisjob, 0); else { jobtab[thisjob].stat |= STAT_LOCKED; - pipecleanfilelist(jobtab[thisjob].filelist); + pipecleanfilelist(jobtab[thisjob].filelist, 0); } thisjob = -1; } diff --git a/Test/D03procsubst.ztst b/Test/D03procsubst.ztst index 7b8758901..9ab67c2b4 100644 --- a/Test/D03procsubst.ztst +++ b/Test/D03procsubst.ztst @@ -126,3 +126,18 @@ eval 'foo here is some output)' 0:full alias expanded when substitution starts in alias >here is some output + + if ! (mkfifo test_pipe >/dev/null 2>&1); then + ZTST_skip="mkfifo not available" + else + echo 1 | tee >(cat > test_pipe) | (){ + local pipein + read pipein <test_pipe + print $pipein + read pipein + print $pipein + } + fi +0:proc subst fd in forked subshell closed in parent +>1 +>1 |