Hi,

"mkdir -p" and "install -d" now fail when creating final component
of the file name when it already exists.
Proposed patch with testcase is attached.


-- 
ldv
2005-10-24  Dmitry V. Levin  <[EMAIL PROTECTED]>

        * 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

Attachment: pgpvEsEIBMU7G.pgp
Description: PGP signature

_______________________________________________
Bug-coreutils mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to