summaryrefslogtreecommitdiff
path: root/src/libotutil/ot-fs-utils.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2014-12-03 10:58:41 +0100
committerAlexander Larsson <alexl@redhat.com>2014-12-08 10:39:39 +0100
commit26a47b9ccaabaf1ff13a69fa5b90b9c87e3fb7fc (patch)
tree16f363aa31edafaf9982313702dbe0d77cc30712 /src/libotutil/ot-fs-utils.c
parentb8a06c11f64c319b54dee833dd68c598534596c9 (diff)
downloadostree-26a47b9ccaabaf1ff13a69fa5b90b9c87e3fb7fc.tar.gz
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
Diffstat (limited to 'src/libotutil/ot-fs-utils.c')
-rw-r--r--src/libotutil/ot-fs-utils.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/libotutil/ot-fs-utils.c b/src/libotutil/ot-fs-utils.c
index 1d02003e..966f31ae 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;
+}