Module Name:    src
Committed By:   kre
Date:           Wed Jul 25 14:42:50 UTC 2018

Modified Files:
        src/bin/sh: eval.c eval.h exec.c

Log Message:
Fix several bugs in the command / type builtin ( including PR bin/48499 )

1. Make command -pv (and -pV) work (which is not as easy as the PR
   suggests it might be (the "check and cause error" was there because
   it did not work, not in order to prevent it from working).

2. Stop -v and -V being both used (that makes no sense).

3. Stop the "type" builtin inheriting the args (-pvV) that "command" has
   (which it did, as when -v -or -V is used with command, it and type are
    implemented using the same code).

4. make "command -v word" DTRT for sh keywords (was treating them as an error).

5. Require at least one arg for "command -[vV]" or "type" else usage & error.
   Strictly this should also apply to "command" and "command -p" (no -v)
   but that's handled elsewhere, so perhaps some other time.   Perhaps
   "command -v" (and -V) should be limited to 1 command name (where "type"
   can have many) as in the POSIX definitions, but I don't think that matters.

6. With "command -V alias", (or "type alias" which is the same thing),
   (but not "command -v alias") alter the output format, so we get
        ll is an alias for: ls -al
   instead of the old
        ll is an alias for
        ls -al
   (and note there was a space, for some reason, after "for")

   That is, unless the alias value contains any \n characters, in which
   case (something approximating) the old multi-line format is retained.
   Also note: that if code wants to parse/use the value of an alias, it
   should be using the output of "alias name", not command or type.

Note that none of the above affects "command [-p] cmd" (no -v or -V options)
only "command -[vV]" and "type".

Note also that the changes to eval.[ch] are merely to make syspath()
visible in exec.c rather than static in eval.c


To generate a diff of this commit:
cvs rdiff -u -r1.155 -r1.156 src/bin/sh/eval.c
cvs rdiff -u -r1.19 -r1.20 src/bin/sh/eval.h
cvs rdiff -u -r1.52 -r1.53 src/bin/sh/exec.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.155 src/bin/sh/eval.c:1.156
--- src/bin/sh/eval.c:1.155	Fri Jun 22 11:04:55 2018
+++ src/bin/sh/eval.c	Wed Jul 25 14:42:50 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: eval.c,v 1.155 2018/06/22 11:04:55 kre Exp $	*/
+/*	$NetBSD: eval.c,v 1.156 2018/07/25 14:42:50 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.155 2018/06/22 11:04:55 kre Exp $");
+__RCSID("$NetBSD: eval.c,v 1.156 2018/07/25 14:42:50 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -703,7 +703,7 @@ evalbackcmd(union node *n, struct backcm
 		result->fd, result->buf, result->nleft, result->jp));
 }
 
-static const char *
+const char *
 syspath(void)
 {
 	static char *sys_path = NULL;

Index: src/bin/sh/eval.h
diff -u src/bin/sh/eval.h:1.19 src/bin/sh/eval.h:1.20
--- src/bin/sh/eval.h:1.19	Mon May  9 21:03:10 2016
+++ src/bin/sh/eval.h	Wed Jul 25 14:42:50 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: eval.h,v 1.19 2016/05/09 21:03:10 kre Exp $	*/
+/*	$NetBSD: eval.h,v 1.20 2018/07/25 14:42:50 kre Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -52,6 +52,8 @@ union node;	/* BLETCH for ansi C */
 void evaltree(union node *, int);
 void evalbackcmd(union node *, struct backcmd *);
 
+const char *syspath(void);
+
 /* in_function returns nonzero if we are currently evaluating a function */
 int in_function(void);		/* return non-zero, if evaluating a function */
 

Index: src/bin/sh/exec.c
diff -u src/bin/sh/exec.c:1.52 src/bin/sh/exec.c:1.53
--- src/bin/sh/exec.c:1.52	Fri Jun 22 11:04:55 2018
+++ src/bin/sh/exec.c	Wed Jul 25 14:42:50 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec.c,v 1.52 2018/06/22 11:04:55 kre Exp $	*/
+/*	$NetBSD: exec.c,v 1.53 2018/07/25 14:42:50 kre Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)exec.c	8.4 (Berkeley) 6/8/95";
 #else
-__RCSID("$NetBSD: exec.c,v 1.52 2018/06/22 11:04:55 kre Exp $");
+__RCSID("$NetBSD: exec.c,v 1.53 2018/07/25 14:42:50 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -1064,8 +1064,15 @@ typecmd(int argc, char **argv)
 		}
 	}
 
-	if (p_flag && (v_flag || V_flag))
-		error("cannot specify -p with -v or -V");
+	if (argv[0][0] != 'c' && v_flag | V_flag | p_flag)
+		error("usage: %s name...", argv[0]);
+
+	if (v_flag && V_flag)
+		error("-v and -V cannot both be specified");
+
+	if (*argptr == NULL)
+		error("usage: %s%s name ...", argv[0],
+		    argv[0][0] == 'c' ? " [-p] [-v|-V]" : "");
 
 	while ((arg = *argptr++)) {
 		if (!v_flag)
@@ -1077,7 +1084,7 @@ typecmd(int argc, char **argv)
 
 		if (*pp) {
 			if (v_flag)
-				err = 1;
+				out1fmt("%s\n", arg);
 			else
 				out1str(" is a shell keyword\n");
 			continue;
@@ -1085,27 +1092,42 @@ typecmd(int argc, char **argv)
 
 		/* Then look at the aliases */
 		if ((ap = lookupalias(arg, 1)) != NULL) {
-			if (!v_flag)
-				out1fmt(" is an alias for \n");
+			int ml = 0;
+
+			if (!v_flag) {
+				out1str(" is an alias ");
+				if (strchr(ap->val, '\n')) {
+					out1str("(multiline)...\n");
+					ml = 1;
+				} else
+					out1str("for: ");
+			}
 			out1fmt("%s\n", ap->val);
+			if (ml && *argptr != NULL)
+				out1c('\n');
 			continue;
 		}
 
 		/* Then check if it is a tracked alias */
-		if ((cmdp = cmdlookup(arg, 0)) != NULL) {
+		if (!p_flag && (cmdp = cmdlookup(arg, 0)) != NULL) {
 			entry.cmdtype = cmdp->cmdtype;
 			entry.u = cmdp->param;
 		} else {
+			cmdp = NULL;
 			/* Finally use brute force */
-			find_command(arg, &entry, DO_ABS, pathval());
+			find_command(arg, &entry, DO_ABS,
+			     p_flag ? syspath() + 5 : pathval());
 		}
 
 		switch (entry.cmdtype) {
 		case CMDNORMAL: {
 			if (strchr(arg, '/') == NULL) {
-				const char *path = pathval();
+				const char *path;
 				char *name;
 				int j = entry.u.index;
+
+				path = p_flag ? syspath() + 5 : pathval();
+
 				do {
 					name = padvance(&path, arg, 1);
 					stunalloc(name);

Reply via email to