Module Name:    src
Committed By:   kre
Date:           Mon May  9 20:50:08 UTC 2016

Modified Files:
        src/bin/sh: eval.c eval.h main.c redir.c

Log Message:
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@


To generate a diff of this commit:
cvs rdiff -u -r1.122 -r1.123 src/bin/sh/eval.c
cvs rdiff -u -r1.16 -r1.17 src/bin/sh/eval.h
cvs rdiff -u -r1.64 -r1.65 src/bin/sh/main.c
cvs rdiff -u -r1.45 -r1.46 src/bin/sh/redir.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/bin/sh/eval.c
diff -u src/bin/sh/eval.c:1.122 src/bin/sh/eval.c:1.123
--- src/bin/sh/eval.c:1.122	Tue May  3 13:47:58 2016
+++ src/bin/sh/eval.c	Mon May  9 20:50:08 2016
@@ -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
 #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 && 
 			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, s
 		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;

Index: src/bin/sh/eval.h
diff -u src/bin/sh/eval.h:1.16 src/bin/sh/eval.h:1.17
--- src/bin/sh/eval.h:1.16	Sat May 31 14:42:18 2014
+++ src/bin/sh/eval.h	Mon May  9 20:50:08 2016
@@ -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 inter
  * 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 */

Index: src/bin/sh/main.c
diff -u src/bin/sh/main.c:1.64 src/bin/sh/main.c:1.65
--- src/bin/sh/main.c:1.64	Thu Mar 31 16:16:35 2016
+++ src/bin/sh/main.c	Mon May  9 20:50:08 2016
@@ -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, 19
 #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);

Index: src/bin/sh/redir.c
diff -u src/bin/sh/redir.c:1.45 src/bin/sh/redir.c:1.46
--- src/bin/sh/redir.c:1.45	Sun May  8 20:14:27 2016
+++ src/bin/sh/redir.c	Mon May  9 20:50:08 2016
@@ -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 mem
 			    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;
 }

Reply via email to