[Haskell-cafe] File path programme
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
More information about the Haskell-Cafe
mailing list