tests: clean up tests of env -- handling
authorEric Blake <ebb9@byu.net>
Mon, 26 Oct 2009 19:32:49 +0000 (13:32 -0600)
committerEric Blake <ebb9@byu.net>
Tue, 27 Oct 2009 03:30:34 +0000 (21:30 -0600)
The comment in env.c about -- handling has not matched the behavior
in the code since the initial commit back in 1992.

* src/env.c: Fix bogus comment.
* tests/misc/env: Further tweaks, avoiding PATH problems inherent
in testing -i, and testing program name containing =.
* doc/coreutils.texi (env invocation): Mention that intermediate
program is needed to invoke program with name containing =.

doc/coreutils.texi
src/env.c
tests/misc/env

index 8a79ba7..138cf01 100644 (file)
@@ -14413,6 +14413,20 @@ Modifications to @env{PATH} take effect prior to searching for
 not portable when @env{PATH} is undefined or omits key directories
 such as @file{/bin}.
 
+In the rare case that a utility contains a @samp{=} in the name, the
+only way to disambiguate it from a variable assignment is to use an
+intermediate command for @var{command}, and pass the problematic
+program name via @var{args}.  For example, if @file{./prog=} is an
+executable in the current @env{PATH}:
+
+@example
+env prog= true # runs 'true', with prog= in environment
+env ./prog= true # runs 'true', with ./prog= in environment
+env -- prog= true # runs 'true', with prog= in environment
+env sh -c '\prog= true' # runs 'prog=' with argument 'true'
+env sh -c 'exec "$@@"' sh prog= true # also runs 'prog='
+@end example
+
 @cindex environment, printing
 
 If no command name is specified following the environment
index 02d155d..8d7d55e 100644 (file)
--- a/src/env.c
+++ b/src/env.c
         zero-length value is different from unsetting it.
 
    --
-        Indicate that the following argument is the program
-        to invoke.  This is necessary when the program's name
-        begins with "-" or contains a "=".
+        Indicate that the following argument is not an option.
+        This is necessary when the program's name begins with "-",
+        but does not help if the program's name contains a "=".
 
    The first remaining argument specifies a program to invoke;
    it is searched for according to the specification of the PATH
-   environment variable.  Any arguments following that are
-   passed as arguments to that program.
+   environment variable, after environment modifications.  Any
+   arguments following that are passed as arguments to that program.
 
    If no command name is specified following the environment
    specifications, the resulting environment is printed.
@@ -72,8 +72,9 @@
         call.
 
    env -u EDITOR LOGNAME=foo PATH=/energy -- e=mc2 bar baz
-        runs the program "/energy/e=mc2" with environment
-        { LOGNAME=foo PATH=/energy }
+        attempts to run the program "/energy/--" with arguments
+        "e=mc2", "bar" and "baz" in the environment
+        { LOGNAME=foo PATH=/energy }.
 */
 
 #include <config.h>
index e1e51ed..fb3be29 100755 (executable)
@@ -103,25 +103,49 @@ env also_unlikely && fail=1
 test x`PATH=$PATH:unlikely_name env also_unlikely` = xpass || fail=1
 test x`env PATH="$PATH":unlikely_name also_unlikely` = xpass || fail=1
 
-# Use -- to end arguments.
-ln -s "$abs_top_builddir/src/echo" ./-i || framework_failure
-case `PATH="$PATH:" env -i echo good` in
+# Explicitly put . on the PATH for the rest of this test.
+PATH=$PATH:
+export PATH
+
+# Use -- to end options (but not variable assignments).
+# On some systems, execve("-i") invokes a shebang script ./-i on PATH as
+# '/bin/sh -i', rather than '/bin/sh -- -i', which doesn't do what we want.
+# Avoid the issue by using an executable rather than a script.
+# Test -u, rather than -i, to minimize PATH problems.
+ln -s "$abs_top_builddir/src/echo" ./-u || framework_failure
+case `env -u echo echo good` in
   good) ;;
   *) fail=1 ;;
 esac
-case `env -i -- PATH=. -i no-echo` in
-  no-echo) ;;
+case `env -u echo -- echo good` in
+  good) ;;
+  *) fail=1 ;;
+esac
+case `env -- -u pass` in
+  pass) ;;
+  *) fail=1 ;;
+esac
+
+# After options have ended, the first argument not containing = is a program.
+env a=b -- true
+test $? = 127 || fail=1
+ln -s "$abs_top_builddir/src/echo" ./-- || framework_failure
+case `env a=b -- true || echo fail` in
+  true) ;;
   *) fail=1 ;;
 esac
 
-# FIXME - POSIX does not allow this; decide what we want to do
-# cat <<EOF >./c=d || framework_failure
-# #!/bin/sh
-# echo pass
-# EOF
-# chmod +x c=d || framework_failure
-# test "x`env c=d echo fail`" = xfail || fail=1
-# test "x`env -- c=d echo fail`" = xpass || fail=1
+# No way to directly invoke program name containing =.
+cat <<EOF >./c=d || framework_failure
+#!/bin/sh
+echo pass
+EOF
+chmod +x c=d || framework_failure
+test "x`env c=d echo fail`" = xfail || fail=1
+test "x`env -- c=d echo fail`" = xfail || fail=1
+test "x`env ./c=d echo fail`" = xfail || fail=1
+test "x$(env sh -c '\c=d echo fail')" = xpass || fail=1
+test "x$(env sh -c 'exec "$@"' sh c=d echo fail)" = xpass || fail=1
 
 # catch unsetenv failure, broken through coreutils 8.0
 env -u a=b true && fail=1