Skip to content

Commit

Permalink
MKDIR_P now falls back on mkdir -p
Browse files Browse the repository at this point in the history
* lib/autoconf/programs.m4 (AC_PROG_MKDIR_P):
Fall back on mkdir -p instead of on a relative path to
install-sh, as the latter now seems to be more of a problem
than the former.
  • Loading branch information
eggert committed Oct 12, 2022
1 parent 85c0db3 commit d081ac3
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 61 deletions.
13 changes: 12 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ GNU Autoconf NEWS - User visible changes.
This matters only for uses that, contrary to the documentation
and despite warnings, use m4_divert with numbered diversions.


** New features

*** New macro AC_YEAR2038 for 64-bit time_t.
Expand Down Expand Up @@ -57,6 +56,18 @@ GNU Autoconf NEWS - User visible changes.
and ‘false’ work anyway. This is for compatibility with C 2023 and
with C++.

*** AC_PROG_MKDIR_P now falls back on plain 'mkdir -p'.

When AC_PROG_MKDIR_P cannot find a mkdir implementation that is
known to lack race condition bugs, it now falls back on 'mkdir -p'
instead of falling back on a relative path to install-sh, as the
relative paths now seem to be a more important problem than the
problems of ancient mkdir implementations with race condition bugs.
See <https://savannah.gnu.org/support/?110740>. The only ancient
mkdir still in common use is Solaris 10 /usr/bin/mkdir, and for that
platform AC_PROG_MKDIR_P falls back on /opt/sfw/bin/mkdir which
should work.

* Noteworthy changes in release 2.71 (2021-01-28) [stable]

** Bug fixes, including:
Expand Down
56 changes: 14 additions & 42 deletions doc/autoconf.texi
Original file line number Diff line number Diff line change
Expand Up @@ -2178,7 +2178,7 @@ without any backslash-newlines.
@prindex @command{install-sh}

Some Autoconf macros require auxiliary scripts. @code{AC_PROG_INSTALL}
and @code{AC_PROG_@w{MKDIR_P}} (@pxref{Particular Programs}) require a
(@pxref{Particular Programs}) requires a
fallback implementation of @command{install} called @file{install-sh},
and the @code{AC_CANONICAL} macros (@pxref{Manual Configuration})
require the system-identification scripts @file{config.sub} and
Expand Down Expand Up @@ -4272,16 +4272,10 @@ 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}.
An @file{install-sh} file that predates Autoconf 2.60 or Automake 1.10
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.
This macro uses the equivalent of the @samp{mkdir -p} command. Ancient
versions of @command{mkdir} are vulnerable to race conditions, so if you
want to support parallel installs from different packages into the same
directory you should use a non-ancient @command{mkdir}.

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
Expand All @@ -4291,11 +4285,6 @@ but @code{MKDIR_P} supports the @option{-m} option, e.g., a makefile
might invoke @code{$(MKDIR_P) -m 0 dir} to create an inaccessible
directory, and conversely a makefile should use @code{$(MKDIR_P) --
$(FOO)} if @var{FOO} might yield a value that begins with @samp{-}.
Finally, @code{AS_MKDIR_P} does not check for race condition
vulnerability, whereas @code{AC_PROG_MKDIR_P} does.

@samp{@@MKDIR_P@@} is special, as its value may vary for different
configuration files.

The result of the test can be overridden by setting the variable
@code{MKDIR_P} or the cache variable @code{ac_cv_path_mkdir}.
Expand Down Expand Up @@ -14208,15 +14197,8 @@ use @code{AC_REQUIRE} directly or indirectly (@pxref{Prerequisite Macros}).
@defmac AS_MKDIR_P (@var{file-name})
@asindex{MKDIR_P}
Make the directory @var{file-name}, including intervening directories
as necessary. This is equivalent to @samp{mkdir -p -- @var{file-name}},
except that it is portable to older versions of @command{mkdir} that
lack support for the @option{-p} option or for the @option{--}
delimiter (@pxref{mkdir, , Limitations of Usual Tools}). Also,
@code{AS_MKDIR_P}
succeeds if @var{file-name} is a symbolic link to an existing directory,
even though Posix is unclear whether @samp{mkdir -p} should
succeed in that case. If creation of @var{file-name} fails, exit the
script.
as necessary. This is equivalent to @samp{mkdir -p -- @var{file-name}}.
If creation of @var{file-name} fails, exit the script.

Also see the @code{AC_PROG_MKDIR_P} macro (@pxref{Particular Programs}).
@end defmac
Expand Down Expand Up @@ -19739,11 +19721,6 @@ through @code{uniq}.
@c ------------------
@prindex @command{mkdir}
@cindex Making directories
No @command{mkdir} option is portable to older systems. Instead of
@samp{mkdir -p @var{file-name}}, you should use
@code{AS_MKDIR_P(@var{file-name})} (@pxref{Programming in M4sh})
or @code{AC_PROG_MKDIR_P} (@pxref{Particular Programs}).

Combining the @option{-m} and @option{-p} options, as in @samp{mkdir -m
go-w -p @var{dir}}, often leads to trouble. FreeBSD
@command{mkdir} incorrectly attempts to change the permissions of
Expand All @@ -19753,26 +19730,21 @@ any newly-created parents of @var{dir}.

Posix does not clearly specify whether @samp{mkdir -p foo}
should succeed when @file{foo} is a symbolic link to an already-existing
directory. The GNU Core Utilities 5.1.0 @command{mkdir}
succeeds, but Solaris @command{mkdir} fails.
directory. The GNU @command{mkdir}
succeeds, but Solaris 10 @command{mkdir} fails.

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. The GNU Core
Utilities (@samp{fileutils} version 4.1), FreeBSD 5.0,
NetBSD 2.0.2, and OpenBSD 2.4 are known to be
race-free when two processes invoke @code{mkdir -p} simultaneously, but
earlier versions are vulnerable. Solaris @command{mkdir} is still
vulnerable as of Solaris 10, and other traditional Unix systems are
and fail with a @code{File exists} diagnostic. Solaris 10 @command{mkdir}
is vulnerable, and other traditional Unix systems are
probably vulnerable too. This possible race is harmful in parallel
builds when several Make 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 vulnerable.

@code{install-sh -d} as a safe replacement, for example by setting
@samp{MKDIR_P='/path/to/install-sh -d'} in the environment of
@command{configure}, assuming the package distributes @file{install-sh}.

@item @command{mkfifo}
@itemx @command{mknod}
Expand Down
28 changes: 10 additions & 18 deletions lib/autoconf/programs.m4
Original file line number Diff line number Diff line change
Expand Up @@ -653,36 +653,30 @@ AC_SUBST(INSTALL_DATA)dnl
# Do not use -m 0755 and let people choose whatever they expect by
# setting umask.
#
# We cannot accept any implementation of 'mkdir' that recognizes '-p'.
# Some implementations (such as Solaris 8's) are vulnerable to race conditions:
# Some implementations (such as Solaris 10's) are vulnerable to race conditions:
# if a parallel make tries to run 'mkdir -p a/b' and 'mkdir -p a/c'
# 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 known race-free implementations.
# one can create it and the other will error out. Users of these
# implementations should install and use GNU mkdir instead;
# on Solaris 10, this is /opt/sfw/bin/mkdir.
#
# Automake used to define mkdir_p as 'mkdir -p .', in order to
# allow $(mkdir_p) to be used without argument. As in
# $(mkdir_p) $(somedir)
# where $(somedir) is conditionally defined. However we don't do
# that for MKDIR_P.
# 1. before we restricted the check to GNU mkdir, 'mkdir -p .' was
# reported to fail in read-only directories. The system where this
# happened has been forgotten.
# 2. in practice we call $(MKDIR_P) on directories such as
# * in practice we call $(MKDIR_P) on directories such as
# $(MKDIR_P) "$(DESTDIR)$(somedir)"
# and we don't want to create $(DESTDIR) if $(somedir) is empty.
# To support the latter case, we have to write
# test -z "$(somedir)" || $(MKDIR_P) "$(DESTDIR)$(somedir)"
# so $(MKDIR_P) always has an argument.
# We will have better chances of detecting a missing test if
# $(MKDIR_P) complains about missing arguments.
# 3. $(MKDIR_P) is named after 'mkdir -p' and we don't expect this
# * $(MKDIR_P) is named after 'mkdir -p' and we don't expect this
# to accept no argument.
# 4. having something like 'mkdir .' in the output is unsightly.
# * having something like 'mkdir .' in the output is unsightly.
#
# On NextStep and OpenStep, the 'mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create.
AN_MAKEVAR([MKDIR_P], [AC_PROG_MKDIR_P])
AC_DEFUN_ONCE([AC_PROG_MKDIR_P],
[AC_REQUIRE_AUX_FILE([install-sh])dnl
Expand All @@ -706,11 +700,9 @@ if test -z "$MKDIR_P"; then
if test ${ac_cv_path_mkdir+y}; 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.
MKDIR_P="$ac_install_sh -d"
# As a last resort, use plain mkdir -p,
# in the hope it doesn't have the bugs of ancient mkdir.
MKDIR_P='mkdir -p'
fi
fi
dnl status.m4 does special magic for MKDIR_P instead of AC_SUBST,
Expand Down

0 comments on commit d081ac3

Please sign in to comment.