> From: "Mark D. Roth" <[EMAIL PROTECTED]>
> Date: Thu, 25 Jul 2002 08:25:39 -0500
> 
> The -P option isn't listed in the ksh docs under Solaris or AIX.
> Only OpenBSD seems to document this.

It's also documented in Bash 2.05b.  This feature was recently added
to Bash (presumably in response to POSIX 1003.1-2001 requiring it), so
newer versions of Bash will also have the problem.  I was using an
older Bash when I couldn't reproduce your original bug report.

> > So it appears to me that the "proper" fix is to try "cd -P DIR" first,
> > and to fall back on plain "cd DIR" if that doesn't work.
> 
> Sounds good.  Please see the attached patch.

On second thought, I don't think this is wise.  There is at least one
other instance of "cd $foo && pwd" in Autoconf and the Autoconf manual
talks about this idiom so that we can expect to see it in user code
too.  Even if we work around these two instances of the problem, other
instances will remain.

The underlying problem here is that $ac_top_srcdir is bogus, because
"cd $ac_top_srcdir" and "ls $ac_top_srcdir" refer to different
directories in POSIX 1003.1-2001 shells.  How about if we merely
detect this problem and ask the invoker of "configure" to fix it?
We should also document the problem, of course.

Here is a proposed patch along these lines.  The doc fix also clears
up some of the CDPATH confusion, and mentions the PWD problem.
(Arggh: two lines of code fixes, and 100 lines of documentation fixes
-- the story of my life.  :-)

2002-08-01  Paul Eggert  <[EMAIL PROTECTED]>

        * doc/autoconf.texi: Document the problem that "cd $foo" and
        "ls $foo" may refer to different directories in shells conforming
        to POSIX 1003.1-2001.  Simplify the description of $CDPATH.
        Explain $PWD.

        * lib/autoconf/general.m4 (_AC_INIT_SRCDIR): Reject source
        directories that can't be cd'ed into; this catches problems
        when POSIX 1003.1-2001 "cd" fails due to symlink spaghetti.

--- doc/autoconf.texi.~1.654.~  2002-07-31 12:41:29.000000000 -0700
+++ doc/autoconf.texi   2002-08-01 07:16:00.462961000 -0700
@@ -8961,50 +8961,18 @@ fallback value is needed.  We list these
 @table @code
 @item CDPATH
 @evindex CDPATH
-When this variable is set @code{cd} is verbose, so idioms such as
-@samp{abs=`cd $rel && pwd`} break because @code{abs} receives the path
-twice.
-
-@c FIXME: Which shells?  How do they behave?
-Setting @code{CDPATH} to the empty value is not enough for most shells.
-A simple path separator is enough except for @code{zsh}, which prefers a
-leading dot:
-
-@example
-zsh-3.1.6$ @kbd{mkdir foo && (CDPATH=: cd foo)}
-/tmp/foo
-zsh-3.1.6$ @kbd{(CDPATH=:. cd foo)}
-/tmp/foo
-zsh-3.1.6$ @kbd{(CDPATH=.: cd foo)}
-zsh-3.1.6$
-@end example
-
-@noindent
-(of course we could just @command{unset} @code{CDPATH}, since it also
-behaves properly if set to the empty string).
-
-Life wouldn't be so much fun if @command{bash} and @command{zsh} had the
-same behavior:
-
-@example
-bash-2.02$ @kbd{mkdir foo && (CDPATH=: cd foo)}
-bash-2.02$ @kbd{(CDPATH=:. cd foo)}
-bash-2.02$ @kbd{(CDPATH=.: cd foo)}
-/tmp/foo
-@end example
-
-Of course, even better style would be to use @code{PATH_SEPARATOR} instead
-of a @samp{:}.
-Therefore, a portable solution to neutralize @code{CDPATH} is
-
-@example
-CDPATH=$@{ZSH_VERSION+.@}$PATH_SEPARATOR
-@end example
-
-@noindent
-Note that since @command{zsh} supports @command{unset}, you may unset
-@code{CDPATH} using @code{PATH_SEPARATOR} as a fallback, see
-@ref{Limitations of Builtins}.
+When this variable is set it specifies a list of directories to search
+when invoking @code{cd} with a relative filename.  @acronym{POSIX}
+1003.1-2001 says that if a nonempty directory name from @code{CDPATH}
+is used successfully, @code{cd} prints the resulting absolute
+filename.  Unfortunately this output can break idioms like
+@samp{abs=`cd $rel && pwd`}.  Also, many shells do not conform to this
+part of @acronym{POSIX}; for example, @command{zsh} prints the result
+only if a directory name other than @file{.} was used.
+
+To work around the problem, Autoconf-generated scripts unset
+@code{CDPATH} if possible, and set @code{CDPATH} to
+@code{$PATH_SEPARATOR} if @command{unset} is not available.
 
 @item IFS
 @evindex IFS
@@ -9145,6 +9113,16 @@ When executing the command @samp{>foo}, 
 sets @code{NULLCMD} to @samp{cat}.  If you forgot to set @code{NULLCMD},
 your script might be suspended waiting for data on its standard input.
 
+@item PWD
+@acronym{POSIX} 1003.1-2001 requires that @command{cd} and
+@command{pwd} must update the @env{PWD} environment variable to point
+to the logical path to the current directory, but traditional shells
+do not support this.  This can cause confusion if one shell instance
+maintains @env{PWD} but a subsidiary and different shell does not know
+about @env{PWD} and executes @command{cd}; in this case @env{PWD} will
+point to the wrong directory.  Use @samp{`pwd`} rather than
+@samp{$PWD}.
+
 @item status
 @evindex status
 This variable is an alias to @samp{$?} for @code{zsh} (at least 3.1.6),
@@ -9206,6 +9184,27 @@ You can't use @command{!}, you'll have t
 The use of @samp{break 2}, etcetera, is safe.
 
 
+@item @command{cd} and @command{pwd}
+@c ---------------------------------
+@prindex @command{cd}
+@prindex @command{pwd}
+@acronym{POSIX} 1003.1-2001 requires that @command{cd} and
+@command{pwd} must support the @option{-L} and @option{-P} options,
+with @option{-L} being the default.  However, traditional shells do
+not support these options, and their @command{cd} and @command{pwd}
+commands have the @option{-P} behavior.
+
+Portable scripts should assume neither option is supported, and should
+assume neither behavior is the default.  This can be a bit tricky,
+since the @acronym{POSIX} default behavior means that, for example,
+@samp{ls ..} and @samp{cd ..} may refer to different directories.  It
+is safe to use @command{cd @var{dir}} if @var{dir} contains no
+@file{..} components.  Also, Autoconf-generated scripts check for this
+problem when computing variables like @code{ac_top_srcdir}
+(@pxref{Configuration Actions}), so it is safe to @command{cd} to
+these variables.
+
+
 @item @command{case}
 @c -----------------
 @prindex @command{case}
@@ -9431,6 +9430,10 @@ fi
 @end example
 
 
+@item @command{pwd}
+@c ----------------
+See @command{cd} above.
+
 @item @command{set}
 @c ----------------
 @prindex @command{set}
@@ -9654,7 +9657,7 @@ if (unset FOO) >/dev/null 2>&1; then
 else
   unset=false
 fi
-$unset CDPATH || CDPATH=:
+$unset CDPATH || CDPATH=$PATH_SEPARATOR
 @end example
 
 @xref{Special Shell Variables}, for some neutralizing values. Also, see
--- lib/autoconf/general.m4.~1.801.~    2002-07-19 00:43:27.000000000 -0700
+++ lib/autoconf/general.m4     2002-08-01 06:50:36.238961000 -0700
@@ -537,6 +537,8 @@ if test ! -r $srcdir/$ac_unique_file; th
     AC_MSG_ERROR([cannot find sources ($ac_unique_file) in $srcdir])
   fi
 fi
+(cd $srcdir && test -r $ac_unique_file) 2>/dev/null ||
+  AC_MSG_ERROR([sources are in $srcdir, but \`cd $srcdir' does not work])
 dnl Double slashes in pathnames in object file debugging info
 dnl mess up M-x gdb in Emacs.
 srcdir=`echo "$srcdir" | sed 's%\([[^\\/]]\)[[\\/]]*$%\1%'`

Reply via email to