mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Multiple 'whence' and path search fixes
Hopefully this doesn't introduce new bugs, but it does fix at
least the following:
1. When whence -v/-a found an "undefined" (i.e. autoloadable)
function in $FPATH, it actually loaded the function as a side
effect of reporting on its existence (!). Now it only reports.
2. 'whence' will now canonicalise paths properly. Examples:
$ whence ///usr/lib/../bin//./env
/usr/bin/env
$ (cd /; whence -v dev/../usr/bin//./env)
dev/../usr/bin//./env is /usr/bin/env
3. 'whence' no longer prefixes a spurious double slash when doing
something like 'cd / && whence bin/echo'. On Cygwin, an initial
double slash denotes a network server, so this was not just a
cosmetic problem.
4. 'whence -a' now reports a "tracked alias" (a.k.a. hash table
entry, i.e. cached $PATH search) even if an actual alias by the
same name exists. This needed fixing because in fact the hash
table entry continues to be used when bypassing the alias.
Aliases and "tracked aliases" are not remotely the same thing;
confusing nomenclature is not a reason to report wrong results.
5. When using 'hash' or 'alias -t' on a command that is also a
builtin to force caching a $PATH search for the external
command, 'whence -a' double-reported the path:
$ hash printf; whence -a printf
printf is a shell builtin
printf is /usr/bin/printf
printf is a tracked alias for /usr/bin/printf
This is now fixed so that the second output line is gone.
Plus, if there were multiple versions of the command on $PATH,
the tracked alias was reported at the end, which is the wrong
order. This is also fixed.
src/cmd/ksh93/bltins/whence.c: whence():
- Refactor the do...while loop that handles whence -v/-a for path
searches in such a way that the code actually makes sense and
stops looking like higher esotericism. Just doing this fixed #2,
#4 and #5 above (the latter two before I even noticed them). For
instance, the path_fullname() call to canonicalise paths was
already there; it was just never used.
- Remove broken 'notrack' flaggery for deciding whether to report a
hash table entry a.k.a. "tracked alias"; instead, check the hash
table (shp->track_tree).
src/cmd/ksh93/sh/path.c:
- path_search(): Re #3: When prefixing the PWD, first check if
we're in '/' and if so, don't prefix it; otherwise, adding the
next slash causes an initial double slash. (Since '/' is the only
valid single-character absolute path, all we need to do is check
if the second character pwd[1] is non-null.)
- path_search(): Re #1: Stop autoloading when called by 'whence':
* The 'flag==2' check to avoid autoloading a function was
broken. The flag value is 2 on the first whence() loop
iteration, but 3 on subsequent ones. Change to 'flag >= 2'.
* However, this only fixes it if the function file does not have
the x permission bit, as executable files are handled by
path_absolute() which unconditionally autoloads functions!
So, pass on our flag parameter when callling path_absolute().
- path_absolute(): Re #1: Add flag parameter. Do not autoload
functions if flag >= 2.
src/cmd/ksh93/include/path.h,
src/cmd/ksh93/bltins/typeset.c,
src/cmd/ksh93/sh/main.c,
src/cmd/ksh93/sh/xec.c:
- Re #1: Update path_absolute() calls, adding a 0 flag parameter.
src/cmd/ksh93/include/name.h:
- Remove now-unused pathcomp member from union Value. It was
introduced in 99065353
to allow examining the value of a tracked
alias. This commit uses nv_getval() instead.
src/cmd/ksh93/tests/builtins.sh,
src/cmd/ksh93/tests/path.sh:
- Add and tweak various related tests.
Fixes: https://github.com/ksh93/ksh/issues/84
This commit is contained in:
parent
95fc175993
commit
a329c22dba
11 changed files with 192 additions and 106 deletions
|
@ -763,7 +763,7 @@ foo=BUG command eval ':'
|
|||
[[ $foo == BUG ]] && err_exit '`command` fails to disable the special properties of special builtins'
|
||||
|
||||
# ======
|
||||
# 'whence -a' tests
|
||||
# whence -a/-v tests
|
||||
|
||||
# wrong path to tracked aliases after loading builtin: https://github.com/ksh93/ksh/pull/25
|
||||
actual=$("$SHELL" -c '
|
||||
|
@ -771,34 +771,75 @@ actual=$("$SHELL" -c '
|
|||
builtin chmod
|
||||
whence -a chmod
|
||||
')
|
||||
expected="chmod is a shell builtin
|
||||
$(whence -a -p chmod | sed 's/^/chmod is /')
|
||||
expect="chmod is a shell builtin
|
||||
chmod is a tracked alias for $(whence -p chmod)"
|
||||
[[ $actual == $expected ]] || err_exit "'whence -a' does not work correctly with tracked aliases" \
|
||||
"(expected $(printf %q "$expected"), got $(printf %q "$actual"))"
|
||||
[[ $actual == "$expect" ]] || err_exit "'whence -a' does not work correctly with tracked aliases" \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# spurious 'undefined function' message: https://github.com/ksh93/ksh/issues/26
|
||||
actual=$("$SHELL" -c 'whence -a printf')
|
||||
expected="printf is a shell builtin
|
||||
expect="printf is a shell builtin
|
||||
$(whence -a -p printf | sed 's/^/printf is /')"
|
||||
[[ $actual == $expected ]] || err_exit "'whence -a': incorrect output" \
|
||||
"(expected $(printf %q "$expected"), got $(printf %q "$actual"))"
|
||||
[[ $actual == "$expect" ]] || err_exit "'whence -a': incorrect output" \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# 'whence -a'/'type -a' failed to list builtin if function exists: https://github.com/ksh93/ksh/issues/83
|
||||
actual=$(printf() { :; }; whence -a printf)
|
||||
expected="printf is a function
|
||||
expect="printf is a function
|
||||
printf is a shell builtin
|
||||
$(whence -a -p printf | sed 's/^/printf is /')"
|
||||
[[ $actual == $expected ]] || err_exit "'whence -a': incorrect output for function+builtin" \
|
||||
"(expected $(printf %q "$expected"), got $(printf %q "$actual"))"
|
||||
|
||||
# 'whence -a'/'type -a' failed to list builtin if autoload function exists: https://github.com/ksh93/ksh/issues/83
|
||||
[[ $actual == "$expect" ]] || err_exit "'whence -a': incorrect output for function+builtin" \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
actual=$(autoload printf; whence -a printf)
|
||||
expected="printf is an undefined function
|
||||
expect="printf is an undefined function
|
||||
printf is a shell builtin
|
||||
$(whence -a -p printf | sed 's/^/printf is /')"
|
||||
[[ $actual == $expected ]] || err_exit "'whence -a': incorrect output for autoload+builtin" \
|
||||
"(expected $(printf %q "$expected"), got $(printf %q "$actual"))"
|
||||
[[ $actual == "$expect" ]] || err_exit "'whence -a': incorrect output for autoload+builtin" \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# 'whence -v' canonicalized paths improperly: https://github.com/ksh93/ksh/issues/84
|
||||
cmdpath=${ whence -p printf; }
|
||||
actual=$(cd /; whence -v "${cmdpath#/}")
|
||||
expect="${cmdpath#/} is $cmdpath"
|
||||
[[ $actual == "$expect" ]] || err_exit "'whence -v': incorrect canonicalization of initial /" \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
dotdot=
|
||||
num=$(set -f; IFS=/; set -- $PWD; echo $#)
|
||||
for ((i=1; i<num; i++))
|
||||
do dotdot+='../'
|
||||
done
|
||||
actual=$(cd /; whence -v "$dotdot${cmdpath#/}")
|
||||
expect="$dotdot${cmdpath#/} is $cmdpath"
|
||||
[[ $actual == "$expect" ]] || err_exit "'whence -v': incorrect canonicalization of pathname containing '..'" \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# even absolute paths should be canonicalized
|
||||
if [[ -x /usr/bin/env && -d /usr/lib ]] # even NixOS has this...
|
||||
then expect='/usr/lib/../bin/./env is /usr/bin/env'
|
||||
actual=$(whence -v /usr/lib/../bin/./env)
|
||||
[[ $actual == "$expect" ]] || err_exit "'whence -v': incorrect canonicalization of absolute path" \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
fi
|
||||
|
||||
# whence -v/-a should not autoload functions itself
|
||||
echo 'ls() { echo "Oops, I'\''m a function!"; }' >$tmp/ls
|
||||
expect=$'/dev/null\n/dev/null'
|
||||
actual=$(FPATH=$tmp; ls /dev/null; whence -a ls >/dev/null; ls /dev/null)
|
||||
[[ $actual == "$expect" ]] || err_exit "'whence -a': mistaken \$FPATH function autoload (non-executable file)" \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
chmod +x "$tmp/ls"
|
||||
actual=$(FPATH=$tmp; ls /dev/null; whence -a ls >/dev/null; ls /dev/null)
|
||||
[[ $actual == "$expect" ]] || err_exit "'whence -a': mistaken \$FPATH function autoload (executable file)" \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# "tracked aliases" (known on other shells as hash table entries) are really just cached PATH search
|
||||
# results; they should be reported independently from real aliases, as they're actually completely
|
||||
# different things, and "tracked aliases" are actually used when bypassing an alias (with e.g. \ls).
|
||||
expect="ls is an alias for 'echo ALL UR F1LEZ R G0N3'
|
||||
ls is a tracked alias for /bin/ls"
|
||||
actual=$(hash -r; alias ls='echo ALL UR F1LEZ R G0N3'; hash ls; whence -a ls)
|
||||
[[ $actual == "$expect" ]] || err_exit "'whence -a' does not report tracked alias if alias exists" \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# ======
|
||||
# 'cd ../.foo' should not exclude the '.' in '.foo'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue