bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#1135: 23.0.60; (expand-file-name ".." "/") produces surprising resul


From: Daniel Pittman
Subject: bug#1135: 23.0.60; (expand-file-name ".." "/") produces surprising results
Date: Sat, 11 Oct 2008 10:54:57 +1100
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/23.0.60 (gnu/linux)

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> I use some code that uses (setq dir (expand-file-name ".." dir)) to
>> walk up a directory tree to the root.
>
> Was there any particular reason not to use:
>
>    (setq dir (directory-file-name (file-name-directory dir)))

While applying `file-name-directory' to a directory works fine and makes
sense, it never occurred to me to consider that.

>> I debugged this down to the unexpected (to me) behaviour of
>
>>     (expand-file-name ".." "/")
>>     => "/.."
>
>>     (expand-file-name ".." "/..")
>>     => "/"
>
> That's a bit problematic, indeed.  The reason for the first behavior is
> because there exist(ed) special file systems that were accessible under
> /.. (IIRC machines at cs.cmu.edu around early 90s, maybe late 80s, had
> such a distributed filesystem that allowed access to other machines via
> /../<hostname>/..., maybe there were other such things).  The second is
> there because nobody knows what /../.. is supposed to mean in such
> a context: if /.. is a mounted filesystem, then /../.. should get you
> back to /; then again if /.. is really the Root, then /../.. should just
> be /..; or maybe there's a hierarchy of roots so /../.. should just stay
> as /../..?

*nod*  I would certainly (myself) encourage this to be documented, or to
be added as a machine dependent extension to the code on those
particular systems.

I knew about a whole bunch of odd file-name handling on various systems
through the decades, but this is a new one to me.  I can imagine it
would be rather a shock to, for example, people used only to Windows and
Linux systems. :)


For what it is worth, since I hit this only via Tramp I initially
assumed that it was a bug in the implementation of `expand-file-name' in
that code, probably through an optimization that didn't quite work out.

>> This was causing the code, which checked if the current and previous
>> result of (expand-file-name ".." dir) were the same, to go into an
>> infinite loop cycling between those two values...
>
> The more I see such problems the more I think that such code should
> check (> (length before) (length after)).  At least, that should
> *guarantee* termination, no matter how weird expand-file-name can
> behave.

*nod*  I had assumed that while things like Tramp and, possibly, other
random platforms meant my code couldn't assume that simply walking up to
`(equal dir (expand-file-name "/"))' would assure termination, a
back-and-forth loop would not occur.

Anyway, thank you for both the advice on a better (and terminating)
approach, and your interest in the fault.  


My suggestion would be the documentation approach; in my Emacs the help
reads, with my extension following:

    expand-file-name is a built-in function in `C source code'.

    (expand-file-name name &optional default-directory)

    Convert filename name to absolute, and canonicalize it.
    Second arg default-directory is directory to start with if name is relative
    (does not start with slash or tilde); if default-directory is nil or 
missing,
    the current buffer's value of `default-directory' is used.
    File name components that are `.' are removed, and
    so are file name components followed by `..', along with the `..' itself;
    note that these simplifications are done without checking the resulting
    file names in the file system.
    An initial `~/' expands to your home directory.
    An initial `~USER/' expands to USER's home directory.
    See also the function `substitute-in-file-name'.

In some cases `expand-file-name' can return surprising results, such as
expanding `..' against `/', which correctly returns `/..'; in most cases
`file-name-directory' and `directory-file-name' are more appropriate for
walking filesystem trees.


Regards,
        Daniel






reply via email to

[Prev in Thread] Current Thread [Next in Thread]