Source-Changes-HG archive

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

[src/trunk]: src/bin/sh More standard (and saner) implementation of the ! res...



details:   https://anonhg.NetBSD.org/src/rev/af95e849cdfe
branches:  trunk
changeset: 353893:af95e849cdfe
user:      kre <kre%NetBSD.org@localhost>
date:      Sat May 27 11:19:57 2017 +0000

description:
More standard (and saner) implementation of the ! reserved word.
Unless the shell is compiled with the (compilation time) option
BOGUS_NOT_COMMAND (as in CFLAGS+=-DBOGUS_NOT_COMMAND) which it
will not normally be, the ! command (reserved word) will only
be permitted at the start of a pipeline (which includes the
degenerate pipeline with no '|'s in it of course - ie: a simple cmd)
and not in the middle of a pipeline sequence (no "cmd | ! cmd" nonsense.)
If the latter is really required, then "cmd | { ! cmd; }" works as
a standard equivalent.

In POSIX mode, permit only one !  ("! pipeline" is ok. "! ! pipeline" is not).
Again, if needed (and POSIX conformance is wanted) "! { ! pipeline; }"
works as an alternative - and is safer, some shells treat "! ! cmd" as
being identical to "cmd" (this one did until recently.)

diffstat:

 bin/sh/parser.c |  26 ++++++++++++++++++++++----
 bin/sh/sh.1     |  15 ++++++++++-----
 bin/sh/shell.h  |   4 +++-
 bin/sh/var.c    |   7 +++++--
 4 files changed, 40 insertions(+), 12 deletions(-)

diffs (192 lines):

diff -r f0ba0e9ece4a -r af95e849cdfe bin/sh/parser.c
--- a/bin/sh/parser.c   Sat May 27 11:10:24 2017 +0000
+++ b/bin/sh/parser.c   Sat May 27 11:19:57 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: parser.c,v 1.128 2017/05/14 11:17:04 kre Exp $ */
+/*     $NetBSD: parser.c,v 1.129 2017/05/27 11:19:57 kre 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.128 2017/05/14 11:17:04 kre Exp $");
+__RCSID("$NetBSD: parser.c,v 1.129 2017/05/27 11:19:57 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -264,6 +264,10 @@
        checkkwd = 2;
        while (readtoken() == TNOT) {
                TRACE(("pipeline: TNOT recognized\n"));
+#ifndef BOGUS_NOT_COMMAND
+               if (posix && negate)
+                       synerror("2nd \"!\" unexpected");
+#endif
                negate++;
        }
        tokpushback++;
@@ -304,7 +308,10 @@
        union node *ap, **app;
        union node *cp, **cpp;
        union node *redir, **rpp;
-       int t, negate = 0;
+       int t;
+#ifdef BOGUS_NOT_COMMAND
+       int negate = 0;
+#endif
 
        TRACE(("command: entered\n"));
 
@@ -321,11 +328,13 @@
        }
        tokpushback++;
 
+#ifdef BOGUS_NOT_COMMAND               /* only in pileline() */
        while (readtoken() == TNOT) {
                TRACE(("command: TNOT recognized\n"));
                negate++;
        }
        tokpushback++;
+#endif
 
        switch (readtoken()) {
        case TIF:
@@ -568,6 +577,7 @@
        }
 
  checkneg:
+#ifdef BOGUS_NOT_COMMAND
        if (negate) {
                TRACE(("%snegate command\n", (negate&1) ? "" : "double "));
                n2 = stalloc(sizeof(struct nnot));
@@ -576,6 +586,7 @@
                return n2;
        }
        else
+#endif
                return n1;
 }
 
@@ -584,8 +595,11 @@
 simplecmd(union node **rpp, union node *redir)
 {
        union node *args, **app;
-       union node *n = NULL, *n2;
+       union node *n = NULL;
+#ifdef BOGUS_NOT_COMMAND
+       union node *n2;
        int negate = 0;
+#endif
 
        /* If we don't have any redirections already, then we must reset */
        /* rpp to be the address of the local redir variable.  */
@@ -595,11 +609,13 @@
        args = NULL;
        app = &args;
 
+#ifdef BOGUS_NOT_COMMAND       /* pipelines get negated, commands do not */
        while (readtoken() == TNOT) {
                TRACE(("simplcmd: TNOT recognized\n"));
                negate++;
        }
        tokpushback++;
+#endif
 
        for (;;) {
                if (readtoken() == TWORD) {
@@ -643,6 +659,7 @@
        n->ncmd.redirect = redir;
 
  checkneg:
+#ifdef BOGUS_NOT_COMMAND
        if (negate) {
                TRACE(("%snegate simplecmd\n", (negate&1) ? "" : "double "));
                n2 = stalloc(sizeof(struct nnot));
@@ -651,6 +668,7 @@
                return n2;
        }
        else
+#endif
                return n;
 }
 
diff -r f0ba0e9ece4a -r af95e849cdfe bin/sh/sh.1
--- a/bin/sh/sh.1       Sat May 27 11:10:24 2017 +0000
+++ b/bin/sh/sh.1       Sat May 27 11:19:57 2017 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: sh.1,v 1.144 2017/05/27 06:32:12 kre Exp $
+.\"    $NetBSD: sh.1,v 1.145 2017/05/27 11:19:57 kre Exp $
 .\" Copyright (c) 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
 .\"
@@ -385,13 +385,18 @@
 It also controls whether file descriptors greater than 2
 opened using the
 .Ic exec
-built-in command are passed on to utilities executed,
+built-in command are passed on to utilities executed
+.Dq ( yes
+in posix mode),
 and whether the shell treats
-an empty compound statement as a syntax error (required
-by posix) or permits it.
-Empty compound statements
+an empty brace-list compound statement as a syntax error
+(required by posix) or permits it.
+Such statements
 .Dq "{ }"
 can be useful when defining dummy functions.
+Lastly, in posix mode, only one
+.Dq \&!
+is permitted before a pipeline.
 .It "\ \ " Em tabcomplete
 Enables filename completion in the command line editor.
 Typing a tab character will extend the current input word to match a
diff -r f0ba0e9ece4a -r af95e849cdfe bin/sh/shell.h
--- a/bin/sh/shell.h    Sat May 27 11:10:24 2017 +0000
+++ b/bin/sh/shell.h    Sat May 27 11:19:57 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: shell.h,v 1.21 2017/05/13 03:26:03 kre Exp $   */
+/*     $NetBSD: shell.h,v 1.22 2017/05/27 11:19:57 kre Exp $   */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -43,6 +43,8 @@
  *     define DEBUG=2 to compile in and turn on debugging.
  *     define DO_SHAREDVFORK to indicate that vfork(2) shares its address
  *            with its parent.
+ *     define BOGUS_NOT_COMMAND to allow ! reserved words in weird places
+ *             (traditional ash behaviour.)
  *
  * When debugging is on, debugging info will be written to ./trace and
  * a quit signal will generate a core dump.
diff -r f0ba0e9ece4a -r af95e849cdfe bin/sh/var.c
--- a/bin/sh/var.c      Sat May 27 11:10:24 2017 +0000
+++ b/bin/sh/var.c      Sat May 27 11:19:57 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: var.c,v 1.54 2017/05/27 06:32:12 kre Exp $     */
+/*     $NetBSD: var.c,v 1.55 2017/05/27 11:19:57 kre Exp $     */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)var.c      8.3 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: var.c,v 1.54 2017/05/27 06:32:12 kre Exp $");
+__RCSID("$NetBSD: var.c,v 1.55 2017/05/27 11:19:57 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -200,6 +200,9 @@
 #ifndef BSD
                " -BSD"
 #endif
+#ifdef BOGUS_NOT_COMMAND
+               " BOGUS_NOT"
+#endif
                    , VTEXTFIXED|VREADONLY|VNOEXPORT);
 }
 #endif



Home | Main Index | Thread Index | Old Index