]> Savannah Git Hosting - gnulib.git/commitdiff
qcopy-acl: Optimize copying of ACLs by directly copying the attributes.
authorOndrej Valousek <ondrej.valousek.xm@renesas.com>
Wed, 4 Jan 2023 14:34:26 +0000 (15:34 +0100)
committerBruno Haible <bruno@clisp.org>
Thu, 12 Jan 2023 20:38:43 +0000 (21:38 +0100)
* lib/qcopy-acl.c (is_attr_permissions): New functions.
(qcopy_acl): If USE_XATTR, copy the ACL related attributes directly.
* m4/xattr.m4: New file.
* modules/qcopy-acl (Files): Add it.
(configure.ac): Invoke gl_FUNC_XATTR.

ChangeLog
lib/qcopy-acl.c
m4/xattr.m4 [new file with mode: 0644]
modules/qcopy-acl

index d9d728b7bb3cba05f779d50f1d6bd52325500ce2..5fab6a279cb483428e9faeda8343ee2a7a9f12b1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2023-01-12  Ondrej Valousek  <ondrej.valousek.xm@renesas.com>
+
+       qcopy-acl: Optimize copying of ACLs by directly copying the attributes.
+       * lib/qcopy-acl.c (is_attr_permissions): New functions.
+       (qcopy_acl): If USE_XATTR, copy the ACL related attributes directly.
+       * m4/xattr.m4: New file.
+       * modules/qcopy-acl (Files): Add it.
+       (configure.ac): Invoke gl_FUNC_XATTR.
+
 2023-01-12  Bruno Haible  <bruno@clisp.org>
 
        error: Work around an Android problem.
index 883bcf7d5886ec6e7e77857465657f079a7334ef..0f4159b7fd954646d27946823e937264235bdfbb 100644 (file)
 
 #include "acl-internal.h"
 
+#if USE_XATTR
+
+# include <attr/libattr.h>
+
+/* Returns 1 if NAME is the name of an extended attribute that is related
+   to permissions, i.e. ACLs.  Returns 0 otherwise.  */
+
+static int
+is_attr_permissions (const char *name, struct error_context *ctx)
+{
+  return attr_copy_action (name, ctx) == ATTR_ACTION_PERMISSIONS;
+}
+
+#endif  /* USE_XATTR */
 
 /* Copy access control lists from one file to another. If SOURCE_DESC is
    a valid file descriptor, use file descriptor operations, else use
@@ -39,13 +53,33 @@ int
 qcopy_acl (const char *src_name, int source_desc, const char *dst_name,
            int dest_desc, mode_t mode)
 {
-  struct permission_context ctx;
   int ret;
 
+#ifdef USE_XATTR
+  /* in case no ACLs present and also to set higher mode bits
+     we chmod before setting ACLs as doing it after could overwrite them
+     (especially true for NFSv4, posix ACL has that ugly "mask" hack that
+     nobody understands) */
+  ret = chmod_or_fchmod (dst_name, dest_desc, mode);
+  /* Rather than fiddling with acls one by one, we just copy the whole ACL xattrs
+     (Posix or NFSv4). Of course, that won't address ACLs conversion
+     (i.e. posix <-> nfs4) but we can't do it anyway, so for now, we don't care
+     Functions attr_copy_* return 0 in case we copied something OR nothing
+     to copy */
+  if (ret == 0)
+    ret = source_desc <= 0 || dest_desc <= 0
+      ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL)
+      : attr_copy_fd (src_name, source_desc, dst_name, dest_desc,
+                      is_attr_permissions, NULL);
+#else
+  /* no XATTR, so we proceed the old dusty way */
+  struct permission_context ctx;
+
   ret = get_permissions (src_name, source_desc, mode, &ctx);
   if (ret != 0)
     return -2;
   ret = set_permissions (&ctx, dst_name, dest_desc);
   free_permission_context (&ctx);
+#endif
   return ret;
 }
diff --git a/m4/xattr.m4 b/m4/xattr.m4
new file mode 100644 (file)
index 0000000..6efdfa4
--- /dev/null
@@ -0,0 +1,42 @@
+# xattr.m4 - check for Extended Attributes (Linux)
+# serial 4
+
+# Copyright (C) 2003-2021 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_XATTR],
+[
+  AC_ARG_ENABLE([xattr],
+        AS_HELP_STRING([--disable-xattr],
+                       [do not support extended attributes]),
+        [use_xattr=$enableval], [use_xattr=yes])
+
+  LIB_XATTR=
+  AC_SUBST([LIB_XATTR])
+
+  if test "$use_xattr" = "yes"; then
+    AC_CHECK_HEADERS([attr/error_context.h attr/libattr.h])
+    use_xattr=no
+    if test "$ac_cv_header_attr_libattr_h" = yes \
+        && test "$ac_cv_header_attr_error_context_h" = yes; then
+      xattr_saved_LIBS=$LIBS
+      AC_SEARCH_LIBS([attr_copy_file], [attr],
+                     [test "$ac_cv_search_attr_copy_file" = "none required" ||
+                        LIB_XATTR="$ac_cv_search_attr_copy_file"])
+      AC_CHECK_FUNCS([attr_copy_file])
+      LIBS=$xattr_saved_LIBS
+      if test "$ac_cv_func_attr_copy_file" = yes; then
+        use_xattr=yes
+      fi
+    fi
+    if test $use_xattr = no; then
+      AC_MSG_WARN([libattr development library was not found or not usable.])
+      AC_MSG_WARN([AC_PACKAGE_NAME will be built without xattr support.])
+    fi
+  fi
+  if test $use_xattr = yes; then
+    AC_DEFINE_UNQUOTED([USE_XATTR], 1)
+  fi
+])
index c0e5b6a8f8953c37d4e31dea35462d87ed93d494..e0cd914953ceeadbaa7ec7454331ee8b1b9364ce 100644 (file)
@@ -3,11 +3,13 @@ Copy access control list from one file to another.  (Unportable.)
 
 Files:
 lib/qcopy-acl.c
+m4/xattr.m4
 
 Depends-on:
 acl-permissions
 
 configure.ac:
+gl_FUNC_XATTR
 
 Makefile.am:
 lib_SOURCES += qcopy-acl.c