diff options
author | Bernhard Voelker <mail@bernhard-voelker.de> | 2014-06-11 11:28:03 +0200 |
---|---|---|
committer | Bernhard Voelker <mail@bernhard-voelker.de> | 2014-06-11 15:48:39 +0200 |
commit | 15d092f94a3abd4ba328a9c9ac4531320ec381ec (patch) | |
tree | b8576eca8ea89b2286402fb1123da2130b2ba1a4 /src | |
parent | 696f539e62557984f303e790df9a463d41ebf22a (diff) | |
download | coreutils-15d092f94a3abd4ba328a9c9ac4531320ec381ec.tar.xz |
install: allow options -D and -t to be used together
* src/install.c (install_file_in_file_parents): Factor out the
creation of any parent directories into ...
(mkancesdirs_safe_wd): ... this new function.
(install_file_in_dir): Add the parameter 'mkdir_and_install', and
call the above new function if it evaluates to true.
(main): During parsing of the -t option, move the check whether
the target_directory exists down after the option parsing loop,
and do not complain about stat(optarg,...) failing if -D was given.
Pass 'mkdir_and_install' to install_file_in_dir().
* doc/coreutils.texi (install invocation): Remove the (false)
restriction that -D would be ignored together with -t. Instead,
clarify install's new bahavior.
Fix the node's reference in the top-level @direntry for consistency.
* src/install/basic-1.sh: Add tests for the now-allowed combination
of the -D and -t options.
* NEWS: Mention the improvement.
Diffstat (limited to 'src')
-rw-r--r-- | src/install.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/src/install.c b/src/install.c index c9bfdaef0..e7de260c6 100644 --- a/src/install.c +++ b/src/install.c @@ -706,8 +706,7 @@ install_file_in_file (const char *from, const char *to, Return true if successful. */ static bool -install_file_in_file_parents (char const *from, char *to, - struct cp_options *x) +mkancesdirs_safe_wd (char const *from, char *to, struct cp_options *x) { bool save_working_directory = ! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to)); @@ -737,8 +736,18 @@ install_file_in_file_parents (char const *from, char *to, return false; } } + return status == EXIT_SUCCESS; +} + +/* Copy file FROM onto file TO, creating any missing parent directories of TO. + Return true if successful. */ - return (status == EXIT_SUCCESS && install_file_in_file (from, to, x)); +static bool +install_file_in_file_parents (char const *from, char *to, + const struct cp_options *x) +{ + return (mkancesdirs_safe_wd (from, to, (struct cp_options *)x) + && install_file_in_file (from, to, x)); } /* Copy file FROM into directory TO_DIR, keeping its same name, @@ -747,11 +756,16 @@ install_file_in_file_parents (char const *from, char *to, static bool install_file_in_dir (const char *from, const char *to_dir, - const struct cp_options *x) + const struct cp_options *x, bool mkdir_and_install) { const char *from_base = last_component (from); char *to = file_name_concat (to_dir, from_base, NULL); - bool ret = install_file_in_file (from, to, x); + bool ret = true; + + if (mkdir_and_install) + ret = mkancesdirs_safe_wd (from, to, (struct cp_options *)x); + + ret = ret && install_file_in_file (from, to, x); free (to); return ret; } @@ -851,16 +865,6 @@ main (int argc, char **argv) if (target_directory) error (EXIT_FAILURE, 0, _("multiple target directories specified")); - else - { - struct stat st; - if (stat (optarg, &st) != 0) - error (EXIT_FAILURE, errno, _("failed to access %s"), - quote (optarg)); - if (! S_ISDIR (st.st_mode)) - error (EXIT_FAILURE, 0, _("target %s is not a directory"), - quote (optarg)); - } target_directory = optarg; break; case 'T': @@ -915,6 +919,18 @@ main (int argc, char **argv) error (EXIT_FAILURE, 0, _("target directory not allowed when installing a directory")); + if (target_directory) + { + struct stat st; + bool stat_success = stat (target_directory, &st) == 0 ? true : false; + if (! mkdir_and_install && ! stat_success) + error (EXIT_FAILURE, errno, _("failed to access %s"), + quote (target_directory)); + if (stat_success && ! S_ISDIR (st.st_mode)) + error (EXIT_FAILURE, 0, _("target %s is not a directory"), + quote (target_directory)); + } + if (backup_suffix_string) simple_backup_suffix = xstrdup (backup_suffix_string); @@ -1020,7 +1036,8 @@ main (int argc, char **argv) int i; dest_info_init (&x); for (i = 0; i < n_files; i++) - if (! install_file_in_dir (file[i], target_directory, &x)) + if (! install_file_in_dir (file[i], target_directory, &x, + mkdir_and_install)) exit_status = EXIT_FAILURE; } } |