2005-10-24 Dmitry V. Levin * lib/mkdir-p.c (make_dir_parents): When creating final component of the file name, do not fail when it already exists. * tests/install/d-slashdot: New test, for "install -d" failure. * tests/install/Makefile.am (TESTS): Add d-slashdot. * tests/mkdir/p-slashdot: New test, for "mkdir -p" failure. * tests/mkdir/Makefile.am (TESTS): Add p-slashdot. diff -upk.orig coreutils-5.92.orig/lib/mkdir-p.c coreutils-5.92/lib/mkdir-p.c --- coreutils-5.92.orig/lib/mkdir-p.c 2005-10-13 20:32:19 +0000 +++ coreutils-5.92/lib/mkdir-p.c 2005-10-24 11:18:38 +0000 @@ -118,6 +118,8 @@ make_dir_parents (char const *arg, bool re_protect; /* Should leading dirs be unwritable? */ char *basename_dir; char *dir; + bool dir_known_to_exist; + int mkdir_errno; /* Temporarily relax umask in case it's overly restrictive. */ mode_t oldmask = umask (0); @@ -171,9 +173,6 @@ make_dir_parents (char const *arg, while (true) { - bool dir_known_to_exist; - int mkdir_errno; - /* slash points to the leftmost unprocessed component of dir. */ basename_dir = slash; @@ -264,9 +263,17 @@ make_dir_parents (char const *arg, Create the final component of the file name. */ if (retval) { - if (mkdir (basename_dir, mode) != 0) + dir_known_to_exist = (mkdir (basename_dir, mode) == 0); + mkdir_errno = errno; + + if (!dir_known_to_exist) + dir_known_to_exist = (stat (basename_dir, &stats) == 0 + && S_ISDIR (stats.st_mode)); + + if (!dir_known_to_exist) { - error (0, errno, _("cannot create directory %s"), quote (dir)); + error (0, mkdir_errno, _("cannot create directory %s"), + quote (dir)); retval = false; } else diff -upk.orig coreutils-5.92.orig/tests/install/d-slashdot coreutils-5.92/tests/install/d-slashdot --- coreutils-5.92.orig/tests/install/d-slashdot 1970-01-01 00:00:00 +0000 +++ coreutils-5.92/tests/install/d-slashdot 2005-10-24 11:38:37 +0000 @@ -0,0 +1,31 @@ +#!/bin/sh +# Ensure that ginstall -d works with arguments specified with a trailing "/.". + +if test "$VERBOSE" = yes; then + set -x + install --version +fi + +pwd=`pwd` +tmp=`echo "$0"|sed 's,.*/,,'`.tmp +trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0 +trap '(exit $?); exit' 1 2 13 15 + +framework_failure=0 +mkdir $tmp || framework_failure=1 +cd $tmp || framework_failure=1 + +if test $framework_failure = 1; then + echo 'failure in testing framework' + (exit 1); exit 1 +fi + +fail=0 + +ginstall -d d1/. || fail=1 +test -d d1 || fail=1 + +ginstall -d d2/.. || fail=1 +test -d d2 || fail=1 + +(exit $fail); exit $fail diff -upk.orig coreutils-5.92.orig/tests/install/Makefile.am coreutils-5.92/tests/install/Makefile.am --- coreutils-5.92.orig/tests/install/Makefile.am 2005-04-21 00:29:50 +0000 +++ coreutils-5.92/tests/install/Makefile.am 2005-10-24 11:35:43 +0000 @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in -*-Makefile-*-. AUTOMAKE_OPTIONS = 1.3 gnits -TESTS = trap basic-1 create-leading +TESTS = trap basic-1 create-leading d-slashdot EXTRA_DIST = $(TESTS) TESTS_ENVIRONMENT = \ EXEEXT='$(EXEEXT)' \ diff -upk.orig coreutils-5.92.orig/tests/mkdir/Makefile.am coreutils-5.92/tests/mkdir/Makefile.am --- coreutils-5.92.orig/tests/mkdir/Makefile.am 2005-06-14 07:59:59 +0000 +++ coreutils-5.92/tests/mkdir/Makefile.am 2005-10-24 11:32:30 +0000 @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in -*-Makefile-*-. AUTOMAKE_OPTIONS = 1.1 gnits -TESTS = p-3 p-1 p-2 special-1 perm parents t-slash +TESTS = p-3 p-1 p-2 special-1 perm parents t-slash p-slashdot EXTRA_DIST = $(TESTS) TESTS_ENVIRONMENT = \ srcdir=$(srcdir) \ diff -upk.orig coreutils-5.92.orig/tests/mkdir/p-slashdot coreutils-5.92/tests/mkdir/p-slashdot --- coreutils-5.92.orig/tests/mkdir/p-slashdot 1970-01-01 00:00:00 +0000 +++ coreutils-5.92/tests/mkdir/p-slashdot 2005-10-24 11:36:09 +0000 @@ -0,0 +1,31 @@ +#!/bin/sh +# Ensure that mkdir -p works with arguments specified with a trailing "/.". + +if test "$VERBOSE" = yes; then + set -x + mkdir --version +fi + +pwd=`pwd` +tmp=`echo "$0"|sed 's,.*/,,'`.tmp +trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0 +trap '(exit $?); exit' 1 2 13 15 + +framework_failure=0 +mkdir $tmp || framework_failure=1 +cd $tmp || framework_failure=1 + +if test $framework_failure = 1; then + echo 'failure in testing framework' + (exit 1); exit 1 +fi + +fail=0 + +mkdir -p d1/. || fail=1 +test -d d1 || fail=1 + +mkdir -p d2/.. || fail=1 +test -d d2 || fail=1 + +(exit $fail); exit $fail