aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorJilles Tjoelker <jilles@FreeBSD.org>2020-09-01 13:19:15 +0000
committerJilles Tjoelker <jilles@FreeBSD.org>2020-09-01 13:19:15 +0000
commitccd0a51fda561d10e091926a83e5bca0e6f41d6d (patch)
tree51509b07b46ed2cc7420d07314703ac18a191924 /bin
parent78ae1e6e15a5c4b5e7d18610a1a0daf44589063c (diff)
downloadsrc-ccd0a51fda561d10e091926a83e5bca0e6f41d6d.tar.gz
src-ccd0a51fda561d10e091926a83e5bca0e6f41d6d.zip
sh: Write absolute path in command -vV and type
POSIX is pretty clear that command -v, command -V and type shall write absolute pathnames. Therefore, we need to prepend the current directory's name to relative pathnames. This can happen either when PATH contains a relative pathname or when the operand contains a slash but is not an absolute pathname.
Notes
Notes: svn path=/head/; revision=365037
Diffstat (limited to 'bin')
-rw-r--r--bin/sh/exec.c33
-rw-r--r--bin/sh/tests/builtins/Makefile3
-rw-r--r--bin/sh/tests/builtins/command13.021
-rw-r--r--bin/sh/tests/builtins/command14.09
-rw-r--r--bin/sh/tests/builtins/type4.09
5 files changed, 64 insertions, 11 deletions
diff --git a/bin/sh/exec.c b/bin/sh/exec.c
index 60be83857466..e3779b097e1d 100644
--- a/bin/sh/exec.c
+++ b/bin/sh/exec.c
@@ -679,6 +679,21 @@ isfunc(const char *name)
}
+static void
+print_absolute_path(const char *name)
+{
+ const char *pwd;
+
+ if (*name != '/' && (pwd = lookupvar("PWD")) != NULL && *pwd != '\0') {
+ out1str(pwd);
+ if (strcmp(pwd, "/") != 0)
+ outcslow('/', out1);
+ }
+ out1str(name);
+ outcslow('\n', out1);
+}
+
+
/*
* Shared code for the following builtin commands:
* type, command -v, command -V
@@ -745,20 +760,16 @@ typecmd_impl(int argc, char **argv, int cmd, const char *path)
name = padvance(&path2, &opt2, argv[i]);
stunalloc(name);
} while (--j >= 0);
- if (cmd == TYPECMD_SMALLV)
- out1fmt("%s\n", name);
- else
- out1fmt("%s is%s %s\n", argv[i],
+ if (cmd != TYPECMD_SMALLV)
+ out1fmt("%s is%s ", argv[i],
(cmdp && cmd == TYPECMD_TYPE) ?
- " a tracked alias for" : "",
- name);
+ " a tracked alias for" : "");
+ print_absolute_path(name);
} else {
if (eaccess(argv[i], X_OK) == 0) {
- if (cmd == TYPECMD_SMALLV)
- out1fmt("%s\n", argv[i]);
- else
- out1fmt("%s is %s\n", argv[i],
- argv[i]);
+ if (cmd != TYPECMD_SMALLV)
+ out1fmt("%s is ", argv[i]);
+ print_absolute_path(argv[i]);
} else {
if (cmd != TYPECMD_SMALLV)
outfmt(out2, "%s: %s\n",
diff --git a/bin/sh/tests/builtins/Makefile b/bin/sh/tests/builtins/Makefile
index 1cce8755a726..197d735920e6 100644
--- a/bin/sh/tests/builtins/Makefile
+++ b/bin/sh/tests/builtins/Makefile
@@ -69,6 +69,8 @@ ${PACKAGE}FILES+= command9.0
${PACKAGE}FILES+= command10.0
${PACKAGE}FILES+= command11.0
${PACKAGE}FILES+= command12.0
+${PACKAGE}FILES+= command13.0
+${PACKAGE}FILES+= command14.0
${PACKAGE}FILES+= dot1.0
${PACKAGE}FILES+= dot2.0
${PACKAGE}FILES+= dot3.0
@@ -170,6 +172,7 @@ ${PACKAGE}FILES+= trap9.0
${PACKAGE}FILES+= type1.0 type1.0.stderr
${PACKAGE}FILES+= type2.0
${PACKAGE}FILES+= type3.0
+${PACKAGE}FILES+= type4.0
${PACKAGE}FILES+= unalias.0
${PACKAGE}FILES+= var-assign.0
${PACKAGE}FILES+= var-assign2.0
diff --git a/bin/sh/tests/builtins/command13.0 b/bin/sh/tests/builtins/command13.0
new file mode 100644
index 000000000000..7c011c938a47
--- /dev/null
+++ b/bin/sh/tests/builtins/command13.0
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+failures=0
+
+check() {
+ if [ "$1" != "$2" ] && { [ "$#" -lt 3 ] || [ "$1" != "$3" ]; } then
+ echo "Mismatch found"
+ echo "Expected: $2"
+ if [ "$#" -ge 3 ]; then
+ echo "Alternative expected: $3"
+ fi
+ echo "Actual: $1"
+ : $((failures += 1))
+ fi
+}
+
+check "$(cd /bin && PATH=. command -v ls)" /bin/ls /bin/./ls
+check "$(cd /bin && PATH=:/var/empty/nosuch command -v ls)" /bin/ls /bin/./ls
+check "$(cd / && PATH=bin command -v ls)" /bin/ls
+check "$(cd / && command -v bin/ls)" /bin/ls
+check "$(cd /bin && command -v ./ls)" /bin/ls /bin/./ls
diff --git a/bin/sh/tests/builtins/command14.0 b/bin/sh/tests/builtins/command14.0
new file mode 100644
index 000000000000..5f6f4447ef61
--- /dev/null
+++ b/bin/sh/tests/builtins/command14.0
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+r=`cd /bin && PATH=. command -V ls`
+case $r in
+*/bin/ls*|*/bin/./ls*) ;;
+*)
+ echo "Unexpected result: $r"
+ exit 1
+esac
diff --git a/bin/sh/tests/builtins/type4.0 b/bin/sh/tests/builtins/type4.0
new file mode 100644
index 000000000000..5b5f96c5078d
--- /dev/null
+++ b/bin/sh/tests/builtins/type4.0
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+r=`cd /bin && PATH=. type ls`
+case $r in
+*/bin/ls*|*/bin/./ls*) ;;
+*)
+ echo "Unexpected result: $r"
+ exit 1
+esac