1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-02 10:01:11 +02:00

Merge of 21049: Don't close process substitution file descriptors for external programmes

This commit is contained in:
Paul Ackersviller 2007-04-23 04:20:22 +00:00
parent f355b42e16
commit eaf13e9eab
4 changed files with 64 additions and 27 deletions

View file

@ -77,7 +77,7 @@ long lastval2;
* by zclose. */
/**/
char *fdtable;
unsigned char *fdtable;
/* The allocated size of fdtable */
@ -498,7 +498,11 @@ execute(UNUSED(Cmdnam cmdname), int dash, int defpath)
}
argv = makecline(args);
closem(3);
/*
* Note that we don't close fd's attached to process substitution
* here, which should be visible to external processes.
*/
closem(FDT_XTRACE);
child_unblock();
if ((int) strlen(arg0) >= PATH_MAX) {
zerr("command too long: %s", arg0, 0);
@ -1055,7 +1059,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
mpipe(opipe);
coprocin = ipipe[0];
coprocout = opipe[1];
fdtable[coprocin] = fdtable[coprocout] = 0;
fdtable[coprocin] = fdtable[coprocout] = FDT_UNUSED;
}
/* This used to set list_pipe_pid=0 unconditionally, but in things
* like `ls|if true; then sleep 20; cat; fi' where the sleep was
@ -1578,7 +1582,7 @@ addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag)
mfds[fd1]->fds[mfds[fd1]->ct++] = movefd(fd2);
}
}
if (subsh_close >= 0 && !fdtable[subsh_close])
if (subsh_close >= 0 && fdtable[subsh_close] == FDT_UNUSED)
subsh_close = -1;
}
@ -2140,7 +2144,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
read(synch[0], &dummy, 1);
close(synch[0]);
#ifdef PATH_DEV_FD
closem(2);
closem(FDT_PROC_SUBST);
#endif
if (how & Z_ASYNC) {
lastpid = (zlong) pid;
@ -2205,7 +2209,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
if (!(xtrerr = fdopen(movefd(dup(fileno(stderr))), "w")))
xtrerr = stderr;
else
fdtable[fileno(xtrerr)] = 3;
fdtable[fileno(xtrerr)] = FDT_XTRACE;
}
/* Add pipeline input/output to mnodes */
@ -2295,7 +2299,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
if (fn->fd2 < 10)
closemn(mfds, fn->fd2);
if (fn->fd2 > 9 &&
(fdtable[fn->fd2] ||
(fdtable[fn->fd2] != FDT_UNUSED ||
fn->fd2 == coprocin ||
fn->fd2 == coprocout)) {
fil = -1;
@ -2423,7 +2427,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
int i;
for (i = 10; i <= max_zsh_fd; i++)
if (fdtable[i] > 1)
if (fdtable[i] >= FDT_PROC_SUBST)
fdtable[i]++;
#endif
if (subsh_close >= 0)
@ -2433,17 +2437,17 @@ execcmd(Estate state, int input, int output, int how, int last1)
execshfunc((Shfunc) hn, args);
#ifdef PATH_DEV_FD
for (i = 10; i <= max_zsh_fd; i++)
if (fdtable[i] > 1)
if (--(fdtable[i]) <= 2)
if (fdtable[i] >= FDT_PROC_SUBST)
if (--(fdtable[i]) <= FDT_PROC_SUBST)
zclose(i);
#endif
} else {
/* It's a builtin */
if (forked)
closem(1);
closem(FDT_INTERNAL);
lastval = execbuiltin(args, (Builtin) hn);
#ifdef PATH_DEV_FD
closem(2);
closem(FDT_PROC_SUBST);
#endif
fflush(stdout);
if (save[1] == -2) {
@ -2487,7 +2491,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
if (errflag)
_exit(1);
}
closem(1);
closem(FDT_INTERNAL);
if (coprocin)
zclose(coprocin);
if (coprocout)
@ -2721,7 +2725,12 @@ entersubsh(int how, int cl, int fake, int revertpgrp)
forklevel = locallevel;
}
/* close internal shell fds */
/*
* Close internal shell fds.
*
* Close any that are marked as used if "how" is FDT_UNUSED, else
* close any with the value "how".
*/
/**/
mod_export void
@ -2730,7 +2739,8 @@ closem(int how)
int i;
for (i = 10; i <= max_zsh_fd; i++)
if (fdtable[i] && (!how || fdtable[i] == how))
if (fdtable[i] != FDT_UNUSED &&
(how == FDT_UNUSED || fdtable[i] == how))
zclose(i);
}
@ -2875,7 +2885,7 @@ getoutput(char *cmd, int qt)
zclose(pipes[1]);
retval = readoutput(pipes[0], qt);
fdtable[pipes[0]] = 0;
fdtable[pipes[0]] = FDT_UNUSED;
waitforpid(pid); /* unblocks */
lastval = cmdoutval;
return retval;
@ -3079,7 +3089,7 @@ getproc(char *cmd)
addproc(pid, NULL, 1, &bgtime);
return pnam;
}
closem(0);
closem(FDT_UNUSED);
fd = open(pnam, out ? O_WRONLY | O_NOCTTY : O_RDONLY | O_NOCTTY);
if (fd == -1) {
zerr("can't open %s: %e", pnam, errno);
@ -3104,7 +3114,7 @@ getproc(char *cmd)
zclose(pipes[!out]);
return NULL;
}
fdtable[pipes[!out]] = 2;
fdtable[pipes[!out]] = FDT_PROC_SUBST;
if (!out)
{
addproc(pid, NULL, 1, &bgtime);
@ -3113,7 +3123,7 @@ getproc(char *cmd)
}
entersubsh(Z_ASYNC, 1, 0, 0);
redup(pipes[out], out);
closem(0); /* this closes pipes[!out] as well */
closem(FDT_UNUSED); /* this closes pipes[!out] as well */
#endif /* PATH_DEV_FD */
cmdpush(CS_CMDSUBST);
@ -3157,7 +3167,7 @@ getpipe(char *cmd, int nullexec)
}
entersubsh(Z_ASYNC, 1, 0, 0);
redup(pipes[out], out);
closem(0); /* this closes pipes[!out] as well */
closem(FDT_UNUSED); /* this closes pipes[!out] as well */
cmdpush(CS_CMDSUBST);
execode(prog, 0, 1);
cmdpop();

View file

@ -1050,7 +1050,7 @@ source(char *s)
freeeprog(prog);
else {
fclose(bshin);
fdtable[SHIN] = 0;
fdtable[SHIN] = FDT_UNUSED;
SHIN = fd; /* the shell input fd */
bshin = obshin; /* file handle for buffered shell input */
}
@ -1250,7 +1250,7 @@ zsh_main(UNUSED(int argc), char **argv)
} while (zsh_name);
fdtable_size = zopenmax();
fdtable = zshcalloc(fdtable_size);
fdtable = zshcalloc(fdtable_size*sizeof(*fdtable));
createoptiontable();
emulate(zsh_name, 1); /* initialises most options */

View file

@ -1078,10 +1078,11 @@ movefd(int fd)
if(fd != -1) {
if (fd > max_zsh_fd) {
while (fd >= fdtable_size)
fdtable = zrealloc(fdtable, (fdtable_size *= 2));
fdtable = zrealloc(fdtable,
(fdtable_size *= 2)*sizeof(*fdtable));
max_zsh_fd = fd;
}
fdtable[fd] = 1;
fdtable[fd] = FDT_INTERNAL;
}
return fd;
}
@ -1096,7 +1097,7 @@ redup(int x, int y)
zclose(y);
else if (x != y) {
while (y >= fdtable_size)
fdtable = zrealloc(fdtable, (fdtable_size *= 2));
fdtable = zrealloc(fdtable, (fdtable_size *= 2)*sizeof(*fdtable));
dup2(x, y);
if ((fdtable[y] = fdtable[x]) && y > max_zsh_fd)
max_zsh_fd = y;
@ -1111,8 +1112,8 @@ mod_export int
zclose(int fd)
{
if (fd >= 0) {
fdtable[fd] = 0;
while (max_zsh_fd > 0 && !fdtable[max_zsh_fd])
fdtable[fd] = FDT_UNUSED;
while (max_zsh_fd > 0 && fdtable[max_zsh_fd] == FDT_UNUSED)
max_zsh_fd--;
if (fd == coprocin)
coprocin = -1;

View file

@ -262,6 +262,32 @@ enum {
#define IS_READFD(X) (((X)>=REDIR_READWRITE && (X)<=REDIR_MERGEIN) || (X)==REDIR_INPIPE)
#define IS_REDIROP(X) ((X)>=OUTANG && (X)<=TRINANG)
/*
* Values for the fdtable array. They say under what circumstances
* the fd will be close. The fdtable is an unsigned char, so these are
* #define's rather than an enum.
*/
/* Entry not used. */
#define FDT_UNUSED 0
/*
* Entry used internally by the shell, should not be visible to other
* processes.
*/
#define FDT_INTERNAL 1
/*
* Entry used by output from the XTRACE option.
*/
#define FDT_XTRACE 2
#ifdef PATH_DEV_FD
/*
* Entry used by a process substition.
* The value will be incremented on entering a function and
* decremented on exit; we don't close entries greater than
* FDT_PROC_SUBST except when closing everything.
*/
#define FDT_PROC_SUBST 3
#endif
/* Flags for input stack */
#define INP_FREE (1<<0) /* current buffer can be free'd */
#define INP_ALIAS (1<<1) /* expanding alias or history */