[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: mkdir inside symlink creates wrong directory with relative parent
From: |
Oldřich Jedlička |
Subject: |
Re: mkdir inside symlink creates wrong directory with relative parent |
Date: |
Mon, 13 Jun 2011 18:48:29 +0200 |
User-agent: |
KMail/1.13.7 (Linux/2.6.39-drm+; KDE/4.6.3; i686; ; ) |
Hi Loïc,
Dne pondělí 13 Červen 2011 18:40:36 Loïc Le Loarer napsal(a):
> Hi Oldřich,
>
> 2011/6/13 Oldřich Jedlička <address@hidden>
>
> > Dne pondělí 13 Červen 2011 16:51:54 Loïc Le Loarer napsal(a):
> > > This behavior is normal. The key here is the .. link in each directory,
> >
> > it
> >
> > > always points to the parent directory.
> > > For example, in your situation, the ".." in z is x, and it cannot be
> > > something else.
> > > Even if you access to z using the path x/y/z which use the symbolic
> > > link, and then use ".." link, you go to x, not y.
> > >
> > > You may have the impression that this is not true if you follow the
> > > same path using your shell, because the shell remember the fact that
> > > you use
> >
> > the
> >
> > > symbolic link and don't really use the ".." link. When you do "cd .."
> > > in the shell, it just removes the last element between / in the
> > > current
> >
> > path.
> >
> > Thanks for the explanation, that made the things much clearer. I
> > understand now why the "test -d ../../something" doesn't work under the
> > same conditions
> > (because the directory really doesn't exist for the program).
> >
> > But what you say is only part of the story. The script/program has the
> > full knowledge of the current working directory and it can do the same
> > trick with
> > the path traversing - remove the ".." in the same way as the shell would
> > do.
> > This is normal when you canonicalize the path - remove the ".." from the
> > path
> > and do not try to dereference. The key is that getcwd() returns really
> > the current working directory with symlinks unresolved - this is how the
> > shell sees it too.
>
> I have tested this last sentence, and as far as I can see, getcwd is
> returning resolved path. You can check this by doing a small program
> calling getcwd system call or by launching the command "stat
> /proc/self/cwd", it is doing the same.
>
> In order to know if the current dir which canonical name is "x/z" has been
> accessed using "cd x/z" or cd "x/y/z", the shell store the access path in
> PWD. Any script or program can use the PWD variable to mimic the shell
> behavior (see man get_current_dir_name), but it is not what is expected
> from mkdir or other basic commands.
>
> When you run the "mkdir ../../dir_xy" command, mkdir command is calling the
> mkdir system call with "../../dir_xy" argument, and each part of the
> relative part is resolved by the kernel, the first ".." is pointing to the
> "x" directory, not the "y". And that's it.
Ok, sorry for the noise. I did my testing earlier too and mixed up the
results. You are completely right, the getcwd() returns the resolved path.
Best regards,
Oldrich.
>
> Best regards
> Loïc
>
> > > I agree that it is a bit strange, but once you understand the fact that
> > > each directory contains a ".." link which points to one unique location
> > > and that when the path is interpreted by the kernel, it always follows
> > > those links, you understand how it works.
> >
> > Yes. it is strange and the program has the full knowledge to do the right
> > thing (TM) :-) So I think this can be fixed actually.
> >
> > Best regards,
> > Oldrich.
> >
> > > Best regards
> > > Loïc
> > >
> > > 2011/6/13 Oldřich Jedlička <address@hidden>
> > >
> > > > Hi all,
> > > >
> > > > I was trying to search for any description helping me understand in
> >
> > what
> >
> > > > I see, but actually I didn't find any, so I'm here. I discovered it
> > > > by using automake-1.11, because it uses relative paths a lot. So my
> > > > simplified testcase is as follows:
> > > >
> > > > Have a directory structure x/y and x/z/a. Have a symbolic link from
> >
> > x/y/z
> >
> > > > that points to x/z.
> > > >
> > > > mkdir -p x/y
> > > > mkdir -p x/z/a
> > > > ln -s ../z x/y/z
> > > >
> > > > Now go into x/y/z/a and try to create directory like that:
> > > > cd x/y/z/a
> > > > mkdir ../dir_xyz
> > > > mkdir ../../dir_xy
> > > > mkdir ../../../dir_x
> > > >
> > > > I would expet that there would be a directory like this:
> > > > x/dir_x
> > > > x/y/dir_xy
> > > > x/y/z/dir_xyz (x/z/dir_xyz)
> > > >
> > > > But the result is completely different:
> > > > dir_x
> > > > x/dir_xy
> > > > x/y/z/dir_xyz (x/z/dir_xyz)
> > > >
> > > > So when you want to create a directory in the parent structure from
> > > > within the symbolic link, you will fail in doing so, because the
> > > > symbolic link would be resolved during walking through parents, so
> > > > you can get to completely different tree while creating your
> > > > directory. It looks like a bug, because it is nowhere documented to
> > > > behave like that (and the behaviour is strange by itself).
> > > >
> > > > Verified on Debian 4.0/RedHat 5.4 with coreutils 5.97 and on Gentoo
> >
> > with
> >
> > > > coreutils 8.12.
> > > >
> > > > Regards,
> > > > Oldrich.