mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-11-01 18:30:55 +01:00
35849: close fd's from process substitution after fork
Leaving these hanging in parent could cause deadlock: test added.
This commit is contained in:
parent
49ff2e00dc
commit
28a962f557
4 changed files with 28 additions and 6 deletions
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
|
|
|||
10
Src/jobs.c
10
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue