Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: [BUG] process substitution breaks when nested or traverses a function
- X-seq: zsh-workers 42708
- From: Peter Stephenson <p.stephenson@xxxxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: Re: [BUG] process substitution breaks when nested or traverses a function
- Date: Tue, 24 Apr 2018 10:43:35 +0100
- Cms-type: 201P
- Dkim-filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20180424094339euoutp02ca971ee9cd6c1fbe789c8e7b8a36510c~oVf0tmPkO2133421334euoutp02L
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1524563019; bh=bCbX/e9krx2S+FxmT2/nHvqRhOgfSswZXTpSvp4hLzw=; h=Date:From:To:Subject:In-reply-to:References:From; b=ejBHlSFCYo1qr+Pg4KJjW5vE1sYn7LU6SIld7mUBLuNDZxv4IJ1HCMz0EGgTZ4o6D o6RMCG5OatrmelW9FwRtNAxOh3zZKxEySfwqthhK9izBzCi9C36c4XFG63/dHvUFWJ I3+AXQlwq4SrT4IJkO9SYaKZMba5KvAzOtD3n3Vs=
- In-reply-to: <CA++-COyOYiE_snQeLB_jsDmWAvne9bjS7GWnA28mPNwTeVo0kg@mail.gmail.com>
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- List-unsubscribe: <mailto:zsh-workers-unsubscribe@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- Organization: SCSC
- References: <CGME20180421093602epcas1p4c7f4182661b42fa2e477f8fe61a3e132@epcas1p4.samsung.com> <CA++-COyOYiE_snQeLB_jsDmWAvne9bjS7GWnA28mPNwTeVo0kg@mail.gmail.com>
On Sat, 21 Apr 2018 06:35:23 -0300
Francisco de Zuviría Allende <franciscodezuviria@xxxxxxxxx> wrote:
> #!/bin/zsh
> foo() { cat <(cat "$@"); }; foo <(echo bar);
> cat: /proc/self/fd/11: No such file or directory
Files and file descriptors for process substitution are handled
specially, so shouldn't be tidied up by closem(), which is called on the
inner process substitution (that's why both were required for this to
show up).
Is there a better way of doing this; or is this patch overkill, or not
careful enough...? If we don't have /proc/self, tidying up is done only
with the job filelist, so there wouldn't be a problem. But the get out
"all" argument looks like a reasonable safety compromise.
pws
diff --git a/Src/Modules/clone.c b/Src/Modules/clone.c
index 9304292..ef6275d 100644
--- a/Src/Modules/clone.c
+++ b/Src/Modules/clone.c
@@ -69,7 +69,7 @@ bin_clone(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
dup2(ttyfd,2);
if (ttyfd > 2)
close(ttyfd);
- closem(0);
+ closem(FDT_UNUSED, 0);
close(coprocin);
close(coprocout);
/* Acquire a controlling terminal */
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index 1c93a1d..2f83f7c 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -400,7 +400,7 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
dup2(slave, 1);
dup2(slave, 2);
- closem(0);
+ closem(FDT_UNUSED, 0);
close(slave);
close(master);
close(coprocin);
diff --git a/Src/exec.c b/Src/exec.c
index e853aff..65139de 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -698,7 +698,7 @@ execute(LinkList args, int flags, int defpath)
* Note that we don't close fd's attached to process substitution
* here, which should be visible to external processes.
*/
- closem(FDT_XTRACE);
+ closem(FDT_XTRACE, 0);
#ifndef FD_CLOEXEC
if (SHTTY != -1) {
close(SHTTY);
@@ -3924,7 +3924,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
LinkList assigns = (LinkList)0;
int postassigns = eparams->postassigns;
if (forked)
- closem(FDT_INTERNAL);
+ closem(FDT_INTERNAL, 0);
if (postassigns) {
Wordcode opc = state->pc;
state->pc = eparams->assignspc;
@@ -4110,7 +4110,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
if (errflag)
_exit(1);
}
- closem(FDT_INTERNAL);
+ closem(FDT_INTERNAL, 0);
if (coprocin != -1) {
zclose(coprocin);
coprocin = -1;
@@ -4172,7 +4172,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
for (i = 0; i < 10; i++)
if (fdtable[i] != FDT_UNUSED)
close(i);
- closem(FDT_UNUSED);
+ closem(FDT_UNUSED, 1);
if (thisjob != -1)
waitjobs();
_exit(lastval);
@@ -4352,12 +4352,17 @@ fixfds(int *save)
/**/
mod_export void
-closem(int how)
+closem(int how, int all)
{
int i;
for (i = 10; i <= max_zsh_fd; i++)
if (fdtable[i] != FDT_UNUSED &&
+ /*
+ * Process substitution needs to be visible to user;
+ * fd's are explicitly cleaned up by filelist handling.
+ */
+ (all || fdtable[i] != FDT_PROC_SUBST) &&
(how == FDT_UNUSED || (fdtable[i] & FDT_TYPE_MASK) == how)) {
if (i == SHTTY)
SHTTY = -1;
@@ -4840,7 +4845,7 @@ getproc(char *cmd, char **eptr)
addproc(pid, NULL, 1, &bgtime);
return pnam;
}
- closem(FDT_UNUSED);
+ closem(FDT_UNUSED, 0);
fd = open(pnam, out ? O_WRONLY | O_NOCTTY : O_RDONLY | O_NOCTTY);
if (fd == -1) {
zerr("can't open %s: %e", pnam, errno);
@@ -4879,7 +4884,7 @@ getproc(char *cmd, char **eptr)
}
entersubsh(ESUB_ASYNC|ESUB_PGRP);
redup(pipes[out], out);
- closem(FDT_UNUSED); /* this closes pipes[!out] as well */
+ closem(FDT_UNUSED, 0); /* this closes pipes[!out] as well */
#endif /* PATH_DEV_FD */
cmdpush(CS_CMDSUBST);
@@ -4929,7 +4934,7 @@ getpipe(char *cmd, int nullexec)
}
entersubsh(ESUB_PGRP);
redup(pipes[out], out);
- closem(FDT_UNUSED); /* this closes pipes[!out] as well */
+ closem(FDT_UNUSED, 0); /* this closes pipes[!out] as well */
cmdpush(CS_CMDSUBST);
execode(prog, 0, 1, out ? "outsubst" : "insubst");
cmdpop();
diff --git a/Test/D03procsubst.ztst b/Test/D03procsubst.ztst
index ca8d56f..861aa9c 100644
--- a/Test/D03procsubst.ztst
+++ b/Test/D03procsubst.ztst
@@ -149,3 +149,10 @@
fi
0:proc subst fd in forked subshell closed in parent (external command)
>1 1
+
+ procfunc() {
+ cat <(cat "$@")
+ }
+ procfunc <(echo argument)
+0:With /proc/self file descriptors must not be tidied up too early
+>argument
Messages sorted by:
Reverse Date,
Date,
Thread,
Author