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
This commit is contained in:
parent
b8a06c11f6
commit
26a47b9cca
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue