|
rpm-build |
c487f7 |
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* This library is free software; you can redistribute it and/or
|
|
rpm-build |
c487f7 |
* modify it under the terms of the GNU Lesser General Public
|
|
rpm-build |
c487f7 |
* License as published by the Free Software Foundation; either
|
|
rpm-build |
c487f7 |
* version 2 of the License, or (at your option) any later version.
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* This library is distributed in the hope that it will be useful,
|
|
rpm-build |
c487f7 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
c487f7 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
rpm-build |
c487f7 |
* Lesser General Public License for more details.
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* You should have received a copy of the GNU Lesser General Public
|
|
rpm-build |
c487f7 |
* License along with this library; if not, write to the
|
|
rpm-build |
c487f7 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
rpm-build |
c487f7 |
* Boston, MA 02111-1307, USA.
|
|
rpm-build |
c487f7 |
*/
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
#include "config.h"
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
#include <string.h>
|
|
rpm-build |
c487f7 |
#include <stdio.h>
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
#include <glnx-macros.h>
|
|
rpm-build |
c487f7 |
#include <glnx-xattrs.h>
|
|
rpm-build |
c487f7 |
#include <glnx-errors.h>
|
|
rpm-build |
c487f7 |
#include <glnx-local-alloc.h>
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
static GVariant *
|
|
rpm-build |
c487f7 |
variant_new_ay_bytes (GBytes *bytes)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
gsize size;
|
|
rpm-build |
c487f7 |
gconstpointer data;
|
|
rpm-build |
c487f7 |
data = g_bytes_get_data (bytes, &size);
|
|
rpm-build |
c487f7 |
g_bytes_ref (bytes);
|
|
rpm-build |
c487f7 |
return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, size,
|
|
rpm-build |
c487f7 |
TRUE, (GDestroyNotify)g_bytes_unref, bytes);
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
static char *
|
|
rpm-build |
c487f7 |
canonicalize_xattrs (char *xattr_string,
|
|
rpm-build |
c487f7 |
size_t len)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
char *p;
|
|
rpm-build |
c487f7 |
GSList *xattrs = NULL;
|
|
rpm-build |
c487f7 |
GSList *iter;
|
|
rpm-build |
c487f7 |
GString *result;
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
result = g_string_new (0);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
p = xattr_string;
|
|
rpm-build |
c487f7 |
while (p < xattr_string+len)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
xattrs = g_slist_prepend (xattrs, p);
|
|
rpm-build |
c487f7 |
p += strlen (p) + 1;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
xattrs = g_slist_sort (xattrs, (GCompareFunc) strcmp);
|
|
rpm-build |
c487f7 |
for (iter = xattrs; iter; iter = iter->next) {
|
|
rpm-build |
c487f7 |
g_string_append (result, iter->data);
|
|
rpm-build |
c487f7 |
g_string_append_c (result, '\0');
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
g_slist_free (xattrs);
|
|
rpm-build |
c487f7 |
return g_string_free (result, FALSE);
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
static gboolean
|
|
rpm-build |
c487f7 |
read_xattr_name_array (const char *path,
|
|
rpm-build |
c487f7 |
int fd,
|
|
rpm-build |
c487f7 |
const char *xattrs,
|
|
rpm-build |
c487f7 |
size_t len,
|
|
rpm-build |
c487f7 |
GVariantBuilder *builder,
|
|
rpm-build |
c487f7 |
GError **error)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
gboolean ret = FALSE;
|
|
rpm-build |
c487f7 |
const char *p;
|
|
rpm-build |
c487f7 |
int r;
|
|
rpm-build |
c487f7 |
const char *funcstr;
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
g_assert (path != NULL || fd != -1);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
funcstr = fd != -1 ? "fgetxattr" : "lgetxattr";
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
for (p = xattrs; p < xattrs+len; p = p + strlen (p) + 1)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
ssize_t bytes_read;
|
|
rpm-build |
c487f7 |
g_autofree char *buf = NULL;
|
|
rpm-build |
c487f7 |
g_autoptr(GBytes) bytes = NULL;
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
again:
|
|
rpm-build |
c487f7 |
if (fd != -1)
|
|
rpm-build |
c487f7 |
bytes_read = fgetxattr (fd, p, NULL, 0);
|
|
rpm-build |
c487f7 |
else
|
|
rpm-build |
c487f7 |
bytes_read = lgetxattr (path, p, NULL, 0);
|
|
rpm-build |
c487f7 |
if (bytes_read < 0)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
if (errno == ENODATA)
|
|
rpm-build |
c487f7 |
continue;
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
glnx_set_prefix_error_from_errno (error, "%s", funcstr);
|
|
rpm-build |
c487f7 |
goto out;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
if (bytes_read == 0)
|
|
rpm-build |
c487f7 |
continue;
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
buf = g_malloc (bytes_read);
|
|
rpm-build |
c487f7 |
if (fd != -1)
|
|
rpm-build |
c487f7 |
r = fgetxattr (fd, p, buf, bytes_read);
|
|
rpm-build |
c487f7 |
else
|
|
rpm-build |
c487f7 |
r = lgetxattr (path, p, buf, bytes_read);
|
|
rpm-build |
c487f7 |
if (r < 0)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
if (errno == ERANGE)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
g_free (g_steal_pointer (&buf));
|
|
rpm-build |
c487f7 |
goto again;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
else if (errno == ENODATA)
|
|
rpm-build |
c487f7 |
continue;
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
glnx_set_prefix_error_from_errno (error, "%s", funcstr);
|
|
rpm-build |
c487f7 |
goto out;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
bytes = g_bytes_new_take (g_steal_pointer (&buf), bytes_read);
|
|
rpm-build |
c487f7 |
g_variant_builder_add (builder, "(@ay@ay)",
|
|
rpm-build |
c487f7 |
g_variant_new_bytestring (p),
|
|
rpm-build |
c487f7 |
variant_new_ay_bytes (bytes));
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
ret = TRUE;
|
|
rpm-build |
c487f7 |
out:
|
|
rpm-build |
c487f7 |
return ret;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
static gboolean
|
|
rpm-build |
c487f7 |
get_xattrs_impl (const char *path,
|
|
rpm-build |
c487f7 |
int fd,
|
|
rpm-build |
c487f7 |
GVariant **out_xattrs,
|
|
rpm-build |
c487f7 |
GCancellable *cancellable,
|
|
rpm-build |
c487f7 |
GError **error)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
gboolean ret = FALSE;
|
|
rpm-build |
c487f7 |
ssize_t bytes_read, real_size;
|
|
rpm-build |
c487f7 |
g_autofree char *xattr_names = NULL;
|
|
rpm-build |
c487f7 |
g_autofree char *xattr_names_canonical = NULL;
|
|
rpm-build |
c487f7 |
GVariantBuilder builder;
|
|
rpm-build |
c487f7 |
gboolean builder_initialized = FALSE;
|
|
rpm-build |
c487f7 |
g_autoptr(GVariant) ret_xattrs = NULL;
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
g_assert (path != NULL || fd != -1);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)"));
|
|
rpm-build |
c487f7 |
builder_initialized = TRUE;
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
again:
|
|
rpm-build |
c487f7 |
if (path)
|
|
rpm-build |
c487f7 |
bytes_read = llistxattr (path, NULL, 0);
|
|
rpm-build |
c487f7 |
else
|
|
rpm-build |
c487f7 |
bytes_read = flistxattr (fd, NULL, 0);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
if (bytes_read < 0)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
if (errno != ENOTSUP)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
glnx_set_prefix_error_from_errno (error, "%s", "llistxattr");
|
|
rpm-build |
c487f7 |
goto out;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
else if (bytes_read > 0)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
xattr_names = g_malloc (bytes_read);
|
|
rpm-build |
c487f7 |
if (path)
|
|
rpm-build |
c487f7 |
real_size = llistxattr (path, xattr_names, bytes_read);
|
|
rpm-build |
c487f7 |
else
|
|
rpm-build |
c487f7 |
real_size = flistxattr (fd, xattr_names, bytes_read);
|
|
rpm-build |
c487f7 |
if (real_size < 0)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
if (errno == ERANGE)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
g_free (xattr_names);
|
|
rpm-build |
c487f7 |
goto again;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
glnx_set_prefix_error_from_errno (error, "%s", "llistxattr");
|
|
rpm-build |
c487f7 |
goto out;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
else if (real_size > 0)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
xattr_names_canonical = canonicalize_xattrs (xattr_names, real_size);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
if (!read_xattr_name_array (path, fd, xattr_names_canonical, real_size, &builder, error))
|
|
rpm-build |
c487f7 |
goto out;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
ret_xattrs = g_variant_builder_end (&builder);
|
|
rpm-build |
c487f7 |
builder_initialized = FALSE;
|
|
rpm-build |
c487f7 |
g_variant_ref_sink (ret_xattrs);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
ret = TRUE;
|
|
rpm-build |
c487f7 |
if (out_xattrs)
|
|
rpm-build |
c487f7 |
*out_xattrs = g_steal_pointer (&ret_xattrs);
|
|
rpm-build |
c487f7 |
out:
|
|
rpm-build |
c487f7 |
if (!builder_initialized)
|
|
rpm-build |
c487f7 |
g_variant_builder_clear (&builder);
|
|
rpm-build |
c487f7 |
return ret;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
/**
|
|
rpm-build |
c487f7 |
* glnx_fd_get_all_xattrs:
|
|
rpm-build |
c487f7 |
* @fd: a file descriptor
|
|
rpm-build |
c487f7 |
* @out_xattrs: (out): A new #GVariant containing the extended attributes
|
|
rpm-build |
c487f7 |
* @cancellable: Cancellable
|
|
rpm-build |
c487f7 |
* @error: Error
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* Read all extended attributes from @fd in a canonical sorted order, and
|
|
rpm-build |
c487f7 |
* set @out_xattrs with the result.
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* If the filesystem does not support extended attributes, @out_xattrs
|
|
rpm-build |
c487f7 |
* will have 0 elements, and this function will return successfully.
|
|
rpm-build |
c487f7 |
*/
|
|
rpm-build |
c487f7 |
gboolean
|
|
rpm-build |
c487f7 |
glnx_fd_get_all_xattrs (int fd,
|
|
rpm-build |
c487f7 |
GVariant **out_xattrs,
|
|
rpm-build |
c487f7 |
GCancellable *cancellable,
|
|
rpm-build |
c487f7 |
GError **error)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
return get_xattrs_impl (NULL, fd, out_xattrs,
|
|
rpm-build |
c487f7 |
cancellable, error);
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
/**
|
|
rpm-build |
c487f7 |
* glnx_dfd_name_get_all_xattrs:
|
|
rpm-build |
c487f7 |
* @dfd: Parent directory file descriptor
|
|
rpm-build |
c487f7 |
* @name: File name
|
|
rpm-build |
c487f7 |
* @out_xattrs: (out): Extended attribute set
|
|
rpm-build |
c487f7 |
* @cancellable: Cancellable
|
|
rpm-build |
c487f7 |
* @error: Error
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* Load all extended attributes for the file named @name residing in
|
|
rpm-build |
c487f7 |
* directory @dfd.
|
|
rpm-build |
c487f7 |
*/
|
|
rpm-build |
c487f7 |
gboolean
|
|
rpm-build |
c487f7 |
glnx_dfd_name_get_all_xattrs (int dfd,
|
|
rpm-build |
c487f7 |
const char *name,
|
|
rpm-build |
c487f7 |
GVariant **out_xattrs,
|
|
rpm-build |
c487f7 |
GCancellable *cancellable,
|
|
rpm-build |
c487f7 |
GError **error)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
if (G_IN_SET(dfd, AT_FDCWD, -1))
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
return get_xattrs_impl (name, -1, out_xattrs, cancellable, error);
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
else
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
char buf[PATH_MAX];
|
|
rpm-build |
c487f7 |
/* A workaround for the lack of lgetxattrat(), thanks to Florian Weimer:
|
|
rpm-build |
c487f7 |
* https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
|
|
rpm-build |
c487f7 |
*/
|
|
rpm-build |
c487f7 |
snprintf (buf, sizeof (buf), "/proc/self/fd/%d/%s", dfd, name);
|
|
rpm-build |
c487f7 |
return get_xattrs_impl (buf, -1, out_xattrs, cancellable, error);
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
static gboolean
|
|
rpm-build |
c487f7 |
set_all_xattrs_for_path (const char *path,
|
|
rpm-build |
c487f7 |
GVariant *xattrs,
|
|
rpm-build |
c487f7 |
GCancellable *cancellable,
|
|
rpm-build |
c487f7 |
GError **error)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
const guint n = g_variant_n_children (xattrs);
|
|
rpm-build |
c487f7 |
for (guint i = 0; i < n; i++)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
const guint8* name;
|
|
rpm-build |
c487f7 |
g_autoptr(GVariant) value = NULL;
|
|
rpm-build |
c487f7 |
g_variant_get_child (xattrs, i, "(^&ay@ay)",
|
|
rpm-build |
c487f7 |
&name, &value);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
gsize value_len;
|
|
rpm-build |
c487f7 |
const guint8* value_data = g_variant_get_fixed_array (value, &value_len, 1);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
if (lsetxattr (path, (char*)name, (char*)value_data, value_len, 0) < 0)
|
|
rpm-build |
c487f7 |
return glnx_throw_errno_prefix (error, "lsetxattr");
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
return TRUE;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
/**
|
|
rpm-build |
c487f7 |
* glnx_dfd_name_set_all_xattrs:
|
|
rpm-build |
c487f7 |
* @dfd: Parent directory file descriptor
|
|
rpm-build |
c487f7 |
* @name: File name
|
|
rpm-build |
c487f7 |
* @xattrs: Extended attribute set
|
|
rpm-build |
c487f7 |
* @cancellable: Cancellable
|
|
rpm-build |
c487f7 |
* @error: Error
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* Set all extended attributes for the file named @name residing in
|
|
rpm-build |
c487f7 |
* directory @dfd.
|
|
rpm-build |
c487f7 |
*/
|
|
rpm-build |
c487f7 |
gboolean
|
|
rpm-build |
c487f7 |
glnx_dfd_name_set_all_xattrs (int dfd,
|
|
rpm-build |
c487f7 |
const char *name,
|
|
rpm-build |
c487f7 |
GVariant *xattrs,
|
|
rpm-build |
c487f7 |
GCancellable *cancellable,
|
|
rpm-build |
c487f7 |
GError **error)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
if (G_IN_SET(dfd, AT_FDCWD, -1))
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
return set_all_xattrs_for_path (name, xattrs, cancellable, error);
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
else
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
char buf[PATH_MAX];
|
|
rpm-build |
c487f7 |
/* A workaround for the lack of lsetxattrat(), thanks to Florian Weimer:
|
|
rpm-build |
c487f7 |
* https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
|
|
rpm-build |
c487f7 |
*/
|
|
rpm-build |
c487f7 |
snprintf (buf, sizeof (buf), "/proc/self/fd/%d/%s", dfd, name);
|
|
rpm-build |
c487f7 |
return set_all_xattrs_for_path (buf, xattrs, cancellable, error);
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
/**
|
|
rpm-build |
c487f7 |
* glnx_fd_set_all_xattrs:
|
|
rpm-build |
c487f7 |
* @fd: File descriptor
|
|
rpm-build |
c487f7 |
* @xattrs: Extended attributes
|
|
rpm-build |
c487f7 |
* @cancellable: Cancellable
|
|
rpm-build |
c487f7 |
* @error: Error
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* For each attribute in @xattrs, set its value on the file or
|
|
rpm-build |
c487f7 |
* directory referred to by @fd. This function does not remove any
|
|
rpm-build |
c487f7 |
* attributes not in @xattrs.
|
|
rpm-build |
c487f7 |
*/
|
|
rpm-build |
c487f7 |
gboolean
|
|
rpm-build |
c487f7 |
glnx_fd_set_all_xattrs (int fd,
|
|
rpm-build |
c487f7 |
GVariant *xattrs,
|
|
rpm-build |
c487f7 |
GCancellable *cancellable,
|
|
rpm-build |
c487f7 |
GError **error)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
const guint n = g_variant_n_children (xattrs);
|
|
rpm-build |
c487f7 |
for (guint i = 0; i < n; i++)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
const guint8* name;
|
|
rpm-build |
c487f7 |
g_autoptr(GVariant) value = NULL;
|
|
rpm-build |
c487f7 |
g_variant_get_child (xattrs, i, "(^&ay@ay)",
|
|
rpm-build |
c487f7 |
&name, &value);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
gsize value_len;
|
|
rpm-build |
c487f7 |
const guint8* value_data = g_variant_get_fixed_array (value, &value_len, 1);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
if (TEMP_FAILURE_RETRY (fsetxattr (fd, (char*)name, (char*)value_data, value_len, 0)) < 0)
|
|
rpm-build |
c487f7 |
return glnx_throw_errno_prefix (error, "fsetxattr");
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
return TRUE;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
/**
|
|
rpm-build |
c487f7 |
* glnx_lgetxattrat:
|
|
rpm-build |
c487f7 |
* @dfd: Directory file descriptor
|
|
rpm-build |
c487f7 |
* @subpath: Subpath
|
|
rpm-build |
c487f7 |
* @attribute: Extended attribute to retrieve
|
|
rpm-build |
c487f7 |
* @error: Error
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* Retrieve an extended attribute value, relative to a directory file
|
|
rpm-build |
c487f7 |
* descriptor.
|
|
rpm-build |
c487f7 |
*/
|
|
rpm-build |
c487f7 |
GBytes *
|
|
rpm-build |
c487f7 |
glnx_lgetxattrat (int dfd,
|
|
rpm-build |
c487f7 |
const char *subpath,
|
|
rpm-build |
c487f7 |
const char *attribute,
|
|
rpm-build |
c487f7 |
GError **error)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
char pathbuf[PATH_MAX];
|
|
rpm-build |
c487f7 |
snprintf (pathbuf, sizeof (pathbuf), "/proc/self/fd/%d/%s", dfd, subpath);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
ssize_t bytes_read, real_size;
|
|
rpm-build |
c487f7 |
if (TEMP_FAILURE_RETRY (bytes_read = lgetxattr (pathbuf, attribute, NULL, 0)) < 0)
|
|
rpm-build |
c487f7 |
return glnx_null_throw_errno_prefix (error, "lgetxattr");
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
g_autofree guint8 *buf = g_malloc (bytes_read);
|
|
rpm-build |
c487f7 |
if (TEMP_FAILURE_RETRY (real_size = lgetxattr (pathbuf, attribute, buf, bytes_read)) < 0)
|
|
rpm-build |
c487f7 |
return glnx_null_throw_errno_prefix (error, "lgetxattr");
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
return g_bytes_new_take (g_steal_pointer (&buf), real_size);
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
/**
|
|
rpm-build |
c487f7 |
* glnx_fgetxattr_bytes:
|
|
rpm-build |
c487f7 |
* @fd: Directory file descriptor
|
|
rpm-build |
c487f7 |
* @attribute: Extended attribute to retrieve
|
|
rpm-build |
c487f7 |
* @error: Error
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* Returns: (transfer full): An extended attribute value, or %NULL on error
|
|
rpm-build |
c487f7 |
*/
|
|
rpm-build |
c487f7 |
GBytes *
|
|
rpm-build |
c487f7 |
glnx_fgetxattr_bytes (int fd,
|
|
rpm-build |
c487f7 |
const char *attribute,
|
|
rpm-build |
c487f7 |
GError **error)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
ssize_t bytes_read, real_size;
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
if (TEMP_FAILURE_RETRY (bytes_read = fgetxattr (fd, attribute, NULL, 0)) < 0)
|
|
rpm-build |
c487f7 |
return glnx_null_throw_errno_prefix (error, "fgetxattr");
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
g_autofree guint8 *buf = g_malloc (bytes_read);
|
|
rpm-build |
c487f7 |
if (TEMP_FAILURE_RETRY (real_size = fgetxattr (fd, attribute, buf, bytes_read)) < 0)
|
|
rpm-build |
c487f7 |
return glnx_null_throw_errno_prefix (error, "fgetxattr");
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
return g_bytes_new_take (g_steal_pointer (&buf), real_size);
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
/**
|
|
rpm-build |
c487f7 |
* glnx_lsetxattrat:
|
|
rpm-build |
c487f7 |
* @dfd: Directory file descriptor
|
|
rpm-build |
c487f7 |
* @subpath: Path
|
|
rpm-build |
c487f7 |
* @attribute: An attribute name
|
|
rpm-build |
c487f7 |
* @value: (array length=len) (element-type guint8): Attribute value
|
|
rpm-build |
c487f7 |
* @len: Length of @value
|
|
rpm-build |
c487f7 |
* @flags: Flags, containing either XATTR_CREATE or XATTR_REPLACE
|
|
rpm-build |
c487f7 |
* @error: Error
|
|
rpm-build |
c487f7 |
*
|
|
rpm-build |
c487f7 |
* Set an extended attribute, relative to a directory file descriptor.
|
|
rpm-build |
c487f7 |
*/
|
|
rpm-build |
c487f7 |
gboolean
|
|
rpm-build |
c487f7 |
glnx_lsetxattrat (int dfd,
|
|
rpm-build |
c487f7 |
const char *subpath,
|
|
rpm-build |
c487f7 |
const char *attribute,
|
|
rpm-build |
c487f7 |
const guint8 *value,
|
|
rpm-build |
c487f7 |
gsize len,
|
|
rpm-build |
c487f7 |
int flags,
|
|
rpm-build |
c487f7 |
GError **error)
|
|
rpm-build |
c487f7 |
{
|
|
rpm-build |
c487f7 |
char pathbuf[PATH_MAX];
|
|
rpm-build |
c487f7 |
snprintf (pathbuf, sizeof (pathbuf), "/proc/self/fd/%d/%s", dfd, subpath);
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
if (TEMP_FAILURE_RETRY (lsetxattr (subpath, attribute, value, len, flags)) < 0)
|
|
rpm-build |
c487f7 |
return glnx_throw_errno_prefix (error, "lsetxattr");
|
|
rpm-build |
c487f7 |
|
|
rpm-build |
c487f7 |
return TRUE;
|
|
rpm-build |
c487f7 |
}
|
|
rpm-build |
c487f7 |
|