From f136e9216811eb33c31c5e2d042138f9eba58d82 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 15 Feb 2015 17:38:13 -0500 Subject: fileutils: Switch to libglnx xattr code --- libglnx | 2 +- src/gsystem-file-utils.c | 329 ++--------------------------------------------- 2 files changed, 13 insertions(+), 318 deletions(-) diff --git a/libglnx b/libglnx index ba67dd3..a90e1c3 160000 --- a/libglnx +++ b/libglnx @@ -1 +1 @@ -Subproject commit ba67dd39a7d5cc779f83bb22512740cdb4c61b33 +Subproject commit a90e1c3423d815931408b39181e10d281ae3d40b diff --git a/src/gsystem-file-utils.c b/src/gsystem-file-utils.c index 5c1b251..bc7dc35 100644 --- a/src/gsystem-file-utils.c +++ b/src/gsystem-file-utils.c @@ -27,6 +27,8 @@ #include +#include + #define _GSYSTEM_NO_LOCAL_ALLOC #include "libgsystem.h" #include "gsystem-glib-compat.h" @@ -37,9 +39,6 @@ #include #include #include -#ifdef GSYSTEM_CONFIG_XATTRS -#include -#endif static int close_nointr (int fd) @@ -1416,169 +1415,6 @@ gs_file_realpath (GFile *file) return file_real; } -#ifdef GSYSTEM_CONFIG_XATTRS -static char * -canonicalize_xattrs (char *xattr_string, - size_t len) -{ - char *p; - GSList *xattrs = NULL; - GSList *iter; - GString *result; - - result = g_string_new (0); - - p = xattr_string; - while (p < xattr_string+len) - { - xattrs = g_slist_prepend (xattrs, p); - p += strlen (p) + 1; - } - - xattrs = g_slist_sort (xattrs, (GCompareFunc) strcmp); - for (iter = xattrs; iter; iter = iter->next) { - g_string_append (result, iter->data); - g_string_append_c (result, '\0'); - } - - g_slist_free (xattrs); - return g_string_free (result, FALSE); -} - -static GVariant * -variant_new_ay_bytes (GBytes *bytes) -{ - gsize size; - gconstpointer data; - data = g_bytes_get_data (bytes, &size); - g_bytes_ref (bytes); - return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, size, - TRUE, (GDestroyNotify)g_bytes_unref, bytes); -} - -static gboolean -read_xattr_name_array (const char *path, - int fd, - const char *xattrs, - size_t len, - GVariantBuilder *builder, - GError **error) -{ - gboolean ret = FALSE; - const char *p; - int r; - const char *funcstr; - - g_assert (path != NULL || fd != -1); - - funcstr = fd != -1 ? "fgetxattr" : "lgetxattr"; - - p = xattrs; - while (p < xattrs+len) - { - ssize_t bytes_read; - char *buf; - GBytes *bytes = NULL; - - if (fd != -1) - bytes_read = fgetxattr (fd, p, NULL, 0); - else - bytes_read = lgetxattr (path, p, NULL, 0); - if (bytes_read < 0) - { - gs_set_prefix_error_from_errno (error, errno, "%s", funcstr); - goto out; - } - if (bytes_read == 0) - continue; - - buf = g_malloc (bytes_read); - bytes = g_bytes_new_take (buf, bytes_read); - if (fd != -1) - r = fgetxattr (fd, p, buf, bytes_read); - else - r = lgetxattr (path, p, buf, bytes_read); - if (r < 0) - { - g_bytes_unref (bytes); - gs_set_prefix_error_from_errno (error, errno, "%s", funcstr); - goto out; - } - - g_variant_builder_add (builder, "(@ay@ay)", - g_variant_new_bytestring (p), - variant_new_ay_bytes (bytes)); - - p = p + strlen (p) + 1; - g_bytes_unref (bytes); - } - - ret = TRUE; - out: - return ret; -} -#endif - -static gboolean -get_xattrs_impl (const char *path, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error) -{ -#ifdef GSYSTEM_CONFIG_XATTRS - gboolean ret = FALSE; - ssize_t bytes_read; - char *xattr_names = NULL; - char *xattr_names_canonical = NULL; - GVariantBuilder builder; - gboolean builder_initialized = FALSE; - GVariant *ret_xattrs = NULL; - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)")); - builder_initialized = TRUE; - - bytes_read = llistxattr (path, NULL, 0); - - if (bytes_read < 0) - { - if (errno != ENOTSUP) - { - gs_set_prefix_error_from_errno (error, errno, "llistxattr"); - goto out; - } - } - else if (bytes_read > 0) - { - xattr_names = g_malloc (bytes_read); - if (llistxattr (path, xattr_names, bytes_read) < 0) - { - gs_set_prefix_error_from_errno (error, errno, "llistxattr"); - goto out; - } - xattr_names_canonical = canonicalize_xattrs (xattr_names, bytes_read); - - if (!read_xattr_name_array (path, -1, xattr_names_canonical, bytes_read, &builder, error)) - goto out; - } - - ret_xattrs = g_variant_builder_end (&builder); - builder_initialized = FALSE; - g_variant_ref_sink (ret_xattrs); - - ret = TRUE; - gs_transfer_out_value (out_xattrs, &ret_xattrs); - out: - g_clear_pointer (&xattr_names, g_free); - g_clear_pointer (&xattr_names_canonical, g_free); - g_clear_pointer (&ret_xattrs, g_variant_unref); - if (!builder_initialized) - g_variant_builder_clear (&builder); - return ret; -#else - return TRUE; -#endif -} - /** * gs_dfd_and_name_get_all_xattrs: * @dfd: Parent directory file descriptor @@ -1597,19 +1433,7 @@ gs_dfd_and_name_get_all_xattrs (int dfd, GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - /* A workaround for the lack of lgetxattrat(), thanks to Florian Weimer: - * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html - */ - char *path = g_strdup_printf ("/proc/self/fd/%d/%s", dfd, name); - if (!get_xattrs_impl (path, out_xattrs, - cancellable, error)) - goto out; - - ret = TRUE; - out: - g_free (path); - return ret; + return glnx_dfd_name_get_all_xattrs (dfd, name, out_xattrs, cancellable, error); } /** @@ -1631,8 +1455,9 @@ gs_file_get_all_xattrs (GFile *f, GCancellable *cancellable, GError **error) { - return get_xattrs_impl (gs_file_get_path_cached (f), out_xattrs, - cancellable, error); + return glnx_dfd_name_get_all_xattrs (AT_FDCWD, + gs_file_get_path_cached (f), + out_xattrs, cancellable, error); } /** @@ -1654,58 +1479,7 @@ gs_fd_get_all_xattrs (int fd, GCancellable *cancellable, GError **error) { -#ifdef GSYSTEM_CONFIG_XATTRS - gboolean ret = FALSE; - ssize_t bytes_read; - char *xattr_names = NULL; - char *xattr_names_canonical = NULL; - GVariantBuilder builder; - gboolean builder_initialized = FALSE; - GVariant *ret_xattrs = NULL; - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)")); - builder_initialized = TRUE; - - bytes_read = flistxattr (fd, NULL, 0); - - if (bytes_read < 0) - { - if (errno != ENOTSUP) - { - gs_set_prefix_error_from_errno (error, errno, "flistxattr"); - goto out; - } - } - else if (bytes_read > 0) - { - xattr_names = g_malloc (bytes_read); - if (flistxattr (fd, xattr_names, bytes_read) < 0) - { - gs_set_prefix_error_from_errno (error, errno, "flistxattr"); - goto out; - } - xattr_names_canonical = canonicalize_xattrs (xattr_names, bytes_read); - - if (!read_xattr_name_array (NULL, fd, xattr_names_canonical, bytes_read, &builder, error)) - goto out; - } - - ret_xattrs = g_variant_builder_end (&builder); - builder_initialized = FALSE; - g_variant_ref_sink (ret_xattrs); - - ret = TRUE; - gs_transfer_out_value (out_xattrs, &ret_xattrs); - out: - g_clear_pointer (&xattr_names, g_free); - g_clear_pointer (&xattr_names_canonical, g_free); - g_clear_pointer (&ret_xattrs, g_variant_unref); - if (!builder_initialized) - g_variant_builder_clear (&builder); - return ret; -#else - return TRUE; -#endif + return glnx_fd_get_all_xattrs (fd, out_xattrs, cancellable, error); } /** @@ -1725,80 +1499,7 @@ gs_fd_set_all_xattrs (int fd, GCancellable *cancellable, GError **error) { -#ifdef GSYSTEM_CONFIG_XATTRS - gboolean ret = FALSE; - int i, n; - - n = g_variant_n_children (xattrs); - for (i = 0; i < n; i++) - { - const guint8* name; - const guint8* value_data; - GVariant *value = NULL; - gsize value_len; - int res; - - g_variant_get_child (xattrs, i, "(^&ay@ay)", - &name, &value); - value_data = g_variant_get_fixed_array (value, &value_len, 1); - - do - res = fsetxattr (fd, (char*)name, (char*)value_data, value_len, 0); - while (G_UNLIKELY (res == -1 && errno == EINTR)); - g_variant_unref (value); - if (G_UNLIKELY (res == -1)) - { - gs_set_prefix_error_from_errno (error, errno, "fsetxattr"); - goto out; - } - } - - ret = TRUE; - out: - return ret; -#else - return TRUE; -#endif -} - -static gboolean -set_all_xattrs_for_path (const char *path, - GVariant *xattrs, - GCancellable *cancellable, - GError **error) -{ -#ifdef GSYSTEM_CONFIG_XATTRS - gboolean ret = FALSE; - int i, n; - - n = g_variant_n_children (xattrs); - for (i = 0; i < n; i++) - { - const guint8* name; - GVariant *value; - const guint8* value_data; - gsize value_len; - gboolean loop_err; - - g_variant_get_child (xattrs, i, "(^&ay@ay)", - &name, &value); - value_data = g_variant_get_fixed_array (value, &value_len, 1); - - loop_err = lsetxattr (path, (char*)name, (char*)value_data, value_len, 0) < 0; - g_clear_pointer (&value, (GDestroyNotify) g_variant_unref); - if (loop_err) - { - gs_set_prefix_error_from_errno (error, errno, "lsetxattr"); - goto out; - } - } - - ret = TRUE; - out: - return ret; -#else - return TRUE; -#endif + return glnx_fd_set_all_xattrs (fd, xattrs, cancellable, error); } gboolean @@ -1808,15 +1509,7 @@ gs_dfd_and_name_set_all_xattrs (int dfd, GCancellable *cancellable, GError **error) { - /* A workaround for the lack of lsetxattrat(), thanks to Florian Weimer: - * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html - */ - char *path = g_strdup_printf ("/proc/self/fd/%d/%s", dfd, name); - gboolean ret; - - ret = set_all_xattrs_for_path (path, xattrs, cancellable, error); - g_free (path); - return ret; + return glnx_dfd_name_set_all_xattrs (dfd, name, xattrs, cancellable, error); } /** @@ -1836,7 +1529,9 @@ gs_file_set_all_xattrs (GFile *file, GCancellable *cancellable, GError **error) { - return set_all_xattrs_for_path (gs_file_get_path_cached (file), xattrs, cancellable, error); + return glnx_dfd_name_set_all_xattrs (AT_FDCWD, + gs_file_get_path_cached (file), + xattrs, cancellable, error); } struct GsRealDirfdIterator -- cgit v1.2.1