[ostree] Add ot_lgetxattrat and ot_lsetxattrat utils



commit 26a47b9ccaabaf1ff13a69fa5b90b9c87e3fb7fc
Author: Alexander Larsson <alexl redhat com>
Date:   Wed Dec 3 10:58:41 2014 +0100

    Add ot_lgetxattrat and ot_lsetxattrat utils
    
    These are implementation of the missing corresponding syscalls that
    are done with the /proc/self/fd mechanism described at:
    
    https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
    
    https://bugzilla.gnome.org/show_bug.cgi?id=741125

 src/libotutil/ot-fs-utils.c |   67 +++++++++++++++++++++++++++++++++++++++++++
 src/libotutil/ot-fs-utils.h |   13 ++++++++
 2 files changed, 80 insertions(+), 0 deletions(-)
---
diff --git a/src/libotutil/ot-fs-utils.c b/src/libotutil/ot-fs-utils.c
index 1d02003..966f31a 100644
--- a/src/libotutil/ot-fs-utils.c
+++ b/src/libotutil/ot-fs-utils.c
@@ -21,6 +21,8 @@
 #include "config.h"
 
 #include "ot-fs-utils.h"
+#include "libgsystem.h"
+#include <attr/xattr.h>
 
 int
 ot_opendirat (int dfd, const char *path, gboolean follow)
@@ -48,3 +50,68 @@ ot_gopendirat (int             dfd,
   return TRUE;
 }
 
+GBytes *
+ot_lgetxattrat (int            dfd,
+                const char    *path,
+                const char    *attribute,
+                GError       **error)
+{
+  /* A workaround for the lack of lgetxattrat(), thanks to Florian Weimer:
+   * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
+   */
+  gs_free char *full_path = g_strdup_printf ("/proc/self/fd/%d/%s", dfd, path);
+  GBytes *bytes = NULL;
+  ssize_t bytes_read, real_size;
+  char *buf;
+
+  do
+    bytes_read = lgetxattr (full_path, attribute, NULL, 0);
+  while (G_UNLIKELY (bytes_read < 0 && errno == EINTR));
+  if (G_UNLIKELY (bytes_read < 0))
+    {
+      ot_util_set_error_from_errno (error, errno);
+      goto out;
+    }
+
+  buf = g_malloc (bytes_read);
+  do
+    real_size = lgetxattr (full_path, attribute, buf, bytes_read);
+  while (G_UNLIKELY (real_size < 0 && errno == EINTR));
+  if (G_UNLIKELY (real_size < 0))
+    {
+      ot_util_set_error_from_errno (error, errno);
+      g_free (buf);
+      goto out;
+    }
+
+  bytes = g_bytes_new_take (buf, real_size);
+ out:
+  return bytes;
+}
+
+gboolean
+ot_lsetxattrat (int            dfd,
+                const char    *path,
+                const char    *attribute,
+                const void    *value,
+                gsize          value_size,
+                int            flags,
+                GError       **error)
+{
+  /* A workaround for the lack of lsetxattrat(), thanks to Florian Weimer:
+   * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
+   */
+  gs_free char *full_path = g_strdup_printf ("/proc/self/fd/%d/%s", dfd, path);
+  int res;
+
+  do
+    res = lsetxattr (full_path, "user.ostreemeta", value, value_size, flags);
+  while (G_UNLIKELY (res == -1 && errno == EINTR));
+  if (G_UNLIKELY (res == -1))
+    {
+      ot_util_set_error_from_errno (error, errno);
+      return FALSE;
+    }
+
+  return TRUE;
+}
diff --git a/src/libotutil/ot-fs-utils.h b/src/libotutil/ot-fs-utils.h
index d7ece4f..6d4a372 100644
--- a/src/libotutil/ot-fs-utils.h
+++ b/src/libotutil/ot-fs-utils.h
@@ -31,5 +31,18 @@ gboolean ot_gopendirat (int             dfd,
                         int            *out_fd,
                         GError        **error);
 
+GBytes * ot_lgetxattrat (int            dfd,
+                         const char    *path,
+                         const char    *attribute,
+                         GError       **error);
+
+gboolean ot_lsetxattrat (int            dfd,
+                         const char    *path,
+                         const char    *attribute,
+                         const void    *value,
+                         gsize          value_size,
+                         int            flags,
+                         GError       **error);
+
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]