Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
SUSE:SLE-12-SP3:GA
coreutils-testsuite.1874
coreutils-install-allow-options-D-and-t-to-be-u...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File coreutils-install-allow-options-D-and-t-to-be-used-together.patch of Package coreutils-testsuite.1874
From f89eb921ba9549324173b6ff293ea36f23971144 Mon Sep 17 00:00:00 2001 From: Bernhard Voelker <mail@bernhard-voelker.de> Date: Wed, 11 Jun 2014 11:28:03 +0200 Subject: [PATCH] install: allow options -D and -t to be used together Git-commit: 15d092f94a3abd4ba328a9c9ac4531320ec381ec Patch-mainline: v8.23 * 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. --- NEWS | 4 ++++ doc/coreutils.texi | 6 +++--- src/install.c | 49 ++++++++++++++++++++++++++++++++---------------- tests/install/basic-1.sh | 27 ++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 19 deletions(-) diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 9c2b79c..a3e2419 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -9017,8 +9017,8 @@ Ignored; for compatibility with old Unix versions of @command{install}. @opindex -D Create any missing parent directories of @var{dest}, then copy @var{source} to @var{dest}. -This option is ignored if a destination directory is specified -via @option{--target-directory=DIR}. +Explicitly specifying the @option{--target-directory=@var{dir}} will similarly +ensure the presence of that hierarchy before copying @var{source} arguments. @item -d @itemx --directory diff --git a/src/install.c b/src/install.c index 7076655..5ddde67 100644 --- a/src/install.c +++ b/src/install.c @@ -704,8 +704,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)); @@ -735,8 +734,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, @@ -745,11 +754,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; } @@ -849,16 +863,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': @@ -913,6 +917,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); @@ -1018,7 +1034,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; } } diff --git a/tests/install/basic-1.sh b/tests/install/basic-1.sh index 2e23164..423361c 100755 --- a/tests/install/basic-1.sh +++ b/tests/install/basic-1.sh @@ -112,4 +112,31 @@ ginstall: creating directory 'sub3/a/b/c' 'file' -> 'sub3/a/b/c/file' EOF +# Test -D together with -t (available since coreutils >= 8.23). +# Let ginstall create a completely new destination hierarchy. +ginstall -t sub4/a/b/c -Dv file >out 2>&1 || fail=1 +compare - out <<\EOF || fail=1 +ginstall: creating directory 'sub4' +ginstall: creating directory 'sub4/a' +ginstall: creating directory 'sub4/a/b' +ginstall: creating directory 'sub4/a/b/c' +'file' -> 'sub4/a/b/c/file' +EOF + +# Ensure that -D with an already existing file as -t's option argument fails. +touch sub4/file_exists || framework_failure_ +ginstall -t sub4/file_exists -Dv file >out 2>&1 && fail=1 +compare - out <<\EOF || fail=1 +ginstall: target 'sub4/file_exists' is not a directory +EOF + +# Ensure that -D with an already existing directory for -t's option argument +# succeeds. +mkdir sub4/dir_exists || framework_failure_ +touch sub4/dir_exists || framework_failure_ +ginstall -t sub4/dir_exists -Dv file >out 2>&1 || fail=1 +compare - out <<\EOF || fail=1 +'file' -> 'sub4/dir_exists/file' +EOF + Exit $fail -- 2.10.2 --- coreutils-8.22/NEWS 2017-02-10 13:38:21.819948944 +0100 +++ coreutils-8.22/NEWS 2017-02-10 13:34:18.852519151 +0100 @@ -16,6 +16,9 @@ suppress duplicate remote file systems. [suppression was introduced in coreutils-8.21] +** Improvements + + install now allows the combination of the -D and -t options. Noteworthy changes in release 8.22 (2013-12-13) [stable]
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor