[EMAIL PROTECTED] writes: > $ rm -rf /tmp/foo > $ touch bar > $ install -Dv bar /tmp/foo/a/b/c/d > install: creating directory `__libc_start_main'
Thanks for reporting that. I see now that my patch was too tricky for its own good. I installed this simpler patch instead. (CC'ing to gnulib since some of it affects gnulib.) 2006-10-06 Paul Eggert <[EMAIL PROTECTED]> Fix bug reported today by Mike Frysinger: mkdir -pv is logging the wrong file name in some cases. Lars Wendler reported a bug in my original fix. * lib/mkancesdirs.c (mkancesdirs): Pass to MAKE_DIR both the full file name (relative to the original working directory) and the file name component (relative to the temporary working directory). All callers changed. * lib/mkancesdirs.h (mkancesdirs): Adjust prototype to match. * lib/mkdir-p.c (make_dir_parents): Likewise. * lib/mkdir-p.h (make_dir_parents): Likewise. * src/install.c (make_ancestor): New arg COMPONENT. * src/mkdir.c (make_ancestor): Likewise. * tests/install/basic-1: Check for install -Dv bug. * tests/mkdir/Makefile.am (TESTS): Add p-v. * tests/mkdir/p-v: New file, to test this bug. Index: lib/mkancesdirs.c =================================================================== RCS file: /cvsroot/gnulib/gnulib/lib/mkancesdirs.c,v retrieving revision 1.3 diff -p -u -r1.3 mkancesdirs.c --- lib/mkancesdirs.c 16 Sep 2006 19:58:25 -0000 1.3 +++ lib/mkancesdirs.c 7 Oct 2006 07:06:17 -0000 @@ -42,12 +42,12 @@ savewd. Create any ancestor directories that don't already exist, by - invoking MAKE_DIR (COMPONENT, MAKE_DIR_ARG). This function should - return 0 if successful and the resulting directory is readable, 1 - if successful but the resulting directory might not be readable, -1 - (setting errno) otherwise. If COMPONENT is relative, it is - relative to the temporary working directory, which may differ from - *WD. + invoking MAKE_DIR (FILE, COMPONENT, MAKE_DIR_ARG). This function + should return 0 if successful and the resulting directory is + readable, 1 if successful but the resulting directory might not be + readable, -1 (setting errno) otherwise. If COMPONENT is relative, + it is relative to the temporary working directory, which may differ + from *WD. Ordinarily MAKE_DIR is executed with the working directory changed to reflect the already-made prefix, and mkancesdirs returns with @@ -66,7 +66,7 @@ ptrdiff_t mkancesdirs (char *file, struct savewd *wd, - int (*make_dir) (char const *, void *), + int (*make_dir) (char const *, char const *, void *), void *make_dir_arg) { /* Address of the previous directory separator that follows an @@ -114,7 +114,7 @@ mkancesdirs (char *file, struct savewd * && component[0] == '.' && component[1] == '.') made_dir = false; else - switch (make_dir (component, make_dir_arg)) + switch (make_dir (file, component, make_dir_arg)) { case -1: make_dir_errno = errno; Index: lib/mkancesdirs.h =================================================================== RCS file: /cvsroot/gnulib/gnulib/lib/mkancesdirs.h,v retrieving revision 1.2 diff -p -u -r1.2 mkancesdirs.h --- lib/mkancesdirs.h 16 Sep 2006 19:58:25 -0000 1.2 +++ lib/mkancesdirs.h 7 Oct 2006 07:06:17 -0000 @@ -1,4 +1,4 @@ #include <stddef.h> struct savewd; ptrdiff_t mkancesdirs (char *, struct savewd *, - int (*) (char const *, void *), void *); + int (*) (char const *, char const *, void *), void *); Index: lib/mkdir-p.c =================================================================== RCS file: /cvsroot/gnulib/gnulib/lib/mkdir-p.c,v retrieving revision 1.9 diff -p -u -r1.9 mkdir-p.c --- lib/mkdir-p.c 28 Sep 2006 12:18:58 -0000 1.9 +++ lib/mkdir-p.c 7 Oct 2006 07:06:17 -0000 @@ -43,7 +43,7 @@ WD is the working directory, as in savewd.c. If MAKE_ANCESTOR is not null, create any ancestor directories that - don't already exist, by invoking MAKE_ANCESTOR (ANCESTOR, OPTIONS). + don't already exist, by invoking MAKE_ANCESTOR (DIR, ANCESTOR, OPTIONS). This function should return zero if successful, -1 (setting errno) otherwise. In this case, DIR may be modified by storing '\0' bytes into it, to access the ancestor directories, and this modification @@ -83,7 +83,7 @@ bool make_dir_parents (char *dir, struct savewd *wd, - int (*make_ancestor) (char const *, void *), + int (*make_ancestor) (char const *, char const *, void *), void *options, mode_t mode, void (*announce) (char const *, void *), Index: lib/mkdir-p.h =================================================================== RCS file: /cvsroot/gnulib/gnulib/lib/mkdir-p.h,v retrieving revision 1.4 diff -p -u -r1.4 mkdir-p.h --- lib/mkdir-p.h 16 Sep 2006 19:58:25 -0000 1.4 +++ lib/mkdir-p.h 7 Oct 2006 07:06:17 -0000 @@ -25,7 +25,8 @@ struct savewd; bool make_dir_parents (char *dir, struct savewd *wd, - int (*make_ancestor) (char const *, void *), + int (*make_ancestor) (char const *, char const *, + void *), void *options, mode_t mode, void (*announce) (char const *, void *), Index: src/install.c =================================================================== RCS file: /fetish/cu/src/install.c,v retrieving revision 1.195 diff -p -u -r1.195 install.c --- src/install.c 16 Sep 2006 20:03:56 -0000 1.195 +++ src/install.c 7 Oct 2006 07:05:38 -0000 @@ -79,7 +79,8 @@ static bool install_file_in_file (const static void get_ids (void); static void strip (char const *name); static void announce_mkdir (char const *dir, void *options); -static int make_ancestor (char const *dir, void *options); +static int make_ancestor (char const *dir, char const *component, + void *options); void usage (int status); /* The name this program was run with, for error messages. */ @@ -629,11 +630,13 @@ announce_mkdir (char const *dir, void *o error (0, 0, _("creating directory %s"), quote (dir)); } -/* Make ancestor directory DIR, with options OPTIONS. */ +/* Make ancestor directory DIR, whose last file name component is + COMPONENT, with options OPTIONS. Assume the working directory is + COMPONENT's parent. */ static int -make_ancestor (char const *dir, void *options) +make_ancestor (char const *dir, char const *component, void *options) { - int r = mkdir (dir, DEFAULT_MODE); + int r = mkdir (component, DEFAULT_MODE); if (r == 0) announce_mkdir (dir, options); return r; Index: src/mkdir.c =================================================================== RCS file: /fetish/cu/src/mkdir.c,v retrieving revision 1.106 diff -p -u -r1.106 mkdir.c --- src/mkdir.c 16 Sep 2006 20:03:56 -0000 1.106 +++ src/mkdir.c 7 Oct 2006 07:05:39 -0000 @@ -81,7 +81,7 @@ struct mkdir_options { /* Function to make an ancestor, or NULL if ancestors should not be made. */ - int (*make_ancestor_function) (char const *, void *); + int (*make_ancestor_function) (char const *, char const *, void *); /* Mode for ancestor directory. */ mode_t ancestor_mode; @@ -105,15 +105,16 @@ announce_mkdir (char const *dir, void *o error (0, 0, o->created_directory_format, quote (dir)); } -/* Make ancestor directory DIR, with options OPTIONS. Return 0 if - successful and the resulting directory is readable, 1 if successful - but the resulting directory is not readable, -1 (setting errno) - otherwise. */ +/* Make ancestor directory DIR, whose last component is COMPONENT, + with options OPTIONS. Assume the working directory is COMPONENT's + parent. Return 0 if successful and the resulting directory is + readable, 1 if successful but the resulting directory is not + readable, -1 (setting errno) otherwise. */ static int -make_ancestor (char const *dir, void *options) +make_ancestor (char const *dir, char const *component, void *options) { struct mkdir_options const *o = options; - int r = mkdir (dir, o->ancestor_mode); + int r = mkdir (component, o->ancestor_mode); if (r == 0) { r = ! (o->ancestor_mode & S_IRUSR); Index: tests/install/basic-1 =================================================================== RCS file: /fetish/cu/tests/install/basic-1,v retrieving revision 1.22 diff -p -u -r1.22 basic-1 --- tests/install/basic-1 5 Oct 2006 08:43:25 -0000 1.22 +++ tests/install/basic-1 7 Oct 2006 07:05:39 -0000 @@ -24,6 +24,14 @@ if test "$VERBOSE" = yes; then ginstall --version fi +# Make sure we get English translations. +LANGUAGE=C +export LANGUAGE +LC_ALL=C +export LC_ALL +LANG=C +export LANG + . $srcdir/../envvar-check PRIV_CHECK_ARG=require-non-root . $srcdir/../priv-check @@ -130,4 +138,14 @@ test -d xx/zz || fail=1 test -d sub1/d/rel/a || fail=1 test -d sub1/d/rel/b || fail=1 +touch file || fail=1 +ginstall -Dv file sub3/a/b/c/file >out 2>&1 || fail=1 +diff - out <<\EOF || fail=1 +ginstall: creating directory `sub3' +ginstall: creating directory `sub3/a' +ginstall: creating directory `sub3/a/b' +ginstall: creating directory `sub3/a/b/c' +`file' -> `sub3/a/b/c/file' +EOF + (exit $fail); exit $fail Index: tests/mkdir/Makefile.am =================================================================== RCS file: /fetish/cu/tests/mkdir/Makefile.am,v retrieving revision 1.16 retrieving revision 1.17 diff -p -u -r1.16 -r1.17 --- tests/mkdir/Makefile.am 3 Jul 2006 12:55:33 -0000 1.16 +++ tests/mkdir/Makefile.am 6 Oct 2006 20:44:32 -0000 1.17 @@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS = 1.1 gnits TESTS = \ p-thru-slink \ - p-3 p-1 p-2 special-1 perm parents t-slash p-slashdot + p-3 p-1 p-2 p-v special-1 perm parents t-slash p-slashdot EXTRA_DIST = $(TESTS) TESTS_ENVIRONMENT = \ srcdir=$(srcdir) \ --- /dev/null 2005-09-24 22:00:15.000000000 -0700 +++ tests/mkdir/p-v 2006-10-06 13:42:26.000000000 -0700 @@ -0,0 +1,56 @@ +#!/bin/sh +# Test mkdir -pv. + +# Copyright (C) 2006 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +if test "$VERBOSE" = yes; then + set -x + mkdir --version +fi + +# Make sure we get English translations. +LANGUAGE=C +export LANGUAGE +LC_ALL=C +export LC_ALL +LANG=C +export LANG + +pwd=`pwd` +t0=`echo "$0"|sed 's,.*/,,'`.tmp; tmp=$t0/$$ +trap 'status=$?; cd $pwd; rm -rf $t0 && exit $status' 0 +trap '(exit $?); exit $?' 1 2 13 15 + +framework_failure=0 +mkdir -p $tmp || framework_failure=1 +cd $tmp || framework_failure=1 + +if test $framework_failure = 1; then + echo "$0: failure in testing framework" 1>&2 + (exit 1); exit 1 +fi + +mkdir -pv foo/a/b/c/d 2>out || exit + +diff - out <<\EOF +mkdir: created directory `foo' +mkdir: created directory `foo/a' +mkdir: created directory `foo/a/b' +mkdir: created directory `foo/a/b/c' +mkdir: created directory `foo/a/b/c/d' +EOF