bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

logical paths (was: (no subject))


From: Bob Proulx
Subject: logical paths (was: (no subject))
Date: Sat, 9 Sep 2006 12:48:11 -0600
User-agent: Mutt/1.5.9i

Kartik K. Agaram wrote:
> Does POSIX require that coreutils commands use only physical path rather 
> than pwd to resolve relative paths? When pwd contains symlinks and we try 
> to operate upon relative paths that take us outside the symlink, the 
> effect is often jarring and non-intuitive.

Symlinks violate some principles of least surprise.  Therefore it is
no surprise that it is impossible to make all uses of symlinks
unsurprising.

Note that '.' and '..' are real directory entries.  They are not
pseudo entries as some appear to believe.  The shell covers them with
fake entires to change the behavior into logical paths when symlinks
are in use.  But that does not remove the underyling entries.  All
operating system kernel system calls use the real entries.  The fake
entries are an imaginary world created within the process model of
new-style, symlink-aware command shells.

Perl, for example, has no built-in knowledge of the shell's attempt to
create an imaginary world with logical paths.

  cd $HOME
  perl -le 'chdir("/tmp");print $ENV{PWD};'

Because of this any command executed as a child of that process cannot
trust that $PWD contains useful information.  They use the real
information provided by the operating system kernel filesystem
interface.  Perl was handy here but really I could use any program
that is not-the-command-shell as an example here.

The $PWD process environment variable is a construct created by the
command shell.  The chdir(2) operating system call does not modify any
process environment variable.  Keeping those two in sync is not an
operating system function and is never automatic.  It is only done as
a convention by some programs, notably the command shell but very few
others.  When mixing programs with different conventions one will
always be surprisingly different than expected from the other one.

> For example:
>    $ mkdir base_dir
>    $ cd base_dir
>    $ mkdir -p x/y
>    $ touch z
>    $ ln -s x/y f
>    $ cd f
>    $ cp ../z .
>    cp: cannot stat `../z': No such file or directory
>    $ ls ..
>    y

Thanks for the nice illustrative test case.

>    $ mkdir base_dir
>    $ cd base_dir
>    $ mkdir -p x/y
>    $ touch z
>    $ ln -s x/y f

At this point try this and remember the inode numbers.

  ls -ldogi . x x/y
  4618405 drwxr-xr-x  3 120 2006-09-09 12:20 .
  4618387 drwxr-xr-x  3  72 2006-09-09 12:20 x
  4618388 drwxr-xr-x  2  48 2006-09-09 12:20 x/y

>    $ cd f

At this point you are in the directory base_dir/x/y and not in f as
you think you are.  You got there by going through the f symlink and
you arrived at x/y.

Try this at that point and look at the inode numbers:

  ls -ldogi . ..
  4618388 drwxr-xr-x  2 48 2006-09-09 12:20 .
  4618387 drwxr-xr-x  3 72 2006-09-09 12:20 ..

Compare the inode numbers of the resulting files and directories with
the ones you saw before.  As you can see you are in the x/y directory
as '.' which matches the x/y inode listed previously.  The inode for
'..' matches the inode for x which is the parent directory.

Usually people go through this process of discovery and then decide
that the imaginary world created by the shell and layered on top of
the physical filesystem is the source of trouble and turn off logical
paths in the shell.  Then after using the system that way for a while
they miss the ability to "back out" of directories they arrived at
through a symlink by using "cd ..".  They then restore the default
shell behavior and live in the imaginary world again.  They have
learned that it is imaginary but also now know the real boundaries of
it and can work around the inconsistencies.

Bob




reply via email to

[Prev in Thread] Current Thread [Next in Thread]