summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/copy.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/copy.c b/src/copy.c
index 2be91a223..74bafd635 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -570,6 +570,7 @@ copy_internal (const char *src_path, const char *dst_path,
int rename_errno;
int delayed_fail;
int copied_as_regular = 0;
+ int ran_chown = 0;
if (move_mode && rename_succeeded)
*rename_succeeded = 0;
@@ -1086,6 +1087,7 @@ copy_internal (const char *src_path, const char *dst_path,
if (x->preserve_owner_and_group
&& (new_dst || !SAME_OWNER_AND_GROUP (src_sb, dst_sb)))
{
+ ran_chown = 1;
if (DO_CHOWN (chown, dst_path, src_sb.st_uid, src_sb.st_gid))
{
error (0, errno, _("preserving ownership for %s"), quote (dst_path));
@@ -1094,9 +1096,11 @@ copy_internal (const char *src_path, const char *dst_path,
}
}
- /* Permissions of newly-created regular files were set upon `open'
- in copy_reg. */
- if (new_dst && copied_as_regular)
+ /* Permissions of newly-created regular files were set upon `open' in
+ copy_reg. But don't return early if there were any special bits and
+ we had to run chown, because the chown must have reset those bits. */
+ if ((new_dst && copied_as_regular)
+ && !(ran_chown && (src_mode & ~S_IRWXUGO)))
return delayed_fail;
if ((x->preserve_chmod_bits || new_dst)