]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
autom4te: correct error message when we can’t create autom4te.cache.
authorZack Weinberg <zackw@panix.com>
Mon, 21 Dec 2020 20:29:32 +0000 (15:29 -0500)
committerZack Weinberg <zackw@panix.com>
Wed, 23 Dec 2020 18:12:51 +0000 (13:12 -0500)
While testing something else, I noticed that autom4te may print a
nonsensical error message when it fails to create autom4te.cache,
because it checks again whether the directory already exists before
giving up, and this clobbers errno.

Instead of doing (the perl equivalent of)
    test -d $cache || mkdir $cache || test -d $cache
call mkdir unconditionally.  If it fails with an errno code other than
EEXIST, consider that a hard failure; if it fails with EEXIST, check
whether the thing that exists is in fact a directory.  (A symlink to
a directory qualifies; I wouldn’t be surprised if people are moving
autom4te.cache around with symlinks.)

Either way, if we fail, report strerror(errno) from the original
mkdir failure.  Also, print the current working directory as part
of the error message; this aids debugging when you’re working with a
big hairy nested tree.

* bin/autom4te.in: Don’t check whether autom4te.cache exists before
  attempting to create it.  Only stat autom4te.cache if mkdir fails
  with EEXIST, otherwise fail immediately.  Make sure to report the
  errno code from mkdir, not the subsequent stat (if any).  Report
  the current working directory as part of the error message.

* tests/tools.at: Verify that autom4te reports the actual reason when
  it fails to create autom4te.cache.  Verify that failure to create
  autom4te.cache because that name exists, but isn’t a directory,
  is detected.

bin/autom4te.in
tests/tools.at

index febcdeea8dea45cee2f23f858987fdcd40077c18..4c2b905c072f1bd0972a89dc5d1d0dc621fc6493 100644 (file)
@@ -1012,12 +1012,21 @@ if ($freeze)
     exit $exit_code;
   }
 
-# We need our cache directory.  Don't fail with parallel creation.
-if (! -d "$cache")
+# Ensure the cache directory exists.
+if (! mkdir ($cache, 0755))
   {
-    mkdir "$cache", 0755
-      or -d "$cache"
-      or fatal "cannot create $cache: $!";
+    # Snapshot $! immediately, the next few operations may clobber it.
+    my $eexist = $!{EEXIST};
+    my $errmsg = "$!";
+
+    # If mkdir failed with EEXIST, that means the *name* $cache
+    # already exists, but it might be the wrong kind of file.
+    if (! $eexist || ! -d $cache)
+      {
+        require Cwd;
+        my $cwd = Cwd::cwd();
+        fatal "cannot create $cache in $cwd: $errmsg";
+      }
   }
 
 # Open the index for update, and lock it.  autom4te handles several
index d32ad362a1e84534b7d901f077896469ed64ce52..49710202025caf68b51d96f9082591f3302ecc44 100644 (file)
@@ -1534,20 +1534,36 @@ end-language: "Autoconf-without-aclocal-m4"
 # A failed redirection may cause a status of 2 with FreeBSD sh.
 AT_CHECK([(: > sub/some-file) || exit 1 && exit 77], 1, [ignore], [ignore])
 
-# Failure to create cache directory.
+# Failure to create cache directory due to access permissions.
 AT_CHECK_AUTOCONF([], [1], [ignore], [stderr])
 AT_CHECK([grep 'cannot create .*autom4te.cache' stderr], [0], [ignore])
+AT_CHECK([grep ': Permission denied' stderr], [0], [ignore])
 AT_CHECK([test -f configure], [1])
 
+# Failure to create cache directory due to something else in the way.
 chmod u+w sub
+: > sub/autom4te.cache
+AT_CHECK_AUTOCONF([], [1], [ignore], [stderr])
+AT_CHECK([grep 'cannot create .*autom4te.cache' stderr], [0], [ignore])
+AT_CHECK([grep ': File exists' stderr], [0], [ignore])
+AT_CHECK([test -f configure], [1])
+
+# This time, creation should succeed.
+rm -f sub/autom4te.cache
 AT_CHECK_AUTOCONF
+AT_CHECK([test -d sub/autom4te.cache])
 
 rm -f configure sub/autom4te.cache/*
 chmod a-w sub/autom4te.cache
 
 # Failure to create a file in the cache directory.
 AT_CHECK_AUTOCONF([], [1], [ignore], [stderr])
-AT_CHECK([grep 'cannot open.*autom4te.cache' stderr], [0], [ignore])
+AT_CHECK([grep 'cannot open .*autom4te.cache' stderr], [0], [ignore])
+AT_CHECK([test -f configure], [1])
+
+# If the directory already exists, that should be fine.
+chmod u+w sub/autom4te.cache
+AT_CHECK_AUTOCONF
 
 AT_CLEANUP