aboutsummaryrefslogtreecommitdiffstats
path: root/lib/qcopy-acl.c
diff options
context:
space:
mode:
authorPaul Eggert2025-06-27 22:32:33 -0700
committerPaul Eggert2025-06-27 23:06:40 -0700
commitdbdf761187d7cccfad20a2899bab3dc77f379c3a (patch)
treed4e160b187f6f56e27dad185dfdd4cb955c4ec80 /lib/qcopy-acl.c
parent68100ca656ad76e937622a1a74b6ca185bc82e07 (diff)
downloademacs-dbdf761187d7cccfad20a2899bab3dc77f379c3a.tar.gz
emacs-dbdf761187d7cccfad20a2899bab3dc77f379c3a.zip
Update from Gnulib by running admin/merge-gnulib
Diffstat (limited to 'lib/qcopy-acl.c')
-rw-r--r--lib/qcopy-acl.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/lib/qcopy-acl.c b/lib/qcopy-acl.c
index ad7966152aa..282f4b2d2a5 100644
--- a/lib/qcopy-acl.c
+++ b/lib/qcopy-acl.c
@@ -26,6 +26,7 @@
26#if USE_XATTR 26#if USE_XATTR
27 27
28# include <attr/libattr.h> 28# include <attr/libattr.h>
29# include <dirent.h>
29# include <string.h> 30# include <string.h>
30 31
31# if HAVE_LINUX_XATTR_H 32# if HAVE_LINUX_XATTR_H
@@ -61,6 +62,7 @@ is_attr_permissions (const char *name, struct error_context *ctx)
61 a valid file descriptor, use file descriptor operations, else use 62 a valid file descriptor, use file descriptor operations, else use
62 filename based operations on SRC_NAME. Likewise for DEST_DESC and 63 filename based operations on SRC_NAME. Likewise for DEST_DESC and
63 DST_NAME. 64 DST_NAME.
65 MODE should be the source file's st_mode.
64 If access control lists are not available, fchmod the target file to 66 If access control lists are not available, fchmod the target file to
65 MODE. Also sets the non-permission bits of the destination file 67 MODE. Also sets the non-permission bits of the destination file
66 (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set. 68 (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set.
@@ -86,10 +88,29 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name,
86 Functions attr_copy_* return 0 in case we copied something OR nothing 88 Functions attr_copy_* return 0 in case we copied something OR nothing
87 to copy */ 89 to copy */
88 if (ret == 0) 90 if (ret == 0)
89 ret = source_desc <= 0 || dest_desc <= 0 91 {
90 ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL) 92 ret = source_desc <= 0 || dest_desc <= 0
91 : attr_copy_fd (src_name, source_desc, dst_name, dest_desc, 93 ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL)
92 is_attr_permissions, NULL); 94 : attr_copy_fd (src_name, source_desc, dst_name, dest_desc,
95 is_attr_permissions, NULL);
96
97 /* Copying can fail with EOPNOTSUPP even when the source
98 permissions are trivial (Bug#78328). Don't report an error
99 in this case, as the chmod_or_fchmod suffices. */
100 if (ret < 0 && errno == EOPNOTSUPP)
101 {
102 /* fdfile_has_aclinfo cares only about DT_DIR, _GL_DT_NOTDIR,
103 and DT_LNK (but DT_LNK is not possible here),
104 so use _GL_DT_NOTDIR | DT_UNKNOWN for other file types. */
105 int flags = S_ISDIR (mode) ? DT_DIR : _GL_DT_NOTDIR | DT_UNKNOWN;
106
107 struct aclinfo ai;
108 if (!fdfile_has_aclinfo (source_desc, src_name, &ai, flags))
109 ret = 0;
110 aclinfo_free (&ai);
111 errno = EOPNOTSUPP;
112 }
113 }
93#else 114#else
94 /* no XATTR, so we proceed the old dusty way */ 115 /* no XATTR, so we proceed the old dusty way */
95 struct permission_context ctx; 116 struct permission_context ctx;