Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/sh Finish the fd reassignment fixes from 1.43 and 1.45 ....



details:   https://anonhg.NetBSD.org/src/rev/1e8e65d80ff1
branches:  trunk
changeset: 345137:1e8e65d80ff1
user:      kre <kre%NetBSD.org@localhost>
date:      Mon May 09 20:50:08 2016 +0000

description:
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@

diffstat:

 bin/sh/eval.c  |  39 +++++++++++++++++++--------------------
 bin/sh/eval.h  |   8 +++++++-
 bin/sh/main.c  |   6 +++---
 bin/sh/redir.c |  16 +++++++++++-----
 4 files changed, 40 insertions(+), 29 deletions(-)

diffs (241 lines):

diff -r 588c28a1f5ef -r 1e8e65d80ff1 bin/sh/eval.c
--- a/bin/sh/eval.c     Mon May 09 20:36:07 2016 +0000
+++ b/bin/sh/eval.c     Mon May 09 20:50:08 2016 +0000
@@ -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 @@
 #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 @@
        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 @@
 #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 @@
                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 @@
                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 @@
        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 @@
                        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 @@
        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 @@
                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 @@
 #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 @@
                freeparam(&shellparam);
                shellparam = saveparam;
                handler = savehandler;
-               popredir();
+               if (flags & EV_MORE)
+                       popredir();
                INTON;
                if (evalskip == SKIPFUNC) {
                        evalskip = SKIPNONE;
diff -r 588c28a1f5ef -r 1e8e65d80ff1 bin/sh/eval.h
--- a/bin/sh/eval.h     Mon May 09 20:36:07 2016 +0000
+++ b/bin/sh/eval.h     Mon May 09 20:50:08 2016 +0000
@@ -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 @@
  * 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 */
diff -r 588c28a1f5ef -r 1e8e65d80ff1 bin/sh/main.c
--- a/bin/sh/main.c     Mon May 09 20:36:07 2016 +0000
+++ b/bin/sh/main.c     Mon May 09 20:50:08 2016 +0000
@@ -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 @@
 #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 @@
                } 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);
diff -r 588c28a1f5ef -r 1e8e65d80ff1 bin/sh/redir.c
--- a/bin/sh/redir.c    Mon May 09 20:36:07 2016 +0000
+++ b/bin/sh/redir.c    Mon May 09 20:50:08 2016 +0000
@@ -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 @@
                            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 @@
        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 @@
                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;
 }



Home | Main Index | Thread Index | Old Index