Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2018 Red Hat, Inc.
3 : : *
4 : : * SPDX-License-Identifier: LGPL-2.1-or-later
5 : : *
6 : : * This library is free software; you can redistribute it and/or modify
7 : : * it under the terms of the GNU Lesser General Public License as
8 : : * published by the Free Software Foundation; either version 2.1 of the
9 : : * licence, or (at your option) any later version.
10 : : *
11 : : * This is distributed in the hope that it will be useful, but WITHOUT
12 : : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 : : * License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General Public License
17 : : * along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : */
19 : :
20 : : #include <glib.h>
21 : :
22 : : #ifndef G_OS_UNIX
23 : : #error This is a Unix-specific test
24 : : #endif
25 : :
26 : : #include <glib/gstdio.h>
27 : : #include <gio/gio.h>
28 : : #include <gio/gunixmounts.h>
29 : :
30 : : /* Test that g_file_trash() returns G_IO_ERROR_NOT_SUPPORTED for files on system mounts. */
31 : : static void
32 : 1 : test_trash_not_supported (void)
33 : : {
34 : : GFile *file;
35 : : GFileIOStream *stream;
36 : : GUnixMountEntry *mount;
37 : : GFileInfo *info;
38 : 1 : GError *error = NULL;
39 : : gboolean ret;
40 : : gchar *parent_dirname;
41 : : GStatBuf parent_stat, home_stat;
42 : :
43 : 1 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/251");
44 : :
45 : : /* The test assumes that tmp file is located on system internal mount. */
46 : 1 : file = g_file_new_tmp ("test-trashXXXXXX", &stream, &error);
47 : 1 : parent_dirname = g_path_get_dirname (g_file_peek_path (file));
48 : 1 : g_assert_no_error (error);
49 : 1 : g_assert_cmpint (g_stat (parent_dirname, &parent_stat), ==, 0);
50 : 1 : g_test_message ("File: %s (parent st_dev: %" G_GUINT64_FORMAT ")",
51 : 1 : g_file_peek_path (file), (guint64) parent_stat.st_dev);
52 : :
53 : 1 : g_assert_cmpint (g_stat (g_get_home_dir (), &home_stat), ==, 0);
54 : 1 : g_test_message ("Home: %s (st_dev: %" G_GUINT64_FORMAT ")",
55 : 1 : g_get_home_dir (), (guint64) home_stat.st_dev);
56 : :
57 [ + - ]: 1 : if (parent_stat.st_dev == home_stat.st_dev)
58 : : {
59 : 1 : g_test_skip ("The file has to be on another filesystem than the home trash to run this test");
60 : :
61 : 1 : g_free (parent_dirname);
62 : 1 : g_object_unref (stream);
63 : 1 : g_object_unref (file);
64 : :
65 : 1 : return;
66 : : }
67 : :
68 : 0 : mount = g_unix_mount_for (g_file_peek_path (file), NULL);
69 : 0 : g_assert_true (mount == NULL || g_unix_mount_is_system_internal (mount));
70 [ # # ]: 0 : g_test_message ("Mount: %s", (mount != NULL) ? g_unix_mount_get_mount_path (mount) : "(null)");
71 : 0 : g_clear_pointer (&mount, g_unix_mount_free);
72 : :
73 : : /* g_file_trash() shouldn't be supported on system internal mounts,
74 : : * because those are not monitored by gvfsd-trash.
75 : : */
76 : 0 : ret = g_file_trash (file, NULL, &error);
77 : 0 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
78 : 0 : g_test_message ("Error: %s", error->message);
79 : 0 : g_assert_false (ret);
80 : 0 : g_clear_error (&error);
81 : :
82 : 0 : info = g_file_query_info (file,
83 : : G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH,
84 : : G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
85 : : NULL,
86 : : &error);
87 : 0 : g_assert_no_error (error);
88 : :
89 : 0 : g_assert_false (g_file_info_get_attribute_boolean (info,
90 : : G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH));
91 : :
92 : 0 : g_io_stream_close (G_IO_STREAM (stream), NULL, &error);
93 : 0 : g_assert_no_error (error);
94 : :
95 : 0 : g_free (parent_dirname);
96 : 0 : g_object_unref (info);
97 : 0 : g_object_unref (stream);
98 : 0 : g_object_unref (file);
99 : : }
100 : :
101 : : /* Test that symlinks are properly expaned when looking for topdir (e.g. for trash folder). */
102 : : static void
103 : 1 : test_trash_symlinks (void)
104 : : {
105 : : GFile *symlink;
106 : : GUnixMountEntry *target_mount, *tmp_mount, *symlink_mount, *target_over_symlink_mount;
107 : : gchar *target, *tmp, *target_over_symlink;
108 : 1 : GError *error = NULL;
109 : :
110 : 1 : g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1522");
111 : :
112 : 1 : target = g_build_filename (g_get_home_dir (), ".local", NULL);
113 : :
114 [ + - ]: 1 : if (!g_file_test (target, G_FILE_TEST_IS_DIR))
115 : : {
116 : 1 : g_test_skip_printf ("Directory '%s' does not exist", target);
117 : 1 : g_free (target);
118 : 1 : return;
119 : : }
120 : :
121 : 0 : target_mount = g_unix_mount_for (target, NULL);
122 : :
123 [ # # ]: 0 : if (target_mount == NULL)
124 : : {
125 : 0 : g_test_skip_printf ("Unable to determine mount point for %s", target);
126 : 0 : g_free (target);
127 : 0 : return;
128 : : }
129 : :
130 : 0 : g_assert_nonnull (target_mount);
131 : 0 : g_test_message ("Target: %s (mount: %s)", target, g_unix_mount_get_mount_path (target_mount));
132 : :
133 : 0 : tmp = g_dir_make_tmp ("test-trashXXXXXX", &error);
134 : 0 : g_assert_no_error (error);
135 : 0 : g_assert_nonnull (tmp);
136 : 0 : tmp_mount = g_unix_mount_for (tmp, NULL);
137 : :
138 [ # # ]: 0 : if (tmp_mount == NULL)
139 : : {
140 : 0 : g_test_skip_printf ("Unable to determine mount point for %s", tmp);
141 : 0 : g_unix_mount_free (target_mount);
142 : 0 : g_free (target);
143 : 0 : g_free (tmp);
144 : 0 : return;
145 : : }
146 : :
147 : 0 : g_assert_nonnull (tmp_mount);
148 : 0 : g_test_message ("Tmp: %s (mount: %s)", tmp, g_unix_mount_get_mount_path (tmp_mount));
149 : :
150 [ # # ]: 0 : if (g_unix_mount_compare (target_mount, tmp_mount) == 0)
151 : : {
152 : 0 : g_test_skip ("The tmp has to be on another mount than the home to run this test");
153 : :
154 : 0 : g_unix_mount_free (tmp_mount);
155 : 0 : g_free (tmp);
156 : 0 : g_unix_mount_free (target_mount);
157 : 0 : g_free (target);
158 : :
159 : 0 : return;
160 : : }
161 : :
162 : 0 : symlink = g_file_new_build_filename (tmp, "symlink", NULL);
163 : 0 : g_file_make_symbolic_link (symlink, g_get_home_dir (), NULL, &error);
164 : 0 : g_assert_no_error (error);
165 : :
166 : 0 : symlink_mount = g_unix_mount_for (g_file_peek_path (symlink), NULL);
167 : 0 : g_assert_nonnull (symlink_mount);
168 : 0 : g_test_message ("Symlink: %s (mount: %s)", g_file_peek_path (symlink), g_unix_mount_get_mount_path (symlink_mount));
169 : :
170 : 0 : g_assert_cmpint (g_unix_mount_compare (symlink_mount, tmp_mount), ==, 0);
171 : :
172 : 0 : target_over_symlink = g_build_filename (g_file_peek_path (symlink),
173 : : ".local",
174 : : NULL);
175 : 0 : target_over_symlink_mount = g_unix_mount_for (target_over_symlink, NULL);
176 : 0 : g_assert_nonnull (symlink_mount);
177 : 0 : g_test_message ("Target over symlink: %s (mount: %s)", target_over_symlink, g_unix_mount_get_mount_path (target_over_symlink_mount));
178 : :
179 : 0 : g_assert_cmpint (g_unix_mount_compare (target_over_symlink_mount, target_mount), ==, 0);
180 : :
181 : 0 : g_unix_mount_free (target_over_symlink_mount);
182 : 0 : g_unix_mount_free (symlink_mount);
183 : 0 : g_free (target_over_symlink);
184 : 0 : g_object_unref (symlink);
185 : 0 : g_unix_mount_free (tmp_mount);
186 : 0 : g_free (tmp);
187 : 0 : g_unix_mount_free (target_mount);
188 : 0 : g_free (target);
189 : : }
190 : :
191 : : int
192 : 1 : main (int argc, char *argv[])
193 : : {
194 : 1 : g_test_init (&argc, &argv, NULL);
195 : :
196 : 1 : g_test_add_func ("/trash/not-supported", test_trash_not_supported);
197 : 1 : g_test_add_func ("/trash/symlinks", test_trash_symlinks);
198 : :
199 : 1 : return g_test_run ();
200 : : }
|