Coverage Report

Created: 2025-07-01 07:09

/src/glib/gio/gtrashportal.c
Line
Count
Source (jump to first uncovered line)
1
/* GIO - GLib Input, Output and Streaming Library
2
 *
3
 * Copyright 2018, Red Hat, Inc.
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2.1 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General
16
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
#include "config.h"
20
21
#include <sys/stat.h>
22
#include <fcntl.h>
23
#include <errno.h>
24
#include <string.h>
25
26
#include "gtrashportal.h"
27
#include "xdp-dbus.h"
28
#include "gstdio.h"
29
30
#ifdef G_OS_UNIX
31
#include "gunixfdlist.h"
32
#endif
33
34
#ifndef O_CLOEXEC
35
#define O_CLOEXEC 0
36
#else
37
#define HAVE_O_CLOEXEC 1
38
#endif
39
40
#ifndef O_PATH
41
#define O_PATH 0
42
#endif
43
44
static GXdpTrash *
45
ensure_trash_portal (void)
46
0
{
47
0
  static GXdpTrash *trash = NULL;
48
49
0
  if (g_once_init_enter (&trash))
50
0
    {
51
0
      GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
52
0
      GXdpTrash *proxy = NULL;
53
54
0
      if (connection != NULL)
55
0
        {
56
0
          proxy = gxdp_trash_proxy_new_sync (connection, 0,
57
0
                                             "org.freedesktop.portal.Desktop",
58
0
                                             "/org/freedesktop/portal/desktop",
59
0
                                             NULL, NULL);
60
0
          g_object_unref (connection);
61
0
        }
62
63
0
      g_once_init_leave (&trash, proxy);
64
0
    }
65
66
0
  return trash;
67
0
}
68
69
gboolean
70
g_trash_portal_trash_file (GFile   *file,
71
                           GError **error)
72
0
{
73
0
  char *path = NULL;
74
0
  GUnixFDList *fd_list = NULL;
75
0
  int fd, fd_in, errsv;
76
0
  gboolean ret = FALSE;
77
0
  guint portal_result = 0;
78
0
  GXdpTrash *proxy;
79
80
0
  proxy = ensure_trash_portal ();
81
0
  if (proxy == NULL)
82
0
    {
83
0
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED,
84
0
                   "Trash portal is not available");
85
0
      goto out;
86
0
    }
87
88
0
  path = g_file_get_path (file);
89
90
0
  fd = g_open (path, O_RDWR | O_CLOEXEC | O_NOFOLLOW);
91
0
  if (fd == -1 && errno == EISDIR)
92
    /* If it is a directory, fall back to O_PATH */
93
0
    fd = g_open (path, O_PATH | O_CLOEXEC | O_RDONLY | O_NOFOLLOW);
94
95
0
  errsv = errno;
96
97
0
  if (fd == -1)
98
0
    {
99
0
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
100
0
                   "Failed to open %s", path);
101
0
      goto out;
102
0
    }
103
104
#ifndef HAVE_O_CLOEXEC
105
  fcntl (fd, F_SETFD, FD_CLOEXEC);
106
#endif
107
108
0
  fd_list = g_unix_fd_list_new ();
109
0
  fd_in = g_unix_fd_list_append (fd_list, fd, error);
110
0
  g_close (fd, NULL);
111
112
0
  if (fd_in == -1)
113
0
    goto out;
114
115
0
  ret = gxdp_trash_call_trash_file_sync (proxy,
116
0
                                         g_variant_new_handle (fd_in),
117
0
                                         fd_list,
118
0
                                         &portal_result,
119
0
                                         NULL,
120
0
                                         NULL,
121
0
                                         error);
122
123
0
  if (ret && portal_result != 1)
124
0
    {
125
0
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Trash portal failed on %s", path);
126
0
      ret = FALSE;
127
0
    }
128
129
0
 out:
130
0
  g_clear_object (&fd_list);
131
0
  g_free (path);
132
133
0
  return ret;
134
0
}