diff options
author | Alexander Larsson <alexl@redhat.com> | 2014-12-03 10:58:41 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2014-12-08 10:39:39 +0100 |
commit | 26a47b9ccaabaf1ff13a69fa5b90b9c87e3fb7fc (patch) | |
tree | 16f363aa31edafaf9982313702dbe0d77cc30712 | |
parent | b8a06c11f64c319b54dee833dd68c598534596c9 (diff) | |
download | ostree-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
-rw-r--r-- | src/libotutil/ot-fs-utils.c | 67 | ||||
-rw-r--r-- | 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 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; +} diff --git a/src/libotutil/ot-fs-utils.h b/src/libotutil/ot-fs-utils.h index d7ece4fa..6d4a3724 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 |