On 12/29/2012 07:38:24 AM, Felix Janda wrote:
On 12/29/12 at 03:53am, Rob Landley wrote:
> On 12/28/2012 03:24:17 PM, Felix Janda wrote:
> > Hi,
> >
> > the first patch adds the -L and -P options to pwd as specified by
> > POSIX.
> > The test script again uses stat. This time in order to get inode
> > numbers
> > of directories.
>
> For future reference adding the test in the same commit as the changes
> being tested is probably ok.

Ok.

> I've applied this patch, but am going to have to take a closer look at > it in the morning. (You added a -L option which... is a NOP? Huh, what > posix specifies here is kind of insane, there's no way to get the raw
> getcwd() output. The -L stuff is all about $PWD, and if that doesn't
> have a valid value it falls back to -P which does a realpath() on the
> data to strip symlinks...? I need to read this when I'm more awake,
> this standard is written for a system that stores state different than
> linux. The current working directory is a process attribute used
> directly by the vfs, it's not an environment variable...)
>
> I think the fix is to have -L _not_ be the default, and to have pwd
> return the raw getcwd() output when neither -L nor -P is specified...
> but that's a technical violation of posix...

POSIX says that "pwd" should behave the same as "pwd -L".

Posix seems to believe that the PWD environment variable is where the current directory is stored, which is not how Linux works. On linux, getcwd() returns one of two process-specific vfs attributes (chdir() sets "." and chroot() sets "/", and neither of those is an environment variable). If you "export PWD=/blah" that's not the same as calling chdir.

The current
"pwd -P" should behave the same way as the previous version of "pwd". It
just returns the getcwd() output.

Which is always an abspath. (I checked.)

I think what happens when you cd through a symlink is that the shell saves the path you descended into in $PWD, and then if you cd ".." it chops off the last path component instead of actually dereferencing .. (which would wind up somewhere other than the directory you came from).

So pwd -L is showing you the shell's view of things (using the $PWD environment variable), and pwd -P is showing you the realpath(). And what this basically means is "pwd is more or less a shell builtin", the standard just isn't EXPLAINING it clearly.

"pwd -L" does just check whether the
environment variable PWD is also a valid current working directory and
uses that instead of the output of getcwd() if that's the case.

Posix goes on at some length about no "." or ".." in it. I added logic to do this, but haven't checked it in yet.

So according to POSIX we have:

$ cd /tmp
$ ln -s . a
$ cd a
$ export PWD=/tmp/a
$ pwd
/tmp/a
$ pwd -P
/tmp

Actually at least bash seems to update PWD automatically so that the export
statement is unnecessary.

Indeed, bash updates PWD. (Unless you assign it to something else or unset it.)

It's maybe interesting to see what coreutils is doing. A fragment:

I never look at gnu source if I can avoid it. I sometimes run that stuff under strace, but mostly I just read the docs and work out tests.

  /* POSIX requires a default of -L, but most scripts expect -P.  */
  bool logical = (getenv ("POSIXLY_CORRECT") != NULL);

The rule is "Anything gnu does is a bad idea", and there are about as many exceptions to that as any other rule.

I think I understand _why_ -L is doing that, and the sanity checks are so if somebody tries to futz around with pwd to point somewhere else (or in a way the shell wouldn't have set it), we discard it and give the abspath instead for security-ish reasons. But the user friendly path may have $HOME be a symlink with the abspath on /mnt/vol2 or something, and we want to default to giving the PWD the user actually remembers.

The implementation of "pwd -L" could also use realpath instead of stat.

Stat's easier.

Taking a further look at POSIX I think that the option string should be
">0LP[-LP]" instead of ">0LP[!LP]".

I already made that change locally. :)

Felix

> Rob


Rob
_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to