]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
install: fix relative copies to absolute directory with -D
authorPádraig Brady <P@draigBrady.com>
Sat, 2 Jan 2016 18:38:37 +0000 (18:38 +0000)
committerPádraig Brady <P@draigBrady.com>
Sun, 3 Jan 2016 12:58:39 +0000 (12:58 +0000)
* src/install.c (mkancesdirs_safe_wd): Unconditionally
restore the current working directory when possibly called
multiple times (from install_file_in_dir()).
* tests/install/create-leading.sh: Add a test case.
* NEWS: Mention the fix.
Fixes http://bugs.gnu.org/21497

NEWS
src/install.c
tests/install/create-leading.sh

diff --git a/NEWS b/NEWS
index 863be187e1910d941e0f828d344b20ad2440ebcd..72d69b8b5f0c66161554277594f72630272ba972 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   cut --fields no longer outputs extraneous characters on some uClibc configs.
   [bug introduced in coreutils-6.11]
 
+  install -D again copies relative file names when absolute file names
+  are also specified along with an absolute destination directory name.
+  [bug introduced in coreutils-6.2]
+
   ls no longer prematurely wraps lines when printing short file names.
   [bug introduced in coreutils-5.1.0]
 
index 1bdb757a10d1f2e8d734e7d10e172db40da70942..6efb29e665ae173fdb69d9da85d36983227caa67 100644 (file)
@@ -704,14 +704,17 @@ install_file_in_file (const char *from, const char *to,
   return change_attributes (to);
 }
 
-/* Copy file FROM onto file TO, creating any missing parent directories of TO.
+/* Create any missing parent directories of TO,
+   while maintaining the current Working Directory.
    Return true if successful.  */
 
 static bool
-mkancesdirs_safe_wd (char const *from, char *to, struct cp_options *x)
+mkancesdirs_safe_wd (char const *from, char *to, struct cp_options *x,
+                     bool save_always)
 {
   bool save_working_directory =
-    ! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to));
+    save_always
+    || ! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to));
   int status = EXIT_SUCCESS;
 
   struct savewd wd;
@@ -749,7 +752,7 @@ 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)
+  return (mkancesdirs_safe_wd (from, to, (struct cp_options *)x, false)
           && install_file_in_file (from, to, x));
 }
 
@@ -766,7 +769,7 @@ install_file_in_dir (const char *from, const char *to_dir,
   bool ret = true;
 
   if (mkdir_and_install)
-    ret = mkancesdirs_safe_wd (from, to, (struct cp_options *)x);
+    ret = mkancesdirs_safe_wd (from, to, (struct cp_options *)x, true);
 
   ret = ret && install_file_in_file (from, to, x);
   free (to);
index 8971d5fde179a1a1128ce4c94c6f5a70d2ab3168..62f74f53f1163cd130a9e30e9da76c52eba0460e 100755 (executable)
@@ -24,7 +24,7 @@ print_ver_ ginstall
 
 
 file=file
-echo foo > $file
+echo foo > $file || framework_failure_
 
 # Before 4.0q, this would mistakenly create $file, not 'dest'
 # in no-dir1/no-dir2/.
@@ -32,4 +32,11 @@ ginstall -D $file no-dir1/no-dir2/dest || fail=1
 test -d no-dir1/no-dir2 || fail=1
 test -r no-dir1/no-dir2/dest || fail=1
 
+# Between 6.1 and 8.24, this would not copy $file
+# due to incorrectly modified working directory
+mkdir dir1 || framework_failure_
+touch dir1/file1 || framework_failure_
+ginstall -D $PWD/dir1/file1 $file -t $PWD/no-dir2/ || fail=1
+test -r no-dir2/$file && test -r no-dir2/file1 || fail=1
+
 Exit $fail