Fix more inconsistent behaviour with symlinks in paths.
Both redo and minimal/do were doing slightly weird things with symlinked directories, especially when combined with "..". For example, if x is a link to ., then x/x/x/x/../y should resolve to "../y", which is quite non-obvious. Added some tests to make sure this stays fixed.
This commit is contained in:
parent
1f64cc4525
commit
686c381109
13 changed files with 121 additions and 8 deletions
36
minimal/do
36
minimal/do
|
|
@ -204,6 +204,38 @@ _normpath()
|
|||
)
|
||||
|
||||
|
||||
# Prints a "real" path, with all symlinks resolved where possible.
|
||||
_realpath()
|
||||
{
|
||||
local path="$1" relto="$2" isabs= rest=
|
||||
if _startswith "$path" "/"; then
|
||||
isabs=1
|
||||
else
|
||||
path="${relto%/}/$path"
|
||||
fi
|
||||
(
|
||||
for d in $(seq 100); do
|
||||
#echo "Trying: $PWD--$path" >&2
|
||||
if cd -P "$path" 2>/dev/null; then
|
||||
# success
|
||||
pwd=$(/bin/pwd)
|
||||
#echo " chdir ok: $pwd--$rest" >&2
|
||||
np=$(_normpath "${pwd%/}/$rest" "$relto")
|
||||
if [ -n "$isabs" ]; then
|
||||
echo "$np"
|
||||
else
|
||||
_relpath "$np" "$relto"
|
||||
fi
|
||||
break
|
||||
fi
|
||||
_dirsplit "${path%/}"
|
||||
path=$_dirsplit_dir
|
||||
rest="$_dirsplit_base/$rest"
|
||||
done
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
# List the possible names for default*.do files in dir $1 matching the target
|
||||
# pattern in $2. We stop searching when we find the first one that exists.
|
||||
_find_dofiles_pwd()
|
||||
|
|
@ -241,7 +273,7 @@ _find_dofiles()
|
|||
[ -n "$dodir" ] && dodir=${dodir%/}/
|
||||
#echo "_find_dofiles: '$dodir' '$dofile'" >&2
|
||||
_find_dofiles_pwd "$dodir" "$dofile" && return 0
|
||||
newdir=$(_normpath "${dodir}.." "$PWD")
|
||||
newdir=$(_realpath "${dodir}.." "$PWD")
|
||||
[ "$newdir" = "$dodir" ] && break
|
||||
dodir=$newdir
|
||||
done
|
||||
|
|
@ -369,7 +401,7 @@ _redo()
|
|||
i=$(_abspath "$i" "$startdir")
|
||||
(
|
||||
cd "$DO_STARTDIR" || return 99
|
||||
i=$(_normpath "$(_relpath "$i" "$PWD")" "$PWD")
|
||||
i=$(_realpath "$(_relpath "$i" "$PWD")" "$PWD")
|
||||
_dirsplit "$i"
|
||||
dir=$_dirsplit_dir base=$_dirsplit_base
|
||||
_do "$dir" "$base"
|
||||
|
|
|
|||
|
|
@ -130,6 +130,17 @@ check ".." _normpath ../ "$x"
|
|||
check ".." _normpath .. "$x"
|
||||
|
||||
|
||||
SECTION _realpath
|
||||
rm -rf y
|
||||
mkdir y
|
||||
ln -s . y/x
|
||||
check "/usr/__does_not/b" _realpath "/usr/__does_not/a/../b" "$x"
|
||||
check "foo" _realpath "y/x/x/x/x/x/../foo" "$PWD"
|
||||
check "$(/bin/pwd)/foo" _realpath "$PWD/y/x/x/x/x/x/../foo" "$PWD"
|
||||
check "foo/blam" _realpath "y/x/x/x/x/x/../foo/spam/../blam" "$PWD"
|
||||
check "$(/bin/pwd)/foo/blam" _realpath "$PWD/y/x/x/../foo/spam/../blam" "$PWD"
|
||||
|
||||
|
||||
SECTION _find_dofile
|
||||
check "test.do" _find_dofiles test
|
||||
check "test.do" _find_dofile test
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue