Source-Changes-HG archive

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

[src/trunk]: src/bin/sh Fix handing of user file descriptors outside the 0..9...



details:   https://anonhg.NetBSD.org/src/rev/1ac26f64799a
branches:  trunk
changeset: 344999:1ac26f64799a
user:      christos <christos%NetBSD.org@localhost>
date:      Mon May 02 01:46:31 2016 +0000

description:
Fix handing of user file descriptors outside the 0..9 range.
Also, move (most of) the shell's internal use fd's to much
higher values (depending upon what ulimit -n allows) so they
are less likely to clash with user supplied fd numbers.  A future
patch will (hopefully) avoid this problem completely by dynamically
moving the shell's internal fds around as needed. (From kre@)

diffstat:

 bin/sh/cd.c     |   10 +--
 bin/sh/eval.c   |   30 ++------
 bin/sh/input.c  |   17 ++--
 bin/sh/jobs.c   |   14 +---
 bin/sh/parser.c |    5 +-
 bin/sh/redir.c  |  195 +++++++++++++++++++++++++++++++++++++++++++++----------
 bin/sh/redir.h  |    5 +-
 7 files changed, 185 insertions(+), 91 deletions(-)

diffs (truncated from 517 to 300 lines):

diff -r 185b63747869 -r 1ac26f64799a bin/sh/cd.c
--- a/bin/sh/cd.c       Mon May 02 01:05:34 2016 +0000
+++ b/bin/sh/cd.c       Mon May 02 01:46:31 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cd.c,v 1.45 2016/01/04 03:00:24 christos Exp $ */
+/*     $NetBSD: cd.c,v 1.46 2016/05/02 01:46:31 christos Exp $ */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)cd.c       8.2 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: cd.c,v 1.45 2016/01/04 03:00:24 christos Exp $");
+__RCSID("$NetBSD: cd.c,v 1.46 2016/05/02 01:46:31 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -427,11 +427,7 @@
                jp = makejob(NULL, 1);
                if (forkshell(jp, NULL, FORK_NOJOB) == 0) {
                        (void) close(pip[0]);
-                       if (pip[1] != 1) {
-                               close(1);
-                               copyfd(pip[1], 1, 1, 0);
-                               close(pip[1]);
-                       }
+                       movefd(pip[1], 1);
                        (void) execl("/bin/pwd", "pwd", (char *)0);
                        error("Cannot exec /bin/pwd");
                }
diff -r 185b63747869 -r 1ac26f64799a bin/sh/eval.c
--- a/bin/sh/eval.c     Mon May 02 01:05:34 2016 +0000
+++ b/bin/sh/eval.c     Mon May 02 01:46:31 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: eval.c,v 1.119 2016/03/16 21:20:59 christos Exp $      */
+/*     $NetBSD: eval.c,v 1.120 2016/05/02 01:46:31 christos 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.119 2016/03/16 21:20:59 christos Exp $");
+__RCSID("$NetBSD: eval.c,v 1.120 2016/05/02 01:46:31 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -508,6 +508,7 @@
 
        for (redir = n ; redir ; redir = redir->nfile.next) {
                struct arglist fn;
+
                fn.lastp = &fn.list;
                switch (redir->type) {
                case NFROMTO:
@@ -566,18 +567,11 @@
                }
                if (forkshell(jp, lp->n, n->npipe.backgnd ? FORK_BG : FORK_FG) == 0) {
                        INTON;
-                       if (prevfd > 0) {
-                               close(0);
-                               copyfd(prevfd, 0, 1, 0);
-                               close(prevfd);
-                       }
+                       if (prevfd > 0)
+                               movefd(prevfd, 0);
                        if (pip[1] >= 0) {
                                close(pip[0]);
-                               if (pip[1] != 1) {
-                                       close(1);
-                                       copyfd(pip[1], 1, 1, 0);
-                                       close(pip[1]);
-                               }
+                               movefd(pip[1], 1);
                        }
                        evaltree(lp->n, EV_EXIT);
                }
@@ -638,11 +632,7 @@
                if (forkshell(jp, n, FORK_NOJOB) == 0) {
                        FORCEINTON;
                        close(pip[0]);
-                       if (pip[1] != 1) {
-                               close(1);
-                               copyfd(pip[1], 1, 1, 0);
-                               close(pip[1]);
-                       }
+                       movefd(pip[1], 1);
                        eflag = 0;
                        evaltree(n, EV_EXIT);
                        /* NOTREACHED */
@@ -970,11 +960,7 @@
                                FORCEINTON;
                        }
                        close(pip[0]);
-                       if (pip[1] != 1) {
-                               close(1);
-                               copyfd(pip[1], 1, 1, 0);
-                               close(pip[1]);
-                       }
+                       movefd(pip[1], 1);
                }
                flags |= EV_EXIT;
        }
diff -r 185b63747869 -r 1ac26f64799a bin/sh/input.c
--- a/bin/sh/input.c    Mon May 02 01:05:34 2016 +0000
+++ b/bin/sh/input.c    Mon May 02 01:46:31 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: input.c,v 1.48 2016/03/27 14:34:46 christos Exp $      */
+/*     $NetBSD: input.c,v 1.49 2016/05/02 01:46:31 christos Exp $      */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)input.c    8.3 (Berkeley) 6/9/95";
 #else
-__RCSID("$NetBSD: input.c,v 1.48 2016/03/27 14:34:46 christos Exp $");
+__RCSID("$NetBSD: input.c,v 1.49 2016/05/02 01:46:31 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -411,14 +411,13 @@
                        error("Cannot rewind the file %s", fname);
        }
 
-       if (fd < 10) {
-               fd2 = copyfd(fd, 10, 0, 0);
-               close(fd);
-               if (fd2 < 0)
-                       error("Out of file descriptors");
-               fd = fd2;
+       fd2 = to_upper_fd(fd);  /* closes fd, returns higher equiv */
+       if (fd2 == fd) {
+               (void) close(fd);
+               error("Out of file descriptors");
        }
-       setinputfd(fd, push);
+
+       setinputfd(fd2, push);
        INTON;
 }
 
diff -r 185b63747869 -r 1ac26f64799a bin/sh/jobs.c
--- a/bin/sh/jobs.c     Mon May 02 01:05:34 2016 +0000
+++ b/bin/sh/jobs.c     Mon May 02 01:46:31 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: jobs.c,v 1.75 2015/08/22 12:12:47 christos Exp $       */
+/*     $NetBSD: jobs.c,v 1.76 2016/05/02 01:46:31 christos Exp $       */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)jobs.c     8.5 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: jobs.c,v 1.75 2015/08/22 12:12:47 christos Exp $");
+__RCSID("$NetBSD: jobs.c,v 1.76 2016/05/02 01:46:31 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -161,15 +161,7 @@
                        if (i == 3)
                                goto out;
                }
-               /* Move to a high fd */
-               for (i = 10; i > 2; i--) {
-                       if ((err = fcntl(ttyfd, F_DUPFD, (1 << i) - 1)) != -1)
-                               break;
-               }
-               if (err != -1) {
-                       close(ttyfd);
-                       ttyfd = err;
-               }
+               ttyfd = to_upper_fd(ttyfd);     /* Move to a high fd */
 #ifdef FIOCLEX
                err = ioctl(ttyfd, FIOCLEX, 0);
 #elif FD_CLOEXEC
diff -r 185b63747869 -r 1ac26f64799a bin/sh/parser.c
--- a/bin/sh/parser.c   Mon May 02 01:05:34 2016 +0000
+++ b/bin/sh/parser.c   Mon May 02 01:46:31 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: parser.c,v 1.116 2016/04/04 12:39:08 christos Exp $    */
+/*     $NetBSD: parser.c,v 1.117 2016/05/02 01:46:31 christos Exp $    */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)parser.c   8.7 (Berkeley) 5/16/95";
 #else
-__RCSID("$NetBSD: parser.c,v 1.116 2016/04/04 12:39:08 christos Exp $");
+__RCSID("$NetBSD: parser.c,v 1.117 2016/05/02 01:46:31 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -50,7 +50,6 @@
 #include "nodes.h"
 #include "expand.h"    /* defines rmescapes() */
 #include "eval.h"      /* defines commandname */
-#include "redir.h"     /* defines copyfd() */
 #include "syntax.h"
 #include "options.h"
 #include "input.h"
diff -r 185b63747869 -r 1ac26f64799a bin/sh/redir.c
--- a/bin/sh/redir.c    Mon May 02 01:05:34 2016 +0000
+++ b/bin/sh/redir.c    Mon May 02 01:46:31 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: redir.c,v 1.42 2016/03/13 01:22:42 christos Exp $      */
+/*     $NetBSD: redir.c,v 1.43 2016/05/02 01:46:31 christos 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.42 2016/03/13 01:22:42 christos Exp $");
+__RCSID("$NetBSD: redir.c,v 1.43 2016/05/02 01:46:31 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -76,9 +76,16 @@
 
 
 MKINIT
+struct renamelist {
+       struct renamelist *next;
+       int orig;
+       int into;
+};
+
+MKINIT
 struct redirtab {
        struct redirtab *next;
-       short renamed[10];
+       struct renamelist *renamed;
 };
 
 
@@ -88,12 +95,64 @@
  * We keep track of whether or not fd0 has been redirected.  This is for
  * background commands, where we want to redirect fd0 to /dev/null only
  * if it hasn't already been redirected.
-*/
-int fd0_redirected = 0;
+ */
+STATIC int fd0_redirected = 0;
 
+/*
+ * And also where to put internal use fds that should be out of the
+ * way of user defined fds (normally)
+ */
+STATIC int big_sh_fd = 0;
+
+STATIC const struct renamelist *is_renamed(const struct renamelist *, int);
+STATIC void fd_rename(struct redirtab *, int, int);
+STATIC void free_rl(struct redirtab *, int);
 STATIC void openredirect(union node *, char[10], int);
 STATIC int openhere(const union node *);
+STATIC void find_big_fd(void);
 
+STATIC const struct renamelist *
+is_renamed(const struct renamelist *rl, int fd)
+{
+       while (rl != NULL) {
+               if (rl->orig == fd)
+                       return rl;
+               rl = rl->next;
+       }
+       return NULL;
+}
+
+STATIC void
+free_rl(struct redirtab *rt, int reset)
+{
+       struct renamelist *rl, *rn = rt->renamed;
+
+       while ((rl = rn) != NULL) {
+               rn = rl->next;
+               if (rl->orig == 0)
+                       fd0_redirected--;
+               if (reset) {
+                       if (rl->into < 0)
+                               close(rl->orig);
+                       else
+                               movefd(rl->into, rl->orig);
+               }
+               ckfree(rl);
+       }
+       rt->renamed = NULL;
+}
+
+STATIC void
+fd_rename(struct redirtab *rt, int from, int to)
+{
+       struct renamelist *rl = ckmalloc(sizeof(struct renamelist));
+
+       rl->next = rt->renamed;



Home | Main Index | Thread Index | Old Index