summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--Completion/Unix/Type/_canonical_paths31
2 files changed, 29 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 69c25383f..4774932ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2008-03-27 Peter Stephenson <pws@csr.com>
+ * 24757: Completion/Unix/Type/_canonical_paths: use
+ CHASE_LINKS and pwd to canonicalize the directory path.
+
* unposted: fix alias test in 24736 properly by replacing
"foo" everywhere.
diff --git a/Completion/Unix/Type/_canonical_paths b/Completion/Unix/Type/_canonical_paths
index 188b1d997..e4101dc47 100644
--- a/Completion/Unix/Type/_canonical_paths
+++ b/Completion/Unix/Type/_canonical_paths
@@ -36,20 +36,41 @@ typeset REPLY
typeset -a matches files
_canonical_paths_get_canonical_path() {
- typeset newfile
+ typeset newfile dir
typeset -A seen
REPLY=$1
- # Guard against loops.
+ # Resolve any trailing symbolic links, guarding against loops.
while [[ -z ${seen[$REPLY]} ]]; do
seen[$REPLY]=1
- newfile=$(zstat +link $REPLY 2>/dev/null)
- if [[ -n $newfile ]]; then
- REPLY=$newfile
+ newfile=()
+ zstat -A newfile +link $REPLY 2>/dev/null
+ if [[ -n $newfile[1] ]]; then
+ REPLY=$newfile[1]
else
break
fi
done
+
+ # Canonicalise the directory path. We may not be able to
+ # do this if we can't read all components.
+ if [[ -d $REPLY ]]; then
+ dir="$(unfunction chpwd
+ setopt CHASE_LINKS
+ cd $REPLY 2>/dev/null && pwd)"
+ if [[ -n $dir ]]; then
+ REPLY=$dir
+ fi
+ elif [[ $REPLY = */*[^/] && $REPLY != /[^/]# ]]; then
+ # Don't try this if there's a trailing slash or we're in
+ # the root directory.
+ dir="$(unfunction chpwd
+ setopt CHASE_LINKS
+ cd ${REPLY%/*} 2>/dev/null && pwd)"
+ if [[ -n $dir ]]; then
+ REPLY=$dir/${REPLY##*/}
+ fi
+ fi
}