* doc/autoconf.texi (Particular Programs, Limitations of Usual Tools):

Use better wording to talk about AC_PROG_MKDIR_P's thread-safety.
Don't use the term "thread-safe" to talk about mkdir race
conditions, since the problem is more a process than a thread
issue.  Problem reported by Stepan Kasal in:
http://lists.gnu.org/archive/html/autoconf-patches/2006-05/msg00088.html
* lib/autoconf/programs.m4 (AC_PROG_MKDIR_P): Use code that mimics
the test for 'install' more closely.  Look at MKDIR_P first.
Look in the PATH, and at /opt/sfw/bin.
Look for a 'gmkdir' program as well (Solaris 10 /opt/sfw/bin/gmkdir).
Don't bother to try mkdir -p, since we already check mkdir --version;
just look at the version number.  (There's no easy way to check
for race-free implementations.)
* tests/tools.at (autoconf: subdirectories): Adjust to above
changes, since MKDIR_P now might end in "/mkdir -p".
This commit is contained in:
Paul Eggert 2006-05-27 02:54:33 +00:00
parent 3b73b97c85
commit aa4a2459e6
4 changed files with 60 additions and 23 deletions

View File

@ -1,5 +1,21 @@
2006-05-26 Paul Eggert <eggert@cs.ucla.edu>
* doc/autoconf.texi (Particular Programs, Limitations of Usual Tools):
Use better wording to talk about AC_PROG_MKDIR_P's thread-safety.
Don't use the term "thread-safe" to talk about mkdir race
conditions, since the problem is more a process than a thread
issue. Problem reported by Stepan Kasal in:
http://lists.gnu.org/archive/html/autoconf-patches/2006-05/msg00088.html
* lib/autoconf/programs.m4 (AC_PROG_MKDIR_P): Use code that mimics
the test for 'install' more closely. Look at MKDIR_P first.
Look in the PATH, and at /opt/sfw/bin.
Look for a 'gmkdir' program as well (Solaris 10 /opt/sfw/bin/gmkdir).
Don't bother to try mkdir -p, since we already check mkdir --version;
just look at the version number. (There's no easy way to check
for race-free implementations.)
* tests/tools.at (autoconf: subdirectories): Adjust to above
changes, since MKDIR_P now might end in "/mkdir -p".
* doc/autoconf.texi (autoheader Invocation): Mention that the
first arg of AC_DEFINE_UNQUOTED must not be a literal.
Problem reported by Ben Pfaff in

View File

@ -3526,15 +3526,17 @@ not found in standard @command{install} programs, there is no reason to use
@ovindex MKDIR_P
Set output variable @code{MKDIR_P} to a program that ensures that for
each argument, a directory named by this argument exists, creating it
and its parent directories if needed. The program is checked to make
sure that it is thread-safe (@pxref{Limitations of Usual Tools}).
and its parent directories if needed, and without race conditions when
two instances of the program attempt to make the same directory at
nearly the same time.
This macro uses the @samp{mkdir -p} command if possible. Otherwise, it
falls back on invoking @command{install-sh} with the @option{-d} option,
so your package should
contain @file{install-sh} as described under @code{AC_PROG_INSTALL}.
A @file{install-sh} file that predates Autoconf 2.60 or Automake 1.10
won't be thread-safe, so if you want to support parallel installs from
is vulnerable to race conditions, so if you want to support parallel
installs from
different packages into the same directory you need to make sure you
have an up-to-date @file{install-sh}. In particular, be careful about
using @samp{autoreconf -if} if your Automake predates Automake 1.10.
@ -3543,9 +3545,10 @@ This macro is related to the @code{AS_MKDIR_P} macro (@pxref{Programming
in M4sh}), but it sets an output variable intended for use in other
files, whereas @code{AS_MKDIR_P} is intended for use in scripts like
@command{configure}. Also, @code{AS_MKDIR_P} does not accept options,
but if you are willing to assume Posix 1003.2-1992 or later, a
@code{MKDIR_P} can use the @option{-m} option, e.g., a makefile might
but @code{MKDIR_P} can use the @option{-m} option, e.g., a makefile might
invoke @code{$(MKDIR_P) -m 0 dir} to create an inaccessible directory.
Finally, @code{AS_MKDIR_P} does not check for race condition
vulnerability, whereas @code{AC_PROG_MKDIR_P} does.
@end defmac
@defmac AC_PROG_LEX
@ -13155,21 +13158,22 @@ should succeed when @file{foo} is a symbolic link to an already-existing
directory. The @acronym{GNU} Core Utilities 5.1.0 @command{mkdir}
succeeds, but Solaris @command{mkdir} fails.
Not all @code{mkdir -p} implementations are thread-safe. When it is not
and you call @code{mkdir -p a/b} and @code{mkdir -p a/c} at the same
time, both will detect that @file{a/} is missing, one will create
@file{a/}, then the other will try to create @file{a/} and die with a
@code{File exists} error. At least Solaris 10, Net@acronym{BSD} 1.6, and Open@acronym{BSD}
3.4 have an unsafe @code{mkdir -p}. The @acronym{GNU} Core Utilities
Traditional @code{mkdir -p} implementations suffer from race conditions.
For example, if you invoke @code{mkdir -p a/b} and @code{mkdir -p a/c}
at the same time, both processes might detect that @file{a} is missing,
one might create @file{a}, then the other might try to create @file{a}
and fail with a @code{File exists} diagnostic. At least Solaris 10,
Net@acronym{BSD} 1.6, and Open@acronym{BSD} 3.4 are vulnerable to race
conditions. The @acronym{GNU} Core Utilities
(since @samp{fileutils}
version 4.0c), Free@acronym{BSD} 5.0, and Net@acronym{BSD}-current are
version 4.1), Free@acronym{BSD} 5.0, and Net@acronym{BSD}-current are
known to have a
race-free @code{mkdir -p}. This possible race is harmful in parallel
builds when several @file{Makefile} rules call @code{mkdir -p} to
construct directories. You may use
@code{install-sh -d} as a safe replacement, provided this script is
recent enough; the copy shipped with Autoconf 2.60 and Automake 1.10 is
OK, but copies from older versions are not thread-safe either.
OK, but copies from older versions are vulnerable.
@item @command{mktemp}

View File

@ -627,7 +627,7 @@ AC_SUBST(INSTALL_DATA)dnl
# concurrently, both version can detect that a/ is missing, but only
# one can create it and the other will error out. Consequently we
# restrict ourselves to GNU mkdir (using the --version option ensures
# this.)
# this).
#
# Automake used to define mkdir_p as `mkdir -p .', in order to
# allow $(mkdir_p) to be used without argument. As in
@ -657,14 +657,31 @@ AC_DEFUN([AC_PROG_MKDIR_P],
[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
AC_REQUIRE_AUX_FILE([install-sh])dnl
AC_MSG_CHECKING([for a thread-safe mkdir -p])
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
MKDIR_P='mkdir -p'
else
for ac_d in ./-p ./--version
do
test -d $ac_d && rmdir $ac_d
done
MKDIR_P="$ac_install_sh -d"
if test -z "$MKDIR_P"; then
AC_CACHE_VAL([ac_cv_path_mkdir],
[_AS_PATH_WALK([$PATH$PATH_SEPARATOR/opt/sfw/bin],
[for ac_prog in mkdir gmkdir; do
for ac_exec_ext in '' $ac_executable_extensions; do
AS_EXECUTABLE_P(["$as_dir/$ac_prog$ac_exec_ext"]) || continue
case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
'mkdir (GNU coreutils) '* | \
'mkdir (coreutils) '* | \
'mkdir (fileutils) '4.1*)
ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
break 3;;
esac
done
done])])
if test "${ac_cv_path_mkdir+set}" = set; then
MKDIR_P="$ac_cv_path_mkdir -p"
else
# As a last resort, use the slow shell script. Don't cache a
# value for MKDIR_P within a source directory, because that will
# break other packages using the cache if that directory is
# removed, or if the value is a relative name.
test -d ./--version && rmdir ./--version
MKDIR_P="$ac_install_sh -d"
fi
fi
dnl Do special magic for MKDIR_P instead of AC_SUBST, to get
dnl relative names right.

View File

@ -347,7 +347,7 @@ AT_DATA([install-sh])
AT_CHECK_AUTOCONF
AT_CHECK_CONFIGURE
AT_CHECK([grep '/mkdir -p' sub/foo], 1)
AT_CHECK([[grep '^[^/].*/mkdir -p' sub/foo]], 1)
AT_CLEANUP