all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Daniel Pittman <daniel@rimspace.net>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: emacs-pretest-bug@gnu.org, 1135@emacsbugs.donarmstrong.com
Subject: bug#1135: 23.0.60; (expand-file-name ".." "/") produces surprising results
Date: Sat, 11 Oct 2008 10:54:57 +1100	[thread overview]
Message-ID: <873aj457la.fsf@rimspace.net> (raw)
In-Reply-To: <jwv8wswmkp3.fsf-monnier+emacsbugreports@gnu.org> (Stefan Monnier's message of "Fri, 10 Oct 2008 13:37:25 -0400")

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	other threads:[~2008-10-10 23:54 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <87ljwo1kt9.fsf@cyd.mit.edu>
2008-10-10  3:41 ` bug#1135: 23.0.60; (expand-file-name ".." "/") produces surprising results Daniel Pittman
2008-10-10 17:37   ` Stefan Monnier
2008-10-10 23:54     ` Daniel Pittman [this message]
2008-10-16 18:10   ` bug#1135: marked as done (23.0.60; (expand-file-name ".." "/") produces surprising results) Emacs bug Tracking System

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=873aj457la.fsf@rimspace.net \
    --to=daniel@rimspace.net \
    --cc=1135@emacsbugs.donarmstrong.com \
    --cc=emacs-pretest-bug@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.