summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2015-02-15 17:38:13 -0500
committerColin Walters <walters@verbum.org>2015-02-15 17:38:13 -0500
commitf136e9216811eb33c31c5e2d042138f9eba58d82 (patch)
tree4fdd054d7579fdb8246e7ba7d81d489824baa36f
parent16862cc4d4e38493705386cf26e2eb46063809ea (diff)
downloadlibgsystem-f136e9216811eb33c31c5e2d042138f9eba58d82.tar.gz
fileutils: Switch to libglnx xattr code
m---------libglnx0
-rw-r--r--src/gsystem-file-utils.c329
2 files changed, 12 insertions, 317 deletions
diff --git a/libglnx b/libglnx
-Subproject ba67dd39a7d5cc779f83bb22512740cdb4c61b3
+Subproject a90e1c3423d815931408b39181e10d281ae3d40
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 <string.h>
+#include <libglnx.h>
+
#define _GSYSTEM_NO_LOCAL_ALLOC
#include "libgsystem.h"
#include "gsystem-glib-compat.h"
@@ -37,9 +39,6 @@
#include <glib-unix.h>
#include <limits.h>
#include <dirent.h>
-#ifdef GSYSTEM_CONFIG_XATTRS
-#include <attr/xattr.h>
-#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