On Fri, 28 May 2010 12:51:36 BST Ethan Grammatikidis <[email protected]>
wrote:
>
> On 27 May 2010, at 21:16, Bakul Shah wrote:
>
> > If BSD had
> > implemented ".." correctly (i.e. walk back up one level in
> > the given path), symlinks would have been more useful and
> > less surprising.
>
> This "correct" implementation of symlinks has never seemed right to
> me. Linux / Bash used to do it the "wrong" way as recently as 2001 if
> not more recently. I was much more comfortable with the "wrong" way,
> with symlinks just being a portal to another place entirely, and I
> wish I could pinpoint why. Having the path "faked" after following a
> symlink just feels badly wrong, and I wish I could put a semantic
> reason on it.
The kernel needs to implement this, not any user program.
When a single user program implements this and no others, it
is far more confusing!
By correct I meant maintaining the following:
<prefix>/<component>/..[/<suffix>] == <prefix>[/<suffix>]
/..[<suffix>] == /[<suffix>]
where <component> is not a literal ".." but can be any other
directory name or a symlink to anything (including "..").
This path string simplification is done left to right. Thus:
a/b/c/../../d == a/b/../d == a/d
The kernel needs to keep the full path to $PWD in order to
perform this simplification with relative paths. In effect
the kernel needs to strip out all .. from a given path before
interpreting it. And of course the kernel must check that
<component> names an existent directory.
Given these changes symlinks will behave in an unsurprising
way. Consider:
One user:
cd /tmp
mkdir -p a/b/c
ln -s a/b/c x
# Some other user at some other time:
cd /tmp/d
cd ..
/bin/pwd # this should show /tmp. At present it shows /tmp/a/b
ln -s d/../a e
cd e # this should succeed. At present it fails.
ln -s d/../../b f
cd f # if there is no /b this should fail. At present it succeeds.
In a later email you said "Maybe the fact that no-one seems
to like to keep the pwd in the kernel is argument enough". A
lack of popularity is not reason enough to reject this; one
must find/understand any technical reasons. The days of
having to fit a kernel in 64KB are long gone (which could've
been a pragmatic reason once). I can't see a logical argument
as to why the kernel shouldn't keep the full path. [Of
course, there may be one, but so far I have not seen it]
The only thing that can't be fixed is if the symlink target
disappears. This is the same as when (remote) target of your
bind (or mount) disappears.