diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | src/install.c | 58 | ||||
-rw-r--r-- | src/mkdir.c | 23 | ||||
-rwxr-xr-x | tests/install/basic-1 | 18 |
4 files changed, 55 insertions, 55 deletions
@@ -2,14 +2,9 @@ Fix bug reported today by Mike Frysinger: mkdir -pv is logging the wrong file name in some cases. - * src/install.c (struct install_options): New type. - (install_file_in_file_parents, main): - Use it instead of struct cp_options. - (process_dir): Remember the full name. - (announce_mkdir, make_ancestor): Use the full name in announcements. - * src/mkdir.c (struct mkdir_options): Add full_name member. - (make_ancestor): Use the full name in announcements. - (process_dir): Remember the full name. + * 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. diff --git a/src/install.c b/src/install.c index aabbafaf0..1ccc7749c 100644 --- a/src/install.c +++ b/src/install.c @@ -66,22 +66,12 @@ /* Number of bytes of a file to copy at a time. */ #define READ_SIZE (32 * 1024) -/* Options passed to subsidiary functions. */ -struct install_options -{ - /* Full name of file being installed. */ - char const *full_name; - - /* Options for cp-related code. */ - struct cp_options cp; -}; - static bool change_timestamps (struct stat const *from_sb, char const *to); static bool change_attributes (char const *name); static bool copy_file (const char *from, const char *to, const struct cp_options *x); static bool install_file_in_file_parents (char const *from, char *to, - struct install_options *x); + struct cp_options *x); static bool install_file_in_dir (const char *from, const char *to_dir, const struct cp_options *x); static bool install_file_in_file (const char *from, const char *to, @@ -89,7 +79,8 @@ static bool install_file_in_file (const char *from, const char *to, 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. */ @@ -208,8 +199,6 @@ target_directory_operand (char const *file) static int process_dir (char *dir, struct savewd *wd, void *options) { - struct install_options *o = options; - o->full_name = dir; return (make_dir_parents (dir, wd, make_ancestor, options, dir_mode, announce_mkdir, @@ -228,7 +217,7 @@ main (int argc, char **argv) char *backup_suffix_string; char *version_control_string = NULL; bool mkdir_and_install = false; - struct install_options x; + struct cp_options x; char const *target_directory = NULL; bool no_target_directory = false; int n_files; @@ -242,7 +231,7 @@ main (int argc, char **argv) atexit (close_stdout); - cp_option_init (&x.cp); + cp_option_init (&x); owner_name = NULL; group_name = NULL; @@ -280,7 +269,7 @@ main (int argc, char **argv) mkdir_and_install = true; break; case 'v': - x.cp.verbose = true; + x.verbose = true; break; case 'g': group_name = optarg; @@ -292,7 +281,7 @@ main (int argc, char **argv) owner_name = optarg; break; case 'p': - x.cp.preserve_timestamps = true; + x.preserve_timestamps = true; break; case 'S': make_backups = true; @@ -334,10 +323,10 @@ main (int argc, char **argv) if (backup_suffix_string) simple_backup_suffix = xstrdup (backup_suffix_string); - x.cp.backup_type = (make_backups - ? xget_version (_("backup type"), - version_control_string) - : no_backups); + x.backup_type = (make_backups + ? xget_version (_("backup type"), + version_control_string) + : no_backups); n_files = argc - optind; file = argv + optind; @@ -397,15 +386,15 @@ main (int argc, char **argv) { if (! (mkdir_and_install ? install_file_in_file_parents (file[0], file[1], &x) - : install_file_in_file (file[0], file[1], &x.cp))) + : install_file_in_file (file[0], file[1], &x))) exit_status = EXIT_FAILURE; } else { int i; - dest_info_init (&x.cp); + dest_info_init (&x); for (i = 0; i < n_files; i++) - if (! install_file_in_dir (file[i], target_directory, &x.cp)) + if (! install_file_in_dir (file[i], target_directory, &x)) exit_status = EXIT_FAILURE; } } @@ -418,7 +407,7 @@ main (int argc, char **argv) static bool install_file_in_file_parents (char const *from, char *to, - struct install_options *x) + struct cp_options *x) { bool save_working_directory = ! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to)); @@ -449,7 +438,7 @@ install_file_in_file_parents (char const *from, char *to, } } - return (status == EXIT_SUCCESS && install_file_in_file (from, to, &x->cp)); + return (status == EXIT_SUCCESS && install_file_in_file (from, to, x)); } /* Copy file FROM onto file TO and give TO the appropriate @@ -636,19 +625,20 @@ get_ids (void) static void announce_mkdir (char const *dir, void *options) { - struct install_options const *x = options; - if (x->cp.verbose) + struct cp_options const *x = options; + if (x->verbose) 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) { - struct install_options const *x = options; - int r = mkdir (dir, DEFAULT_MODE); + int r = mkdir (component, DEFAULT_MODE); if (r == 0) - announce_mkdir (x->full_name, options); + announce_mkdir (dir, options); return r; } diff --git a/src/mkdir.c b/src/mkdir.c index f8a0625a2..6fa0ac21d 100644 --- a/src/mkdir.c +++ b/src/mkdir.c @@ -79,12 +79,9 @@ Mandatory arguments to long options are mandatory for short options too.\n\ /* Options passed to subsidiary functions. */ struct mkdir_options { - /* Full name of directory that we are making. */ - char const *full_name; - /* 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; @@ -108,19 +105,20 @@ announce_mkdir (char const *dir, void *options) 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); - announce_mkdir (o->full_name, options); + announce_mkdir (dir, options); } return r; } @@ -129,8 +127,7 @@ make_ancestor (char const *dir, void *options) static int process_dir (char *dir, struct savewd *wd, void *options) { - struct mkdir_options *o = options; - o->full_name = dir; + struct mkdir_options const *o = options; return (make_dir_parents (dir, wd, o->make_ancestor_function, options, o->mode, announce_mkdir, o->mode_bits, (uid_t) -1, (gid_t) -1, true) diff --git a/tests/install/basic-1 b/tests/install/basic-1 index 55f0b511c..84a94343b 100755 --- a/tests/install/basic-1 +++ b/tests/install/basic-1 @@ -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 |