coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/1] copy: allow --attributes-only to work with directories


From: Vladimir Panteleev
Subject: [PATCH 1/1] copy: allow --attributes-only to work with directories
Date: Wed, 7 Feb 2018 08:53:41 +0000

* src/copy.c: Add logic for data_copy_required on directories.
* tests/cp/dir-attr-only.sh: New test.
---
 src/copy.c                | 64 ++++++++++++++++++++++++++---------------------
 tests/cp/dir-attr-only.sh | 32 ++++++++++++++++++++++++
 2 files changed, 67 insertions(+), 29 deletions(-)
 create mode 100755 tests/cp/dir-attr-only.sh

diff --git a/src/copy.c b/src/copy.c
index e050d4199..f633da808 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1893,7 +1893,7 @@ copy_internal (char const *src_name, char const *dst_name,
 
       src_mode = src_sb.st_mode;
 
-      if (S_ISDIR (src_mode) && !x->recursive)
+      if (S_ISDIR (src_mode) && !x->recursive && x->data_copy_required)
         {
           error (0, 0, ! x->install_mode /* cp */
                  ? _("-r not specified; omitting directory %s")
@@ -2518,24 +2518,27 @@ copy_internal (char const *src_name, char const 
*dst_name,
              for writing the directory's contents. Check if these
              permissions are there.  */
 
-          if (lstat (dst_name, &dst_sb) != 0)
+          if (x->recursive)
             {
-              error (0, errno, _("cannot stat %s"), quoteaf (dst_name));
-              goto un_backup;
-            }
-          else if ((dst_sb.st_mode & S_IRWXU) != S_IRWXU)
-            {
-              /* Make the new directory searchable and writable.  */
-
-              dst_mode = dst_sb.st_mode;
-              restore_dst_mode = true;
-
-              if (lchmod (dst_name, dst_mode | S_IRWXU) != 0)
+              if (lstat (dst_name, &dst_sb) != 0)
                 {
-                  error (0, errno, _("setting permissions for %s"),
-                         quoteaf (dst_name));
+                  error (0, errno, _("cannot stat %s"), quoteaf (dst_name));
                   goto un_backup;
                 }
+              else if ((dst_sb.st_mode & S_IRWXU) != S_IRWXU)
+                {
+                  /* Make the new directory searchable and writable.  */
+
+                  dst_mode = dst_sb.st_mode;
+                  restore_dst_mode = true;
+
+                  if (lchmod (dst_name, dst_mode | S_IRWXU) != 0)
+                    {
+                      error (0, errno, _("setting permissions for %s"),
+                             quoteaf (dst_name));
+                      goto un_backup;
+                    }
+                }
             }
 
           /* Record the created directory's inode and device numbers into
@@ -2572,21 +2575,24 @@ copy_internal (char const *src_name, char const 
*dst_name,
               }
         }
 
-      /* Decide whether to copy the contents of the directory.  */
-      if (x->one_file_system && parent && parent->st_dev != src_sb.st_dev)
-        {
-          /* Here, we are crossing a file system boundary and cp's -x option
-             is in effect: so don't copy the contents of this directory. */
-        }
-      else
+      if (x->recursive)
         {
-          /* Copy the contents of the directory.  Don't just return if
-             this fails -- otherwise, the failure to read a single file
-             in a source directory would cause the containing destination
-             directory not to have owner/perms set properly.  */
-          delayed_ok = copy_dir (src_name, dst_name, new_dst, &src_sb, dir, x,
-                                 first_dir_created_per_command_line_arg,
-                                 copy_into_self);
+          /* Decide whether to copy the contents of the directory.  */
+          if (x->one_file_system && parent && parent->st_dev != src_sb.st_dev)
+            {
+              /* Here, we are crossing a file system boundary and cp's -x 
option
+                 is in effect: so don't copy the contents of this directory. */
+            }
+          else
+            {
+              /* Copy the contents of the directory.  Don't just return if
+                 this fails -- otherwise, the failure to read a single file
+                 in a source directory would cause the containing destination
+                 directory not to have owner/perms set properly.  */
+              delayed_ok = copy_dir (src_name, dst_name, new_dst, &src_sb, dir,
+                                     x, first_dir_created_per_command_line_arg,
+                                     copy_into_self);
+            }
         }
     }
   else if (x->symbolic_link)
diff --git a/tests/cp/dir-attr-only.sh b/tests/cp/dir-attr-only.sh
new file mode 100755
index 000000000..bd03d47f2
--- /dev/null
+++ b/tests/cp/dir-attr-only.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+# Test --attributes-only with directories
+
+# Copyright 2012-2018 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 3 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, see <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ cp
+
+mkdir d e || framework_failure_
+
+chmod 700 d || framework_failure_
+chmod 0 e || framework_failure_
+
+cp -T --attributes-only --preserve=mode d e || fail=1
+
+expected_perms=$(stat --format=%a e)
+test $expected_perms = 700 || fail=1
+
+Exit $fail
-- 
2.16.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]