glocalfile: Check that parent device is the same when trashing

To be honest, I am not sure why, but in some special environments (e.g.
our CI integration) can happen, that file device number is different from
parent device number. Return "Unable to find or create trash directory for
%s" error from g_local_file_trash() in that case and also set
G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH appropriately.
This commit is contained in:
Ondrej Holy 2018-06-08 10:45:56 +02:00
parent 83ca61a421
commit 15cdcd2e0b
2 changed files with 27 additions and 7 deletions

View File

@ -1677,16 +1677,20 @@ find_mountpoint_for (const char *file,
}
}
char *
_g_local_file_find_topdir_for (const char *file)
static char *
_g_local_file_find_topdir_for_internal (const char *file, dev_t file_dev)
{
char *dir;
char *mountpoint = NULL;
dev_t dir_dev;
dir = get_parent (file, &dir_dev);
if (dir == NULL)
return NULL;
if (dir == NULL || dir_dev != file_dev)
{
g_free (dir);
return NULL;
}
mountpoint = find_mountpoint_for (dir, dir_dev);
g_free (dir);
@ -1694,6 +1698,17 @@ _g_local_file_find_topdir_for (const char *file)
return mountpoint;
}
char *
_g_local_file_find_topdir_for (const char *file)
{
GStatBuf file_stat;
if (g_lstat (file, &file_stat) != 0)
return NULL;
return _g_local_file_find_topdir_for_internal (file, file_stat.st_dev);
}
static char *
get_unique_filename (const char *basename,
int id)
@ -1946,7 +1961,8 @@ g_local_file_trash (GFile *file,
uid = geteuid ();
g_snprintf (uid_str, sizeof (uid_str), "%lu", (unsigned long)uid);
topdir = _g_local_file_find_topdir_for (local->filename);
topdir = _g_local_file_find_topdir_for_internal (local->filename,
file_stat.st_dev);
if (topdir == NULL)
{
g_set_io_error (error,

View File

@ -924,9 +924,13 @@ get_access_rights (GFileAttributeMatcher *attribute_matcher,
_g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_DELETE,
writable);
/* Trashing is supported only if the parent device is the same */
if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH))
_g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH,
writable && parent_info->has_trash_dir);
_g_file_info_set_attribute_boolean_by_id (info,
G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH,
writable &&
parent_info->has_trash_dir &&
parent_info->device == statbuf->st_dev);
}
}