Ben Rudiak-Gould Benjamin.Rudiak-Gould at cl.cam.ac.uk
Thu Jan 27 10:40:44 EST 2005

Robert Dockins wrote:

>This is true in a sense, but I think making the distinction explicit is
>helpful for a number of the operations we want to do.  For example, what
>is the parent of the relative path "."?  Answer is "..".  What is the
>parent of "/." on unix?  Answer is "/.".

While true, I don't see what this has to do with the choice between
PathStart and Maybe PathRoot. The types are isomorphic; we can detect
and simplify the /.. case either way.

>Relative paths can refer to different things in the filesystem depending
>on process-local state, whereas absolute paths will always refer to the
>same thing (until the filesystem changes, or if you do something
>esoteric like "chroot").  Relative paths are really "path fragments."

Okay, this is a good point. There is a difference between a path
fragment (i.e. a path with no starting point specified) and a path which
explicitly starts in the process's default directory. You're right that
the pathname "foo/bar" can only sensibly be put in the former category.

The problem is that where Posix has just

Absolute
|
Relative

Win32 has

Absolute
/     \
/       \
Rel:Abs   Abs:Rel
\       /
\     /
Relative

where "Rel:Abs" means something like "\foo" and "Abs:Rel" means
something like "c:foo". I never realized before what a nightmare it is
to handle this sensibly. The problem is that pathAppend "c:\foo\bar"
"d:." == "d:.", but pathAppend "d:\foo\bar" "d:." == "d:\foo\bar\.".
Therefore, pathAppend "\foo\bar" "d:." doesn't have a value at all,
since its meaning depends on the current drive in a way that can't be
expressed in the Win32 path syntax.

Because of the above problem, I'm willing to treat path fragments
(Relative in both lattices) as a special case. But we still need to be
able to round-trip rel:abs and abs:rel pathnames, meaning that the
PathRoot type won't necessarily be a genuine cwd-independent root any more.

>There are a few others.  I took a look at MSDN earlier and was
>astounded.

Is there an MSDN page that actually gives a grammar, or at least a
taxonomy, of Win32 pathnames? That would be useful.

Incidentally, NT doesn't do a perfect job of parsing its own pathnames.
While experimenting I managed to create a file named "..", different
from the directory ".." (both show up in the directory listing), which I
was subsequently unable to read or delete. The command was something
like "cat > ..:foo". I doubt that this behavior is by design.

>> > pathCleanup :: p -> p           -- remove .. and suchlike
>>
>>This can't be done safely except in a few special cases (e.g. "/.." ->
>>"/"). I'm not sure it should be here.
>
>More than you would think, if you follow the conventions of modern unix
>shells.

It's not a general convention even in the shell, just a peculiarity of
the cd builtin:

GNU bash, version 2.05b.0(1)-release (i386-pc-linux-gnu)
# mkdir /bar
# mkdir /bar/baz
# ln -s /bar/baz /foo
# echo /file > /file
# echo /bar/file > /bar/file
# cat /foo/../file
/bar/file
# ls /foo/..
baz  file
# cd /foo
# cat ../file
/bar/file

In the vast majority of cases it's not safe to collapse "/foo/.." to "/".

On reflection I think the function should be provided, but with a name
like pathCancel and a usage warning in the documentation. If it's not
provided people will write it themselves without realizing that it's unsafe.

-- Ben