diff options
| author | Paul Eggert | 2025-06-27 22:32:33 -0700 |
|---|---|---|
| committer | Paul Eggert | 2025-06-27 23:06:40 -0700 |
| commit | dbdf761187d7cccfad20a2899bab3dc77f379c3a (patch) | |
| tree | d4e160b187f6f56e27dad185dfdd4cb955c4ec80 /lib/qcopy-acl.c | |
| parent | 68100ca656ad76e937622a1a74b6ca185bc82e07 (diff) | |
| download | emacs-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.c | 29 |
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; |