Module Name:    src
Committed By:   kre
Date:           Sat May 27 11:19:57 UTC 2017

Modified Files:
        src/bin/sh: parser.c sh.1 shell.h var.c

Log Message:
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.)


To generate a diff of this commit:
cvs rdiff -u -r1.128 -r1.129 src/bin/sh/parser.c
cvs rdiff -u -r1.144 -r1.145 src/bin/sh/sh.1
cvs rdiff -u -r1.21 -r1.22 src/bin/sh/shell.h
cvs rdiff -u -r1.54 -r1.55 src/bin/sh/var.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/parser.c
diff -u src/bin/sh/parser.c:1.128 src/bin/sh/parser.c:1.129
--- src/bin/sh/parser.c:1.128	Sun May 14 11:17:04 2017
+++ src/bin/sh/parser.c	Sat May 27 11:19:57 2017
@@ -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 @@ pipeline(void)
 	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 @@ command(void)
 	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 @@ command(void)
 	}
 	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 @@ TRACE(("expecting DO got %s %s\n", tokna
 	}
 
  checkneg:
+#ifdef BOGUS_NOT_COMMAND
 	if (negate) {
 		TRACE(("%snegate command\n", (negate&1) ? "" : "double "));
 		n2 = stalloc(sizeof(struct nnot));
@@ -576,6 +586,7 @@ TRACE(("expecting DO got %s %s\n", tokna
 		return n2;
 	}
 	else
+#endif
 		return n1;
 }
 
@@ -584,8 +595,11 @@ STATIC union node *
 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 @@ simplecmd(union node **rpp, union node *
 	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 @@ simplecmd(union node **rpp, union node *
 	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 @@ simplecmd(union node **rpp, union node *
 		return n2;
 	}
 	else
+#endif
 		return n;
 }
 

Index: src/bin/sh/sh.1
diff -u src/bin/sh/sh.1:1.144 src/bin/sh/sh.1:1.145
--- src/bin/sh/sh.1:1.144	Sat May 27 06:32:12 2017
+++ src/bin/sh/sh.1	Sat May 27 11:19:57 2017
@@ -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 @@ variable is read at startup by a non-int
 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

Index: src/bin/sh/shell.h
diff -u src/bin/sh/shell.h:1.21 src/bin/sh/shell.h:1.22
--- src/bin/sh/shell.h:1.21	Sat May 13 03:26:03 2017
+++ src/bin/sh/shell.h	Sat May 27 11:19:57 2017
@@ -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.

Index: src/bin/sh/var.c
diff -u src/bin/sh/var.c:1.54 src/bin/sh/var.c:1.55
--- src/bin/sh/var.c:1.54	Sat May 27 06:32:12 2017
+++ src/bin/sh/var.c	Sat May 27 11:19:57 2017
@@ -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 @@ INIT {
 #ifndef BSD
 		" -BSD"
 #endif
+#ifdef BOGUS_NOT_COMMAND
+		" BOGUS_NOT"
+#endif
 		    , VTEXTFIXED|VREADONLY|VNOEXPORT);
 }
 #endif

Reply via email to