mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 05:56:14 +01:00
Merge branch 'wip/oholy/x-gvfs-notrash' into 'master'
Add support to ignore trash for certain mounts See merge request GNOME/glib!1549
This commit is contained in:
commit
1c08f55c6d
@ -1572,6 +1572,7 @@ g_unix_mount_point_guess_symbolic_icon
|
||||
g_unix_mount_point_guess_name
|
||||
g_unix_mount_point_guess_can_eject
|
||||
g_unix_mount_points_get
|
||||
g_unix_mount_point_at
|
||||
g_unix_mounts_get
|
||||
g_unix_mount_at
|
||||
g_unix_mount_for
|
||||
|
@ -4134,7 +4134,9 @@ g_file_delete_finish (GFile *file,
|
||||
* Sends @file to the "Trashcan", if possible. This is similar to
|
||||
* deleting it, but the user can recover it before emptying the trashcan.
|
||||
* Not all file systems support trashing, so this call can return the
|
||||
* %G_IO_ERROR_NOT_SUPPORTED error.
|
||||
* %G_IO_ERROR_NOT_SUPPORTED error. Since GLib 2.66, the `x-gvfs-notrash` unix
|
||||
* mount option can be used to disable g_file_trash() support for certain
|
||||
* mounts, the %G_IO_ERROR_NOT_SUPPORTED error will be returned in that case.
|
||||
*
|
||||
* If @cancellable is not %NULL, then the operation can be cancelled by
|
||||
* triggering the cancellable object from another thread. If the operation
|
||||
|
@ -1777,6 +1777,52 @@ try_make_relative (const char *path,
|
||||
return g_strdup (path);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ignore_trash_mount (GUnixMountEntry *mount)
|
||||
{
|
||||
GUnixMountPoint *mount_point = NULL;
|
||||
const gchar *mount_options;
|
||||
gboolean retval = TRUE;
|
||||
|
||||
if (g_unix_mount_is_system_internal (mount))
|
||||
return TRUE;
|
||||
|
||||
mount_options = g_unix_mount_get_options (mount);
|
||||
if (mount_options == NULL)
|
||||
{
|
||||
mount_point = g_unix_mount_point_at (g_unix_mount_get_mount_path (mount),
|
||||
NULL);
|
||||
if (mount_point != NULL)
|
||||
mount_options = g_unix_mount_point_get_options (mount_point);
|
||||
}
|
||||
|
||||
if (mount_options == NULL ||
|
||||
strstr (mount_options, "x-gvfs-notrash") == NULL)
|
||||
retval = FALSE;
|
||||
|
||||
g_clear_pointer (&mount_point, g_unix_mount_point_free);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ignore_trash_path (const gchar *topdir)
|
||||
{
|
||||
GUnixMountEntry *mount;
|
||||
gboolean retval = TRUE;
|
||||
|
||||
mount = g_unix_mount_at (topdir, NULL);
|
||||
if (mount == NULL)
|
||||
goto out;
|
||||
|
||||
retval = ignore_trash_mount (mount);
|
||||
|
||||
out:
|
||||
g_clear_pointer (&mount, g_unix_mount_free);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_g_local_file_has_trash_dir (const char *dirname, dev_t dir_dev)
|
||||
{
|
||||
@ -1787,7 +1833,6 @@ _g_local_file_has_trash_dir (const char *dirname, dev_t dir_dev)
|
||||
char uid_str[32];
|
||||
GStatBuf global_stat, trash_stat;
|
||||
gboolean res;
|
||||
GUnixMountEntry *mount;
|
||||
|
||||
if (g_once_init_enter (&home_dev_set))
|
||||
{
|
||||
@ -1806,17 +1851,13 @@ _g_local_file_has_trash_dir (const char *dirname, dev_t dir_dev)
|
||||
if (topdir == NULL)
|
||||
return FALSE;
|
||||
|
||||
mount = g_unix_mount_at (topdir, NULL);
|
||||
if (mount == NULL || g_unix_mount_is_system_internal (mount))
|
||||
if (ignore_trash_path (topdir))
|
||||
{
|
||||
g_clear_pointer (&mount, g_unix_mount_free);
|
||||
g_free (topdir);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_clear_pointer (&mount, g_unix_mount_free);
|
||||
|
||||
globaldir = g_build_filename (topdir, ".Trash", NULL);
|
||||
if (g_lstat (globaldir, &global_stat) == 0 &&
|
||||
S_ISDIR (global_stat.st_mode) &&
|
||||
@ -1982,7 +2023,6 @@ g_local_file_trash (GFile *file,
|
||||
{
|
||||
uid_t uid;
|
||||
char uid_str[32];
|
||||
GUnixMountEntry *mount;
|
||||
|
||||
uid = geteuid ();
|
||||
g_snprintf (uid_str, sizeof (uid_str), "%lu", (unsigned long)uid);
|
||||
@ -1996,20 +2036,15 @@ g_local_file_trash (GFile *file,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mount = g_unix_mount_at (topdir, NULL);
|
||||
if (mount == NULL || g_unix_mount_is_system_internal (mount))
|
||||
if (ignore_trash_path (topdir))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("Trashing on system internal mounts is not supported"));
|
||||
|
||||
g_clear_pointer (&mount, g_unix_mount_free);
|
||||
g_free (topdir);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_clear_pointer (&mount, g_unix_mount_free);
|
||||
|
||||
/* Try looking for global trash dir $topdir/.Trash/$uid */
|
||||
globaldir = g_build_filename (topdir, ".Trash", NULL);
|
||||
if (g_lstat (globaldir, &global_stat) == 0 &&
|
||||
|
@ -1660,6 +1660,52 @@ g_unix_mount_points_get (guint64 *time_read)
|
||||
return _g_get_unix_mount_points ();
|
||||
}
|
||||
|
||||
/**
|
||||
* g_unix_mount_point_at:
|
||||
* @mount_path: (type filename): path for a possible unix mount point.
|
||||
* @time_read: (out) (optional): guint64 to contain a timestamp.
|
||||
*
|
||||
* Gets a #GUnixMountPoint for a given mount path. If @time_read is set, it
|
||||
* will be filled with a unix timestamp for checking if the mount points have
|
||||
* changed since with g_unix_mount_points_changed_since().
|
||||
*
|
||||
* If more mount points have the same mount path, the last matching mount point
|
||||
* is returned.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a #GUnixMountPoint, or %NULL if no match
|
||||
* is found.
|
||||
*
|
||||
* Since: 2.66
|
||||
**/
|
||||
GUnixMountPoint *
|
||||
g_unix_mount_point_at (const char *mount_path,
|
||||
guint64 *time_read)
|
||||
{
|
||||
GList *mount_points, *l;
|
||||
GUnixMountPoint *mount_point, *found;
|
||||
|
||||
mount_points = g_unix_mount_points_get (time_read);
|
||||
|
||||
found = NULL;
|
||||
for (l = mount_points; l != NULL; l = l->next)
|
||||
{
|
||||
mount_point = l->data;
|
||||
|
||||
if (strcmp (mount_path, mount_point->mount_path) == 0)
|
||||
{
|
||||
if (found != NULL)
|
||||
g_unix_mount_point_free (found);
|
||||
|
||||
found = mount_point;
|
||||
}
|
||||
else
|
||||
g_unix_mount_point_free (mount_point);
|
||||
}
|
||||
g_list_free (mount_points);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_unix_mounts_changed_since:
|
||||
* @time: guint64 to contain a timestamp.
|
||||
|
@ -132,6 +132,9 @@ GIcon * g_unix_mount_point_guess_symbolic_icon (GUnixMountPoint *mount
|
||||
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
GList * g_unix_mount_points_get (guint64 *time_read);
|
||||
GLIB_AVAILABLE_IN_2_66
|
||||
GUnixMountPoint *g_unix_mount_point_at (const char *mount_path,
|
||||
guint64 *time_read);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
GList * g_unix_mounts_get (guint64 *time_read);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
|
Loading…
Reference in New Issue
Block a user