summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormadmurphy <madmurphy333@gmail.com>2022-07-26 07:58:32 +0000
committerPhilip Withnall <philip@tecnocode.co.uk>2022-07-26 07:58:32 +0000
commitb295c537696fcad7191b8e009473aa0c922288b6 (patch)
tree4174624e7a0082f2bca7286796628627ef8fd67b
parentf839eae274129278154a0d017e38f443e2018869 (diff)
downloadglib-b295c537696fcad7191b8e009473aa0c922288b6.tar.gz
gfileinfo: Implement xattr attribute removal
Fixes: #1187
-rw-r--r--gio/glocalfileinfo.c25
-rw-r--r--gio/tests/g-file-info.c14
2 files changed, 32 insertions, 7 deletions
diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c
index edec7bdde..6f186957a 100644
--- a/gio/glocalfileinfo.c
+++ b/gio/glocalfileinfo.c
@@ -261,10 +261,12 @@ get_selinux_context (const char *path,
#define g_fgetxattr(fd,name,value,size) fgetxattr(fd,name,value,size,0,0)
#define g_flistxattr(fd,name,size) flistxattr(fd,name,size,0)
#define g_setxattr(path,name,value,size) setxattr(path,name,value,size,0,0)
+#define g_removexattr(path,name) removexattr(path,name,0)
#else
#define g_fgetxattr fgetxattr
#define g_flistxattr flistxattr
#define g_setxattr(path,name,value,size) setxattr(path,name,value,size,0)
+#define g_removexattr(path,name) removexattr(path,name)
#endif
static gssize
@@ -774,10 +776,10 @@ set_xattr (char *filename,
return FALSE;
}
- if (attr_value->type != G_FILE_ATTRIBUTE_TYPE_STRING)
+ if (attr_value->type != G_FILE_ATTRIBUTE_TYPE_STRING && attr_value->type != G_FILE_ATTRIBUTE_TYPE_INVALID)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- _("Invalid attribute type (string expected)"));
+ _("Invalid attribute type (string or invalid expected)"));
return FALSE;
}
@@ -799,16 +801,27 @@ set_xattr (char *filename,
escaped_attribute += strlen ("xattr-sys::");
is_user = FALSE;
}
-
+
attribute = hex_unescape_string (escaped_attribute, NULL, &free_attribute);
- value = hex_unescape_string (attr_value->u.string, &val_len, &free_value);
if (is_user)
a = g_strconcat ("user.", attribute, NULL);
else
a = attribute;
-
- res = g_setxattr (filename, a, value, val_len);
+
+ if (attr_value->type == G_FILE_ATTRIBUTE_TYPE_STRING)
+ {
+ value = hex_unescape_string (attr_value->u.string, &val_len, &free_value);
+ res = g_setxattr (filename, a, value, val_len);
+ }
+ else
+ {
+ value = NULL;
+ val_len = 0;
+ free_value = FALSE;
+ res = g_removexattr (filename, a);
+ }
+
errsv = errno;
if (is_user)
diff --git a/gio/tests/g-file-info.c b/gio/tests/g-file-info.c
index 2786e75b7..427ebffcc 100644
--- a/gio/tests/g-file-info.c
+++ b/gio/tests/g-file-info.c
@@ -1015,7 +1015,7 @@ test_xattrs (void)
{
GFile *file = NULL;
GFileIOStream *stream = NULL;
- GFileInfo *file_info0 = NULL, *file_info1 = NULL;
+ GFileInfo *file_info0 = NULL, *file_info1 = NULL, *file_info2 = NULL;
GError *local_error = NULL;
g_test_summary ("Test setting and getting escaped xattrs");
@@ -1037,6 +1037,7 @@ test_xattrs (void)
g_file_info_set_attribute_string (file_info0, "xattr::escaped", "hello\\x82\\x80\\xbd");
g_file_info_set_attribute_string (file_info0, "xattr::string", "hi there");
g_file_info_set_attribute_string (file_info0, "xattr::embedded-nul", "hi\\x00there");
+ g_file_info_set_attribute_string (file_info0, "xattr::deleteme", "this attribute will be deleted");
g_file_set_attributes_from_info (file, file_info0, G_FILE_QUERY_INFO_NONE, NULL, &local_error);
@@ -1061,8 +1062,19 @@ test_xattrs (void)
g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::escaped"), ==, "hello\\x82\\x80\\xbd");
g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::string"), ==, "hi there");
g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::embedded-nul"), ==, "hi\\x00there");
+ g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::deleteme"), ==, "this attribute will be deleted");
g_object_unref (file_info1);
+
+ /* Check whether removing extended attributes works. */
+ g_file_set_attribute (file, "xattr::deleteme", G_FILE_ATTRIBUTE_TYPE_INVALID, NULL, G_FILE_QUERY_INFO_NONE, NULL, &local_error);
+ g_assert_no_error (local_error);
+ file_info2 = g_file_query_info (file, "xattr::deleteme", G_FILE_QUERY_INFO_NONE, NULL, &local_error);
+ g_assert_no_error (local_error);
+ g_assert_nonnull (file_info2);
+ g_assert_cmpstr (g_file_info_get_attribute_string (file_info2, "xattr::deleteme"), ==, NULL);
+
+ g_object_unref (file_info2);
}
/* Tidy up. */