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 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