aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2024-03-25 22:17:35 +0000
committerPádraig Brady <P@draigBrady.com>2024-03-25 22:27:15 +0000
commit30039cb23a2cbdc2ef92e7c474bd9d9ae404ffe0 (patch)
tree745a2014b9d7e1ee496b5bb2330e736cfe5ca0cc
parenttests: avoid false failure with partial locale info (diff)
downloadcoreutils-30039cb23a2cbdc2ef92e7c474bd9d9ae404ffe0.tar.gz
coreutils-30039cb23a2cbdc2ef92e7c474bd9d9ae404ffe0.zip
cp: with --no-preserve=mode ensure set-group-ID bits maintained on dirs
This issue was introduced in commit v8.19-145-g24ebca6 * src/copy.c (copy_internal): On systems that don't support ACLs, the fallback default chmod done on directories should maintain the set-group-ID, as that's generally auto-set by the system. * NEWS: Mention the fix. Reported by Bruno Haible on Alpine (with tests/cp/preserve-mode.sh)
-rw-r--r--NEWS5
-rw-r--r--src/copy.c3
2 files changed, 8 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index a6ec7c6ef..872723e4f 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,11 @@ GNU coreutils NEWS -*- outline -*-
to preserve ownership" when copying to GNU/Linux CIFS file systems.
They do this by working around some Linux CIFS bugs.
+ cp --no-preserve=mode will correctly maintain set-group-ID bits
+ for created directories. Previously on systems that didn't support ACLs,
+ cp would have reset the set-group-ID bit on created directories.
+ [bug introduced in coreutils-8.20]
+
join and uniq now support multi-byte characters better.
For example, 'join -tX' now works even if X is a multi-byte character,
and both programs now treat multi-byte characters like U+3000
diff --git a/src/copy.c b/src/copy.c
index 0318e0067..d584a27eb 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -3268,6 +3268,9 @@ skip:
{
int default_permissions = S_ISDIR (src_mode) || S_ISSOCK (src_mode)
? S_IRWXUGO : MODE_RW_UGO;
+ dst_mode = dst_sb.st_mode;
+ if (S_ISDIR (src_mode)) /* Keep set-group-ID for directories. */
+ default_permissions |= (dst_mode & S_ISGID);
if (set_acl (dst_name, -1, default_permissions & ~cached_umask ()) != 0)
return false;
}