* m4/acl.m4 (gl_FUNC_ACL): Check if acl_get_file_at(),
acl_set_file_at(), acl_delete_def_file_at(), acl_extended_file_at() are
available.
* lib/acl-internal.h: Define HAVE_ACL_*_AT macros and shims for those
functions.
* lib/file-has-acl.c (fdfile_has_aclinfo): Use acl_extended_file_at()
when available.
* lib/get-permissions.c (get_permissions): Likewise for
acl_get_file_at().
* lib/set-permissions.c (set_acls): Likewise for acl_set_file_at() and
acl_delete_def_file_at().
---
lib/acl-internal.h | 28 ++++++++++++++++++++++++++++
lib/file-has-acl.c | 8 +++++++-
lib/get-permissions.c | 6 +++++-
lib/set-permissions.c | 18 +++++++++++++++---
m4/acl.m4 | 6 ++++--
5 files changed, 59 insertions(+), 7 deletions(-)
diff --git a/lib/acl-internal.h b/lib/acl-internal.h
index 36be1f657d..d4012ab4f6 100644
--- a/lib/acl-internal.h
+++ b/lib/acl-internal.h
@@ -25,6 +25,7 @@
#include "acl.h"
#include <stdlib.h>
+#include <fcntl.h>
/* All systems define the ACL related API in <sys/acl.h>. */
#if HAVE_SYS_ACL_H
@@ -83,6 +84,33 @@ _GL_INLINE_HEADER_BEGIN
# define acl_get_fd(fd) (NULL)
# endif
+/* Linux (libacl >= 2.4.0) */
+# ifdef HAVE_ACL_GET_FILE_AT
+/* acl_get_file_at takes four arguments. */
+# else
+# define HAVE_ACL_GET_FILE_AT false
+# undef acl_get_file_at
+# define acl_get_file_at(dirfd, path_p, at_flags, type) (NULL)
+# endif
+
+/* Linux (libacl >= 2.4.0) */
+# ifdef HAVE_ACL_SET_FILE_AT
+/* acl_set_file_at takes five arguments. */
+# else
+# define HAVE_ACL_SET_FILE_AT false
+# undef acl_set_file_at
+# define acl_set_file_at(dirfd, path_p, at_flags, type, acl) (NULL)
+# endif
+
+/* Linux (libacl >= 2.4.0) */
+# ifdef HAVE_ACL_DELETE_DEF_FILE_AT
+/* acl_delete_def_file_at takes three arguments. */
+# else
+# define HAVE_ACL_DELETE_DEF_FILE_AT false
+# undef acl_delete_def_file_at
+# define acl_delete_def_file_at(dirfd, path_p, at_flags) (NULL)
+# endif
+
/* POSIX 1003.1e (draft 17) */
# ifdef HAVE_ACL_SET_FD
/* acl_set_fd takes two arguments. */
diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
index 8b9bb0468f..7c125b3a84 100644
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -524,7 +524,13 @@ fdfile_has_aclinfo (MAYBE_UNUSED int fd,
/* Linux, FreeBSD, NetBSD >= 10, Mac OS X, Cygwin >= 2.5 */
int ret;
-# if HAVE_ACL_EXTENDED_FILE /* Linux */
+# if HAVE_ACL_EXTENDED_FILE_AT /* Linux (libacl >= 2.4.0) */
+ ret = (fd < 0
+ ? acl_extended_file_at (AT_FDCWD, name,
+ (flags & ACL_SYMLINK_FOLLOW)
+ ? 0 : AT_SYMLINK_NOFOLLOW)
+ : acl_extended_file_at (fd, "", AT_EMPTY_PATH));
+# elif HAVE_ACL_EXTENDED_FILE /* Linux (libacl < 2.4.0) */
/* On Linux, acl_extended_file is an optimized function: It only
makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for
ACL_TYPE_DEFAULT. */
diff --git a/lib/get-permissions.c b/lib/get-permissions.c
index 3d744c1cf6..8648e0bba5 100644
--- a/lib/get-permissions.c
+++ b/lib/get-permissions.c
@@ -55,7 +55,11 @@ get_permissions (_GL_UNUSED const char *name, _GL_UNUSED int
desc, mode_t mode,
if (S_ISDIR (mode))
{
- ctx->default_acl = acl_get_file (name, ACL_TYPE_DEFAULT);
+ if (HAVE_ACL_GET_FILE_AT && desc != -1)
+ ctx->default_acl = acl_get_file_at (desc, "", AT_EMPTY_PATH,
+ ACL_TYPE_DEFAULT);
+ else
+ ctx->default_acl = acl_get_file (name, ACL_TYPE_DEFAULT);
if (ctx->default_acl == NULL)
return -1;
}
diff --git a/lib/set-permissions.c b/lib/set-permissions.c
index e17a1e376d..cbe2b8369c 100644
--- a/lib/set-permissions.c
+++ b/lib/set-permissions.c
@@ -523,10 +523,22 @@ set_acls (struct permission_context *ctx, const char
*name, int desc,
{
if (! from_mode && ctx->default_acl &&
acl_default_nontrivial (ctx->default_acl))
- ret = acl_set_file (name, ACL_TYPE_DEFAULT,
- ctx->default_acl);
+ {
+ if (HAVE_ACL_SET_FILE_AT && desc != -1)
+ ret = acl_set_file_at (desc, "", AT_EMPTY_PATH,
+ ACL_TYPE_DEFAULT,
+ ctx->default_acl);
+ else
+ ret = acl_set_file (name, ACL_TYPE_DEFAULT,
+ ctx->default_acl);
+ }
else
- ret = acl_delete_def_file (name);
+ {
+ if (HAVE_ACL_DELETE_DEF_FILE_AT && desc != -1)
+ ret = acl_delete_def_file_at (desc, "", AT_EMPTY_PATH);
+ else
+ ret = acl_delete_def_file (name);
+ }
}
}
}
diff --git a/m4/acl.m4 b/m4/acl.m4
index 897882e140..bb87c56dc7 100644
--- a/m4/acl.m4
+++ b/m4/acl.m4
@@ -44,10 +44,12 @@ AC_DEFUN_ONCE([gl_FUNC_ACL],
LIB_ACL=$ac_cv_search_acl_get_file
fi
AC_CHECK_FUNCS(
- [acl_get_file acl_get_fd acl_set_file acl_set_fd \
+ [acl_get_file acl_get_file_at acl_get_fd \
+ acl_set_file acl_set_file_at acl_set_fd \
+ acl_delete_def_file acl_delete_def_file_at \
+ acl_extended_file acl_extended_file_at \
acl_get_link_np \
acl_free acl_from_mode acl_from_text \
- acl_delete_def_file acl_extended_file \
acl_delete_fd_np acl_delete_file_np \
acl_copy_ext_native acl_create_entry_np \
acl_to_short_text acl_free_text])
--
2.56.0