Martijn Dekker schreef op 04-03-16 om 19:30:
> Todd C. Miller schreef op 04-03-16 om 19:22:
>> This also looks fine but we should add a similar regress for whence's
>> -p and -v flags.
> 
> Some minor updates to the man page are also needed. I'll make a new patch.

Here's take 2.

I had missed one thing: aliases were also missed by 'command -pv' and
'command -pV', but should be found for the same reason as reserved
words. Now fixed.

I've also added two fairly comprehensive regression tests, the first to
test that 'command' now behaves like POSIX for reserved words, aliases,
functions, special builtins and regular builtins, and the second to
ensure that the behaviour of 'whence' is unchanged. The latter test
passes both on the original ksh and the patched one.

Finally I've edited both ksh.1 and sh.1 to reflect the change and to
make the language a little clearer.

Thanks,

- M.

Index: bin/ksh/c_ksh.c
===================================================================
RCS file: /cvs/src/bin/ksh/c_ksh.c,v
retrieving revision 1.49
diff -u -p -u -r1.49 c_ksh.c
--- bin/ksh/c_ksh.c	15 Jan 2016 17:55:45 -0000	1.49
+++ bin/ksh/c_ksh.c	4 Mar 2016 21:28:35 -0000
@@ -433,23 +433,23 @@ c_whence(char **wp)
 
 	fcflags = FC_BI | FC_PATH | FC_FUNC;
 	if (!iam_whence) {
-		/* Note that -p on its own is deal with in comexec() */
+		/* Note that -p on its own is dealt with in comexec() */
 		if (pflag)
 			fcflags |= FC_DEFPATH;
-		/* Convert command options to whence options - note that
-		 * command -pV uses a different path search than whence -v
-		 * or whence -pv.  This should be considered a feature.
+		/* Convert command options to whence options.  Note that
+		 * command -pV and command -pv use a different path search
+		 * than whence -v or whence -pv.  This should be considered
+		 * a feature.
 		 */
 		vflag = Vflag;
-	}
-	if (pflag)
+	} else if (pflag)
 		fcflags &= ~(FC_BI | FC_FUNC);
 
 	while ((vflag || ret == 0) && (id = *wp++) != NULL) {
 		tp = NULL;
-		if ((iam_whence || vflag) && !pflag)
+		if (!iam_whence || !pflag)
 			tp = ktsearch(&keywords, id, hash(id));
-		if (!tp && !pflag) {
+		if (!tp && (!iam_whence || !pflag)) {
 			tp = ktsearch(&aliases, id, hash(id));
 			if (tp && !(tp->flag & ISSET))
 				tp = NULL;
Index: bin/ksh/ksh.1
===================================================================
RCS file: /cvs/src/bin/ksh/ksh.1,v
retrieving revision 1.173
diff -u -p -u -r1.173 ksh.1
--- bin/ksh/ksh.1	29 Dec 2015 01:02:34 -0000	1.173
+++ bin/ksh/ksh.1	4 Mar 2016 21:28:37 -0000
@@ -2969,7 +2969,7 @@ is executed exactly as if
 had not been specified, with two exceptions:
 firstly,
 .Ar cmd
-cannot be a shell function;
+cannot be an alias or a shell function;
 and secondly, special built-in commands lose their specialness
 (i.e. redirection and utility errors do not cause the shell to
 exit, and command assignments are not permanent).
@@ -2981,6 +2981,8 @@ option is given, a default search path i
 (the actual value of the default path is system dependent: on
 POSIX-ish systems, it is the value returned by
 .Ic getconf CS_PATH ) .
+However, this does not change that reserved words, aliases, shell
+functions, and builtin commands are found before external commands.
 .Pp
 If the
 .Fl v
@@ -4473,7 +4475,7 @@ is similar to
 .Ic command Fl v
 except that
 .Ic whence
-will find reserved words and won't print aliases as alias commands.
+won't print aliases as alias commands.
 With the
 .Fl v
 option,
Index: bin/ksh/sh.1
===================================================================
RCS file: /cvs/src/bin/ksh/sh.1,v
retrieving revision 1.130
diff -u -p -u -r1.130 sh.1
--- bin/ksh/sh.1	12 Oct 2015 12:34:42 -0000	1.130
+++ bin/ksh/sh.1	4 Mar 2016 21:28:38 -0000
@@ -305,15 +305,15 @@ Resolve symbolic links before processing
 components.
 .El
 .It Ic command Oo Fl p | V | v Oc Ar command Op Ar arg ...
-Invoke
+Invoke the specified
 .Ar command
-(and any optional arguments),
+(with any arguments given),
 overriding any functions with the same name,
 and without any of the properties that special built-ins have.
 .Pp
-The options to
+The options to the
 .Ic command
-are as follows:
+utility are as follows:
 .Pp
 .Bl -tag -width Ds -offset 3n -compact
 .It Fl p
@@ -321,24 +321,27 @@ Use a default value for
 .Ev PATH
 to search for the command.
 .It Fl V
-Do not invoke
+Do not invoke the specified
 .Ar command ,
 but identify how the shell will interpret it
 (such as a function or special built-in).
 .It Fl v
-Do not invoke
+Do not invoke the specified
 .Ar command ,
 but identify the pathname the shell will use to run it.
+For aliases, a command to define that alias is printed.
+For shell reserved words, shell functions, and built-in utilities,
+just the name is printed.
 .El
 .Pp
-The exit status is that of
+The exit status is that of the specified
 .Ar command ,
-or 126 if
+or 126 if the
 .Ar command
 could not be invoked,
-or 127 if an error occurred in
+or 127 if an error occurred in the
 .Ic command
-itself or
+built-in utility itself or if the specified
 .Ar command
 could not be found.
 If the options
@@ -346,8 +349,9 @@ If the options
 or
 .Fl v
 are given,
-the exit status is 0 on success,
-or >0 if an error occurs.
+the exit status is 0 if the
+.Ar command
+was found, or >0 if it was not found.
 .It Ic continue Op Ar n
 Go directly to the next iteration of the innermost
 .Ic for , while ,
Index: regress/bin/ksh/obsd-regress.t
===================================================================
RCS file: /cvs/src/regress/bin/ksh/obsd-regress.t,v
retrieving revision 1.1
diff -u -p -u -r1.1 obsd-regress.t
--- regress/bin/ksh/obsd-regress.t	2 Dec 2013 20:39:44 -0000	1.1
+++ regress/bin/ksh/obsd-regress.t	4 Mar 2016 21:28:38 -0000
@@ -273,3 +273,75 @@ stdin:
 	set foo bar baz ; for out in ; do echo $out ; done
 
 ---
+name: command-pvV-posix-priorities
+description:
+	For POSIX compatibility, command -v should find aliases and reserved
+	words, and command -p[vV] should find aliases, reserved words, and
+	builtins over external commands.
+stdin:
+	PATH=/bin:/usr/bin
+	alias foo="bar baz"
+	bar() { :; }
+	for word in 'if' 'foo' 'bar' 'set' 'true'; do
+		command -v "$word"
+		command -pv "$word"
+		command -V "$word"
+		command -pV "$word"
+	done
+expected-stdout:
+	if
+	if
+	if is a reserved word
+	if is a reserved word
+	alias foo='bar baz'
+	alias foo='bar baz'
+	foo is an alias for 'bar baz'
+	foo is an alias for 'bar baz'
+	bar
+	bar
+	bar is a function
+	bar is a function
+	set
+	set
+	set is a special shell builtin
+	set is a special shell builtin
+	true
+	true
+	true is a shell builtin
+	true is a shell builtin
+
+---
+name: whence-preserve-tradition
+description:
+	POSIX 'command' and ksh88/pdksh-specific 'whence' are handled by the
+	same c_whence() function.  This regression test is to ensure that
+	the POSIX compatibility changes for 'command' (see previous test) do
+	not affect traditional 'whence' behaviour.
+stdin:
+	PATH=/bin:/usr/bin
+	alias foo="bar baz"
+	bar() { :; }
+	for word in 'if' 'foo' 'bar' 'set' 'true'; do
+		whence "$word"
+		whence -p "$word"
+		whence -v "$word"
+		whence -pv "$word"
+	done
+expected-stdout:
+	if
+	if is a reserved word
+	if not found
+	'bar baz'
+	foo is an alias for 'bar baz'
+	foo not found
+	bar
+	bar is a function
+	bar not found
+	set
+	set is a special shell builtin
+	set not found
+	true
+	/usr/bin/true
+	true is a shell builtin
+	true is a tracked alias for /usr/bin/true
+---

Reply via email to