cvs commit: src/bin/sh main.c

Bruce Evans brde at optusnet.com.au
Tue Jun 12 03:46:38 UTC 2007


On Mon, 11 Jun 2007, John Baldwin wrote:

> On Saturday 04 February 2006 09:47:19 am Jens Schweikhardt wrote:
>> schweikh    2006-02-04 14:47:19 UTC
>>
>>   FreeBSD src repository
>>
>>   Modified files:
>>     bin/sh               main.c
>>   Log:
>>   Initialize PWD early on (don't expect it to be inherited from the
>>   environment or set it only when changing directories with cd).
>>
>>   PR:     standards/92640
>>
>>   Revision  Changes    Path
>>   1.27      +2 -0      src/bin/sh/main.c
>
> I just recently updated my system to contain this and it has broken all
> my /bin/sh shell scripts that use p4 which is highly annoying.  Specifically,
> I use the default freebsd layout of:
>
> /home -> /usr/home
>
> and
>
> /home/jhb as my homedir in the password file.  I also use tcsh as my login
> shell.  tcsh understands that it starts out in /home/jhb without issue, but
> exec'ing sh rewrites $PWD which in turn confuses p4 since it uses $PWD to
> figure out if a path is under the client path.  Can we at least have an
> option to turn this off?

I think it is a bug to not use $PWD from the environment if $PWD is
actually a valid pathname for the current directory.  This seems to
be what is used by bash and even by sh in 6.2 (6.2 is remarkably old,
so it doesn't have this Feb 2006 commit).  The example in the PR uses
env -i to clear $PWD from the environment, and when $PWD is in the
environment an exec'ed shell cannot do any better than use something
like realpath(3) to determine the current directory.  I suppose login
shells do better by setting $PWD literally to $HOME after chdir() to
$HOME.

POSIX.1 has the broken requirement that $PWD not contain any components of
type symlink.  From the draft7 2001 version (the current version has the
same wording):

%%%
1481            PWD                  Set by the shell to be an absolute pathname of the current working directory,
1482                                 containing no components of type symbolic link, no components that are dot,
1483                                 and no components that are dot-dot when the shell is initialized. If an
1484                                 application sets or unsets the value of PWD, the behaviors of the cd and pwd
1485                                 utilities are unspecified.
%%%

Here the scope of the clause "when the shell is initialized" is unclear.
This requires current directories under /home -> /usr/home to give
broken $PWD's since /home is a symlink.  This bug is not implemented
in "bash-2.05b --posix", csh, sh or tcsh in 6.2.  It is implemented
in sh in -current.  (This bug has only been in -current for 16 months
so it isn't in RELENG_6.)

'env -i tcsh -c "echo \$PWD"' works unsurprisingly in 6.2 -- tcsh initializes
$PWD, but must use something like realpath(3) so it resolves symlinks.

'env -i sh -c "echo \$PWD"' in 6.2 demonstrates the bug in the PR -- sh just
doesn't initialize $PWD.

I only completely tested a login shell with bash-1.4.7 and a 2006
version of sh that has the bug.  bash-1.4.7 seems to have the bug for
login shells only (it resolves symlinks in $HOME after login, giving
$PWD != $HOME, but doesn't resolve symlinks in $PWD after exec).
bash-2.0.5b or possibly ssh on FreeBSD cluster machines does the right
thing -- the /home -> /dumpster/home symlink is not resolved in $PWD
after ssh-login.

Bruce


More information about the cvs-src mailing list