Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: _canonical_path not working on *BSD
- X-seq: zsh-workers 24750
- From: Peter Stephenson <pws@xxxxxxx>
- To: zsh-workers@xxxxxxxxxx
- Subject: Re: _canonical_path not working on *BSD
- Date: Wed, 26 Mar 2008 16:21:51 +0000
- In-reply-to: <200803261604.m2QG41Ke017772@xxxxxxxxxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- References: <20080326114413.80713vrmznwpnyuc@xxxxxxxxxxxxxxx> <080326083638.ZM16858@xxxxxxxxxxxxxxxxxxxxxx> <200803261540.m2QFeJmm017381@xxxxxxxxxxxxxx> <200803261604.m2QG41Ke017772@xxxxxxxxxxxxxx>
Peter Stephenson wrote:
> Hmm... sorry about all the traffic... actually, it still doesn't
> guarantee to give a canonical path as "readlink -f" does, since it
> doesn't check if the value returned is itself a symbolic link, and also
> it returns empty instead of the original file if it wasn't a link. We would
> need to do something like the following... if I've correctly divined
> that the intention in both cases is that if a file exists at all we
> should always use the name, but converted to the canonical form.
Sigh. Or even this. This time, I've guarded against loops in the
symbolic links.
I'm still not quite sure what the test of the status from readlink in
the second case was for, seeing as "readlink -qf /nonexistent" returns
status 0. I've interpreted it as a test for a file that actually
exists. In the present context it may not matter.
Index: Completion/Unix/Type/_canonical_paths
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_canonical_paths,v
retrieving revision 1.1
diff -u -r1.1 _canonical_paths
--- Completion/Unix/Type/_canonical_paths 28 May 2006 18:36:06 -0000 1.1
+++ Completion/Unix/Type/_canonical_paths 26 Mar 2008 16:16:14 -0000
@@ -27,18 +27,38 @@
shift 2
-if (( ! $+commands[readlink] )); then
+if ! zmodload -F zsh/stat b:zstat 2>/dev/null; then
_wanted "$tag" expl "$desc" compadd $__gopts $@ && ret=0
return ret
fi
+typeset REPLY
typeset -a matches files
+_canonical_paths_get_canonical_path() {
+ typeset newfile
+ typeset -A seen
+
+ REPLY=$1
+ # Guard against loops.
+ while [[ -z ${seen[$REPLY]} ]]; do
+ seen[$REPLY]=1
+ newfile=$(zstat +link $REPLY 2>/dev/null)
+ if [[ -n $newfile ]]; then
+ REPLY=$newfile
+ else
+ break
+ fi
+ done
+}
+
+
if (( $__opts[(I)-N] )); then
files=($@)
else
for __index in $@; do
- files+=$(readlink -qf $__index)
+ _canonical_paths_get_canonical_path $__index
+ files+=($REPLY)
done
fi
@@ -48,8 +68,9 @@
expref=${~origpref}
[[ $origpref == (|*/). ]] && rltrim=.
curpref=${${expref%$rltrim}:-./}
- canpref=$(readlink -qf $curpref)
- if [[ $? -eq 0 ]]; then
+ if zstat $curpref >&/dev/null; then
+ _canonical_paths_get_canonical_path $curpref
+ canpref=$REPLY
[[ $curpref == */ && $canpref == *[^/] ]] && canpref+=/
canpref+=$rltrim
[[ $expref == *[^/] && $canpref == */ ]] && origpref+=/
--
Peter Stephenson <pws@xxxxxxx> Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070
Messages sorted by:
Reverse Date,
Date,
Thread,
Author