Finish the fd reassignment fixes from 1.43 and 1.45 ... if we are moving
a fd to an unspecified high fd number, we certainly do not want to hand that high fd off to other processes after an exec, so always set close-on-exec on the result (even if lack of fd's means no fd alteration happens.) This will (eventually) allow some other code that sets close-on-exec to be removed, but for now, doing it twice won't hurt. Also, in a N>&M type redirection, do not set close-on-exec if we don't want it. OK christos@
This commit is contained in:
parent
183536927f
commit
07ee700a7e
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: eval.c,v 1.122 2016/05/03 13:47:58 kre Exp $ */
|
||||
/* $NetBSD: eval.c,v 1.123 2016/05/09 20:50:08 kre Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993
|
||||
|
@ -37,7 +37,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: eval.c,v 1.122 2016/05/03 13:47:58 kre Exp $");
|
||||
__RCSID("$NetBSD: eval.c,v 1.123 2016/05/09 20:50:08 kre Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -86,11 +86,6 @@ __RCSID("$NetBSD: eval.c,v 1.122 2016/05/03 13:47:58 kre Exp $");
|
|||
#endif
|
||||
|
||||
|
||||
/* flags in argument to evaltree */
|
||||
#define EV_EXIT 01 /* exit after evaluating tree */
|
||||
#define EV_TESTED 02 /* exit status is checked; ignore -e flag */
|
||||
#define EV_BACKCMD 04 /* command executing within back quotes */
|
||||
|
||||
STATIC enum skipstate evalskip; /* != SKIPNONE if we are skipping commands */
|
||||
STATIC int skipcount; /* number of levels to skip */
|
||||
STATIC int loopnest; /* current loop nesting level */
|
||||
|
@ -224,7 +219,7 @@ evalstring(char *s, int flag)
|
|||
while ((n = parsecmd(0)) != NEOF) {
|
||||
TRACE(("evalstring: "); showtree(n));
|
||||
if (nflag == 0)
|
||||
evaltree(n, flag);
|
||||
evaltree(n, flag | EV_MORE);
|
||||
popstackmark(&smark);
|
||||
}
|
||||
popfile();
|
||||
|
@ -262,19 +257,20 @@ evaltree(union node *n, int flags)
|
|||
#endif
|
||||
switch (n->type) {
|
||||
case NSEMI:
|
||||
evaltree(n->nbinary.ch1, flags & EV_TESTED);
|
||||
evaltree(n->nbinary.ch1, (flags & EV_TESTED) |
|
||||
(n->nbinary.ch2 ? EV_MORE : 0));
|
||||
if (nflag || evalskip)
|
||||
goto out;
|
||||
evaltree(n->nbinary.ch2, flags);
|
||||
break;
|
||||
case NAND:
|
||||
evaltree(n->nbinary.ch1, EV_TESTED);
|
||||
evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE);
|
||||
if (nflag || evalskip || exitstatus != 0)
|
||||
goto out;
|
||||
evaltree(n->nbinary.ch2, flags);
|
||||
break;
|
||||
case NOR:
|
||||
evaltree(n->nbinary.ch1, EV_TESTED);
|
||||
evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE);
|
||||
if (nflag || evalskip || exitstatus == 0)
|
||||
goto out;
|
||||
evaltree(n->nbinary.ch2, flags);
|
||||
|
@ -286,14 +282,14 @@ evaltree(union node *n, int flags)
|
|||
popredir();
|
||||
break;
|
||||
case NSUBSHELL:
|
||||
evalsubshell(n, flags);
|
||||
evalsubshell(n, flags & ~EV_MORE);
|
||||
do_etest = !(flags & EV_TESTED);
|
||||
break;
|
||||
case NBACKGND:
|
||||
evalsubshell(n, flags);
|
||||
evalsubshell(n, flags & ~EV_MORE);
|
||||
break;
|
||||
case NIF: {
|
||||
evaltree(n->nif.test, EV_TESTED);
|
||||
evaltree(n->nif.test, EV_TESTED | EV_MORE);
|
||||
if (nflag || evalskip)
|
||||
goto out;
|
||||
if (exitstatus == 0)
|
||||
|
@ -319,7 +315,7 @@ evaltree(union node *n, int flags)
|
|||
exitstatus = 0;
|
||||
break;
|
||||
case NNOT:
|
||||
evaltree(n->nnot.com, EV_TESTED);
|
||||
evaltree(n->nnot.com, (flags & EV_MORE) | EV_TESTED);
|
||||
exitstatus = !exitstatus;
|
||||
break;
|
||||
case NPIPE:
|
||||
|
@ -365,7 +361,7 @@ evalloop(union node *n, int flags)
|
|||
TRACE(("evalloop done\n"));
|
||||
|
||||
for (;;) {
|
||||
evaltree(n->nbinary.ch1, EV_TESTED);
|
||||
evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE);
|
||||
if (nflag)
|
||||
break;
|
||||
if (evalskip) {
|
||||
|
@ -384,7 +380,7 @@ skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
|
|||
if (exitstatus == 0)
|
||||
break;
|
||||
}
|
||||
evaltree(n->nbinary.ch2, flags & EV_TESTED);
|
||||
evaltree(n->nbinary.ch2, flags & (EV_TESTED | EV_MORE));
|
||||
status = exitstatus;
|
||||
if (evalskip)
|
||||
goto skipping;
|
||||
|
@ -418,7 +414,7 @@ evalfor(union node *n, int flags)
|
|||
loopnest++;
|
||||
for (sp = arglist.list ; sp ; sp = sp->next) {
|
||||
setvar(n->nfor.var, sp->text, 0);
|
||||
evaltree(n->nfor.body, flags & EV_TESTED);
|
||||
evaltree(n->nfor.body, flags & (EV_TESTED | EV_MORE));
|
||||
status = exitstatus;
|
||||
if (nflag)
|
||||
break;
|
||||
|
@ -886,6 +882,8 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd)
|
|||
INTOFF;
|
||||
jp = makejob(cmd, 1);
|
||||
mode = cmd->ncmd.backgnd;
|
||||
if (mode)
|
||||
flags &= ~EV_MORE;
|
||||
if (flags & EV_BACKCMD) {
|
||||
mode = FORK_NOJOB;
|
||||
if (sh_pipe(pip) < 0)
|
||||
|
@ -972,7 +970,7 @@ normal_fork:
|
|||
#ifdef DEBUG
|
||||
trputs("Shell function: "); trargs(argv);
|
||||
#endif
|
||||
redirect(cmd->ncmd.redirect, REDIR_PUSH);
|
||||
redirect(cmd->ncmd.redirect, flags & EV_MORE ? REDIR_PUSH : 0);
|
||||
saveparam = shellparam;
|
||||
shellparam.malloc = 0;
|
||||
shellparam.reset = 1;
|
||||
|
@ -1010,7 +1008,8 @@ normal_fork:
|
|||
freeparam(&shellparam);
|
||||
shellparam = saveparam;
|
||||
handler = savehandler;
|
||||
popredir();
|
||||
if (flags & EV_MORE)
|
||||
popredir();
|
||||
INTON;
|
||||
if (evalskip == SKIPFUNC) {
|
||||
evalskip = SKIPNONE;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: eval.h,v 1.16 2014/05/31 14:42:18 christos Exp $ */
|
||||
/* $NetBSD: eval.h,v 1.17 2016/05/09 20:50:08 kre Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -71,3 +71,9 @@ void stop_skipping(void); /* reset internal skipping state to SKIPNONE */
|
|||
* Only for use by reset() in init.c!
|
||||
*/
|
||||
void reset_eval(void);
|
||||
|
||||
/* flags in argument to evaltree */
|
||||
#define EV_EXIT 0x01 /* exit after evaluating tree */
|
||||
#define EV_TESTED 0x02 /* exit status is checked; ignore -e flag */
|
||||
#define EV_BACKCMD 0x04 /* command executing within back quotes */
|
||||
#define EV_MORE 0x08 /* more commands in this sub-shell */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: main.c,v 1.64 2016/03/31 16:16:35 christos Exp $ */
|
||||
/* $NetBSD: main.c,v 1.65 2016/05/09 20:50:08 kre Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1991, 1993\
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)main.c 8.7 (Berkeley) 7/19/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: main.c,v 1.64 2016/03/31 16:16:35 christos Exp $");
|
||||
__RCSID("$NetBSD: main.c,v 1.65 2016/05/09 20:50:08 kre Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -282,7 +282,7 @@ cmdloop(int top)
|
|||
} else if (n != NULL && nflag == 0) {
|
||||
job_warning = (job_warning == 2) ? 1 : 0;
|
||||
numeof = 0;
|
||||
evaltree(n, 0);
|
||||
evaltree(n, EV_MORE);
|
||||
}
|
||||
popstackmark(&smark);
|
||||
setstackmark(&smark);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: redir.c,v 1.45 2016/05/08 20:14:27 kre Exp $ */
|
||||
/* $NetBSD: redir.c,v 1.46 2016/05/09 20:50:08 kre Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -37,7 +37,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: redir.c,v 1.45 2016/05/08 20:14:27 kre Exp $");
|
||||
__RCSID("$NetBSD: redir.c,v 1.46 2016/05/09 20:50:08 kre Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -302,8 +302,8 @@ openredirect(union node *redir, char memory[10], int flags)
|
|||
memory[redir->ndup.dupfd])
|
||||
memory[fd] = 1;
|
||||
else
|
||||
copyfd(redir->ndup.dupfd, fd, 1,
|
||||
(flags & REDIR_PUSH) != 0);
|
||||
copyfd(redir->ndup.dupfd, fd, 1, (flags &
|
||||
(REDIR_PUSH|REDIR_KEEP)) == REDIR_PUSH);
|
||||
} else
|
||||
close(fd);
|
||||
INTON;
|
||||
|
@ -514,7 +514,7 @@ to_upper_fd(int fd)
|
|||
if (big_sh_fd < 10)
|
||||
find_big_fd();
|
||||
do {
|
||||
i = fcntl(fd, F_DUPFD, big_sh_fd);
|
||||
i = fcntl(fd, F_DUPFD_CLOEXEC, big_sh_fd);
|
||||
if (i >= 0) {
|
||||
if (fd != i)
|
||||
close(fd);
|
||||
|
@ -525,5 +525,11 @@ to_upper_fd(int fd)
|
|||
find_big_fd();
|
||||
} while (big_sh_fd > 10);
|
||||
|
||||
/*
|
||||
* If we wamted to move this fd to some random high number
|
||||
* we certainly do not intend to pass it through exec, even
|
||||
* if the reassignment failed.
|
||||
*/
|
||||
(void)fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
return fd;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue