Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 : :
3 : : /* GIO - GLib Input, Output and Streaming Library
4 : : *
5 : : * Copyright (C) 2006-2008 Red Hat, Inc.
6 : : *
7 : : * SPDX-License-Identifier: LGPL-2.1-or-later
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2.1 of the License, or (at your option) any later version.
13 : : *
14 : : * This library is distributed in the hope that it will be useful,
15 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : * Lesser General Public License for more details.
18 : : *
19 : : * You should have received a copy of the GNU Lesser General
20 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 : : *
22 : : * Author: Alexander Larsson <alexl@redhat.com>
23 : : * David Zeuthen <davidz@redhat.com>
24 : : */
25 : :
26 : : #include "config.h"
27 : :
28 : : #include <string.h>
29 : :
30 : : #include "gmount.h"
31 : : #include "gmountprivate.h"
32 : : #include "gthemedicon.h"
33 : : #include "gasyncresult.h"
34 : : #include "gtask.h"
35 : : #include "gioerror.h"
36 : : #include "glibintl.h"
37 : :
38 : :
39 : : /**
40 : : * GMount:
41 : : *
42 : : * The `GMount` interface represents a user-visible mount, such as a mounted
43 : : * file system.
44 : : *
45 : : * `GMount` is a ‘mounted’ filesystem that you can access. Mounted is in
46 : : * quotes because it’s not the same as a UNIX mount, it might be a GVFS
47 : : * mount, but you can still access the files on it if you use GIO.
48 : : *
49 : : * A `GMount` might be associated with a [iface@Gio.Volume] (such as a USB flash
50 : : * drive) which hosts it.
51 : : *
52 : : * Unmounting a `GMount` instance is an asynchronous operation. For
53 : : * more information about asynchronous operations, see [iface@Gio.AsyncResult]
54 : : * and [class@Gio.Task]. To unmount a `GMount` instance, first call
55 : : * [method@Gio.Mount.unmount_with_operation] with (at least) the `GMount`
56 : : * instance and a [type@Gio.AsyncReadyCallback]. The callback will be fired
57 : : * when the operation has resolved (either with success or failure), and a
58 : : * [iface@Gio.AsyncResult] structure will be passed to the callback. That
59 : : * callback should then call [method@Gio.Mount.unmount_with_operation_finish]
60 : : * with the `GMount` and the [iface@Gio.AsyncResult] data to see if the
61 : : * operation was completed successfully. If an `error` is present when
62 : : * [method@Gio.Mount.unmount_with_operation_finish] is called, then it will be
63 : : * filled with any error information.
64 : : *
65 : : * Note, when [porting from GnomeVFS](migrating-gnome-vfs.html), `GMount` is the
66 : : * moral equivalent of `GnomeVFSVolume`.
67 : : **/
68 : :
69 : : typedef GMountIface GMountInterface;
70 : 17 : G_DEFINE_INTERFACE (GMount, g_mount, G_TYPE_OBJECT)
71 : :
72 : : static void
73 : 1 : g_mount_default_init (GMountInterface *iface)
74 : : {
75 : : /**
76 : : * GMount::changed:
77 : : * @mount: the object on which the signal is emitted
78 : : *
79 : : * Emitted when the mount has been changed.
80 : : **/
81 : 1 : g_signal_new (I_("changed"),
82 : : G_TYPE_MOUNT,
83 : : G_SIGNAL_RUN_LAST,
84 : : G_STRUCT_OFFSET (GMountIface, changed),
85 : : NULL, NULL,
86 : : NULL,
87 : : G_TYPE_NONE, 0);
88 : :
89 : : /**
90 : : * GMount::unmounted:
91 : : * @mount: the object on which the signal is emitted
92 : : *
93 : : * This signal is emitted when the #GMount have been
94 : : * unmounted. If the recipient is holding references to the
95 : : * object they should release them so the object can be
96 : : * finalized.
97 : : **/
98 : 1 : g_signal_new (I_("unmounted"),
99 : : G_TYPE_MOUNT,
100 : : G_SIGNAL_RUN_LAST,
101 : : G_STRUCT_OFFSET (GMountIface, unmounted),
102 : : NULL, NULL,
103 : : NULL,
104 : : G_TYPE_NONE, 0);
105 : : /**
106 : : * GMount::pre-unmount:
107 : : * @mount: the object on which the signal is emitted
108 : : *
109 : : * This signal may be emitted when the #GMount is about to be
110 : : * unmounted.
111 : : *
112 : : * This signal depends on the backend and is only emitted if
113 : : * GIO was used to unmount.
114 : : *
115 : : * Since: 2.22
116 : : **/
117 : 1 : g_signal_new (I_("pre-unmount"),
118 : : G_TYPE_MOUNT,
119 : : G_SIGNAL_RUN_LAST,
120 : : G_STRUCT_OFFSET (GMountIface, pre_unmount),
121 : : NULL, NULL,
122 : : NULL,
123 : : G_TYPE_NONE, 0);
124 : 1 : }
125 : :
126 : : /**
127 : : * g_mount_get_root:
128 : : * @mount: a #GMount.
129 : : *
130 : : * Gets the root directory on @mount.
131 : : *
132 : : * Returns: (transfer full): a #GFile.
133 : : * The returned object should be unreffed with
134 : : * g_object_unref() when no longer needed.
135 : : **/
136 : : GFile *
137 : 0 : g_mount_get_root (GMount *mount)
138 : : {
139 : : GMountIface *iface;
140 : :
141 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
142 : :
143 : 0 : iface = G_MOUNT_GET_IFACE (mount);
144 : :
145 : 0 : return (* iface->get_root) (mount);
146 : : }
147 : :
148 : : /**
149 : : * g_mount_get_default_location:
150 : : * @mount: a #GMount.
151 : : *
152 : : * Gets the default location of @mount. The default location of the given
153 : : * @mount is a path that reflects the main entry point for the user (e.g.
154 : : * the home directory, or the root of the volume).
155 : : *
156 : : * Returns: (transfer full): a #GFile.
157 : : * The returned object should be unreffed with
158 : : * g_object_unref() when no longer needed.
159 : : **/
160 : : GFile *
161 : 0 : g_mount_get_default_location (GMount *mount)
162 : : {
163 : : GMountIface *iface;
164 : : GFile *file;
165 : :
166 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
167 : :
168 : 0 : iface = G_MOUNT_GET_IFACE (mount);
169 : :
170 : : /* Fallback to get_root when default_location () is not available */
171 : 0 : if (iface->get_default_location)
172 : 0 : file = (* iface->get_default_location) (mount);
173 : : else
174 : 0 : file = (* iface->get_root) (mount);
175 : :
176 : 0 : return file;
177 : : }
178 : :
179 : : /**
180 : : * g_mount_get_name:
181 : : * @mount: a #GMount.
182 : : *
183 : : * Gets the name of @mount.
184 : : *
185 : : * Returns: the name for the given @mount.
186 : : * The returned string should be freed with g_free()
187 : : * when no longer needed.
188 : : **/
189 : : char *
190 : 0 : g_mount_get_name (GMount *mount)
191 : : {
192 : : GMountIface *iface;
193 : :
194 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
195 : :
196 : 0 : iface = G_MOUNT_GET_IFACE (mount);
197 : :
198 : 0 : return (* iface->get_name) (mount);
199 : : }
200 : :
201 : : /**
202 : : * g_mount_get_icon:
203 : : * @mount: a #GMount.
204 : : *
205 : : * Gets the icon for @mount.
206 : : *
207 : : * Returns: (transfer full): a #GIcon.
208 : : * The returned object should be unreffed with
209 : : * g_object_unref() when no longer needed.
210 : : **/
211 : : GIcon *
212 : 0 : g_mount_get_icon (GMount *mount)
213 : : {
214 : : GMountIface *iface;
215 : :
216 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
217 : :
218 : 0 : iface = G_MOUNT_GET_IFACE (mount);
219 : :
220 : 0 : return (* iface->get_icon) (mount);
221 : : }
222 : :
223 : :
224 : : /**
225 : : * g_mount_get_symbolic_icon:
226 : : * @mount: a #GMount.
227 : : *
228 : : * Gets the symbolic icon for @mount.
229 : : *
230 : : * Returns: (transfer full): a #GIcon.
231 : : * The returned object should be unreffed with
232 : : * g_object_unref() when no longer needed.
233 : : *
234 : : * Since: 2.34
235 : : **/
236 : : GIcon *
237 : 0 : g_mount_get_symbolic_icon (GMount *mount)
238 : : {
239 : : GMountIface *iface;
240 : : GIcon *ret;
241 : :
242 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
243 : :
244 : 0 : iface = G_MOUNT_GET_IFACE (mount);
245 : :
246 : 0 : if (iface->get_symbolic_icon != NULL)
247 : 0 : ret = iface->get_symbolic_icon (mount);
248 : : else
249 : 0 : ret = g_themed_icon_new_with_default_fallbacks ("folder-remote-symbolic");
250 : :
251 : 0 : return ret;
252 : : }
253 : :
254 : : /**
255 : : * g_mount_get_uuid:
256 : : * @mount: a #GMount.
257 : : *
258 : : * Gets the UUID for the @mount. The reference is typically based on
259 : : * the file system UUID for the mount in question and should be
260 : : * considered an opaque string. Returns %NULL if there is no UUID
261 : : * available.
262 : : *
263 : : * Returns: (nullable) (transfer full): the UUID for @mount or %NULL if no UUID
264 : : * can be computed.
265 : : * The returned string should be freed with g_free()
266 : : * when no longer needed.
267 : : **/
268 : : char *
269 : 0 : g_mount_get_uuid (GMount *mount)
270 : : {
271 : : GMountIface *iface;
272 : :
273 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
274 : :
275 : 0 : iface = G_MOUNT_GET_IFACE (mount);
276 : :
277 : 0 : return (* iface->get_uuid) (mount);
278 : : }
279 : :
280 : : /**
281 : : * g_mount_get_volume:
282 : : * @mount: a #GMount.
283 : : *
284 : : * Gets the volume for the @mount.
285 : : *
286 : : * Returns: (transfer full) (nullable): a #GVolume or %NULL if @mount is not
287 : : * associated with a volume.
288 : : * The returned object should be unreffed with
289 : : * g_object_unref() when no longer needed.
290 : : **/
291 : : GVolume *
292 : 0 : g_mount_get_volume (GMount *mount)
293 : : {
294 : : GMountIface *iface;
295 : :
296 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
297 : :
298 : 0 : iface = G_MOUNT_GET_IFACE (mount);
299 : :
300 : 0 : return (* iface->get_volume) (mount);
301 : : }
302 : :
303 : : /**
304 : : * g_mount_get_drive:
305 : : * @mount: a #GMount.
306 : : *
307 : : * Gets the drive for the @mount.
308 : : *
309 : : * This is a convenience method for getting the #GVolume and then
310 : : * using that object to get the #GDrive.
311 : : *
312 : : * Returns: (transfer full) (nullable): a #GDrive or %NULL if @mount is not
313 : : * associated with a volume or a drive.
314 : : * The returned object should be unreffed with
315 : : * g_object_unref() when no longer needed.
316 : : **/
317 : : GDrive *
318 : 0 : g_mount_get_drive (GMount *mount)
319 : : {
320 : : GMountIface *iface;
321 : :
322 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
323 : :
324 : 0 : iface = G_MOUNT_GET_IFACE (mount);
325 : :
326 : 0 : return (* iface->get_drive) (mount);
327 : : }
328 : :
329 : : /**
330 : : * g_mount_can_unmount:
331 : : * @mount: a #GMount.
332 : : *
333 : : * Checks if @mount can be unmounted.
334 : : *
335 : : * Returns: %TRUE if the @mount can be unmounted.
336 : : **/
337 : : gboolean
338 : 0 : g_mount_can_unmount (GMount *mount)
339 : : {
340 : : GMountIface *iface;
341 : :
342 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
343 : :
344 : 0 : iface = G_MOUNT_GET_IFACE (mount);
345 : :
346 : 0 : return (* iface->can_unmount) (mount);
347 : : }
348 : :
349 : : /**
350 : : * g_mount_can_eject:
351 : : * @mount: a #GMount.
352 : : *
353 : : * Checks if @mount can be ejected.
354 : : *
355 : : * Returns: %TRUE if the @mount can be ejected.
356 : : **/
357 : : gboolean
358 : 0 : g_mount_can_eject (GMount *mount)
359 : : {
360 : : GMountIface *iface;
361 : :
362 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
363 : :
364 : 0 : iface = G_MOUNT_GET_IFACE (mount);
365 : :
366 : 0 : return (* iface->can_eject) (mount);
367 : : }
368 : :
369 : : /**
370 : : * g_mount_unmount:
371 : : * @mount: a #GMount.
372 : : * @flags: flags affecting the operation
373 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
374 : : * @callback: (nullable): a #GAsyncReadyCallback, or %NULL.
375 : : * @user_data: user data passed to @callback.
376 : : *
377 : : * Unmounts a mount. This is an asynchronous operation, and is
378 : : * finished by calling g_mount_unmount_finish() with the @mount
379 : : * and #GAsyncResult data returned in the @callback.
380 : : *
381 : : * Deprecated: 2.22: Use g_mount_unmount_with_operation() instead.
382 : : **/
383 : : void
384 : 0 : g_mount_unmount (GMount *mount,
385 : : GMountUnmountFlags flags,
386 : : GCancellable *cancellable,
387 : : GAsyncReadyCallback callback,
388 : : gpointer user_data)
389 : : {
390 : : GMountIface *iface;
391 : :
392 : 0 : g_return_if_fail (G_IS_MOUNT (mount));
393 : :
394 : 0 : iface = G_MOUNT_GET_IFACE (mount);
395 : :
396 : 0 : if (iface->unmount == NULL)
397 : : {
398 : 0 : g_task_report_new_error (mount, callback, user_data,
399 : : g_mount_unmount_with_operation,
400 : : G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
401 : : /* Translators: This is an error
402 : : * message for mount objects that
403 : : * don't implement unmount. */
404 : 0 : _("mount doesn’t implement “unmount”"));
405 : 0 : return;
406 : : }
407 : :
408 : 0 : (* iface->unmount) (mount, flags, cancellable, callback, user_data);
409 : : }
410 : :
411 : : /**
412 : : * g_mount_unmount_finish:
413 : : * @mount: a #GMount.
414 : : * @result: a #GAsyncResult.
415 : : * @error: a #GError location to store the error occurring, or %NULL to
416 : : * ignore.
417 : : *
418 : : * Finishes unmounting a mount. If any errors occurred during the operation,
419 : : * @error will be set to contain the errors and %FALSE will be returned.
420 : : *
421 : : * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
422 : : *
423 : : * Deprecated: 2.22: Use g_mount_unmount_with_operation_finish() instead.
424 : : **/
425 : : gboolean
426 : 0 : g_mount_unmount_finish (GMount *mount,
427 : : GAsyncResult *result,
428 : : GError **error)
429 : : {
430 : : GMountIface *iface;
431 : :
432 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
433 : 0 : g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
434 : :
435 : 0 : if (g_async_result_legacy_propagate_error (result, error))
436 : 0 : return FALSE;
437 : 0 : else if (g_async_result_is_tagged (result, g_mount_unmount_with_operation))
438 : 0 : return g_task_propagate_boolean (G_TASK (result), error);
439 : :
440 : 0 : iface = G_MOUNT_GET_IFACE (mount);
441 : 0 : return (* iface->unmount_finish) (mount, result, error);
442 : : }
443 : :
444 : :
445 : : /**
446 : : * g_mount_eject:
447 : : * @mount: a #GMount.
448 : : * @flags: flags affecting the unmount if required for eject
449 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
450 : : * @callback: (nullable): a #GAsyncReadyCallback, or %NULL.
451 : : * @user_data: user data passed to @callback.
452 : : *
453 : : * Ejects a mount. This is an asynchronous operation, and is
454 : : * finished by calling g_mount_eject_finish() with the @mount
455 : : * and #GAsyncResult data returned in the @callback.
456 : : *
457 : : * Deprecated: 2.22: Use g_mount_eject_with_operation() instead.
458 : : **/
459 : : void
460 : 0 : g_mount_eject (GMount *mount,
461 : : GMountUnmountFlags flags,
462 : : GCancellable *cancellable,
463 : : GAsyncReadyCallback callback,
464 : : gpointer user_data)
465 : : {
466 : : GMountIface *iface;
467 : :
468 : 0 : g_return_if_fail (G_IS_MOUNT (mount));
469 : :
470 : 0 : iface = G_MOUNT_GET_IFACE (mount);
471 : :
472 : 0 : if (iface->eject == NULL)
473 : : {
474 : 0 : g_task_report_new_error (mount, callback, user_data,
475 : : g_mount_eject_with_operation,
476 : : G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
477 : : /* Translators: This is an error
478 : : * message for mount objects that
479 : : * don't implement eject. */
480 : 0 : _("mount doesn’t implement “eject”"));
481 : 0 : return;
482 : : }
483 : :
484 : 0 : (* iface->eject) (mount, flags, cancellable, callback, user_data);
485 : : }
486 : :
487 : : /**
488 : : * g_mount_eject_finish:
489 : : * @mount: a #GMount.
490 : : * @result: a #GAsyncResult.
491 : : * @error: a #GError location to store the error occurring, or %NULL to
492 : : * ignore.
493 : : *
494 : : * Finishes ejecting a mount. If any errors occurred during the operation,
495 : : * @error will be set to contain the errors and %FALSE will be returned.
496 : : *
497 : : * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise.
498 : : *
499 : : * Deprecated: 2.22: Use g_mount_eject_with_operation_finish() instead.
500 : : **/
501 : : gboolean
502 : 0 : g_mount_eject_finish (GMount *mount,
503 : : GAsyncResult *result,
504 : : GError **error)
505 : : {
506 : : GMountIface *iface;
507 : :
508 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
509 : 0 : g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
510 : :
511 : 0 : if (g_async_result_legacy_propagate_error (result, error))
512 : 0 : return FALSE;
513 : 0 : else if (g_async_result_is_tagged (result, g_mount_eject_with_operation))
514 : 0 : return g_task_propagate_boolean (G_TASK (result), error);
515 : :
516 : 0 : iface = G_MOUNT_GET_IFACE (mount);
517 : 0 : return (* iface->eject_finish) (mount, result, error);
518 : : }
519 : :
520 : : /**
521 : : * g_mount_unmount_with_operation:
522 : : * @mount: a #GMount.
523 : : * @flags: flags affecting the operation
524 : : * @mount_operation: (nullable): a #GMountOperation or %NULL to avoid
525 : : * user interaction.
526 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
527 : : * @callback: (nullable): a #GAsyncReadyCallback, or %NULL.
528 : : * @user_data: user data passed to @callback.
529 : : *
530 : : * Unmounts a mount. This is an asynchronous operation, and is
531 : : * finished by calling g_mount_unmount_with_operation_finish() with the @mount
532 : : * and #GAsyncResult data returned in the @callback.
533 : : *
534 : : * Since: 2.22
535 : : **/
536 : : void
537 : 0 : g_mount_unmount_with_operation (GMount *mount,
538 : : GMountUnmountFlags flags,
539 : : GMountOperation *mount_operation,
540 : : GCancellable *cancellable,
541 : : GAsyncReadyCallback callback,
542 : : gpointer user_data)
543 : : {
544 : : GMountIface *iface;
545 : :
546 : 0 : g_return_if_fail (G_IS_MOUNT (mount));
547 : :
548 : 0 : iface = G_MOUNT_GET_IFACE (mount);
549 : :
550 : 0 : if (iface->unmount == NULL && iface->unmount_with_operation == NULL)
551 : : {
552 : 0 : g_task_report_new_error (mount, callback, user_data,
553 : : g_mount_unmount_with_operation,
554 : : G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
555 : : /* Translators: This is an error
556 : : * message for mount objects that
557 : : * don't implement any of unmount or unmount_with_operation. */
558 : 0 : _("mount doesn’t implement “unmount” or “unmount_with_operation”"));
559 : 0 : return;
560 : : }
561 : :
562 : 0 : if (iface->unmount_with_operation != NULL)
563 : 0 : (* iface->unmount_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
564 : : else
565 : 0 : (* iface->unmount) (mount, flags, cancellable, callback, user_data);
566 : : }
567 : :
568 : : /**
569 : : * g_mount_unmount_with_operation_finish:
570 : : * @mount: a #GMount.
571 : : * @result: a #GAsyncResult.
572 : : * @error: a #GError location to store the error occurring, or %NULL to
573 : : * ignore.
574 : : *
575 : : * Finishes unmounting a mount. If any errors occurred during the operation,
576 : : * @error will be set to contain the errors and %FALSE will be returned.
577 : : *
578 : : * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
579 : : *
580 : : * Since: 2.22
581 : : **/
582 : : gboolean
583 : 0 : g_mount_unmount_with_operation_finish (GMount *mount,
584 : : GAsyncResult *result,
585 : : GError **error)
586 : : {
587 : : GMountIface *iface;
588 : :
589 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
590 : 0 : g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
591 : :
592 : 0 : if (g_async_result_legacy_propagate_error (result, error))
593 : 0 : return FALSE;
594 : 0 : else if (g_async_result_is_tagged (result, g_mount_unmount_with_operation))
595 : 0 : return g_task_propagate_boolean (G_TASK (result), error);
596 : :
597 : 0 : iface = G_MOUNT_GET_IFACE (mount);
598 : 0 : if (iface->unmount_with_operation_finish != NULL)
599 : 0 : return (* iface->unmount_with_operation_finish) (mount, result, error);
600 : : else
601 : 0 : return (* iface->unmount_finish) (mount, result, error);
602 : : }
603 : :
604 : :
605 : : /**
606 : : * g_mount_eject_with_operation:
607 : : * @mount: a #GMount.
608 : : * @flags: flags affecting the unmount if required for eject
609 : : * @mount_operation: (nullable): a #GMountOperation or %NULL to avoid
610 : : * user interaction.
611 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
612 : : * @callback: (nullable): a #GAsyncReadyCallback, or %NULL.
613 : : * @user_data: user data passed to @callback.
614 : : *
615 : : * Ejects a mount. This is an asynchronous operation, and is
616 : : * finished by calling g_mount_eject_with_operation_finish() with the @mount
617 : : * and #GAsyncResult data returned in the @callback.
618 : : *
619 : : * Since: 2.22
620 : : **/
621 : : void
622 : 0 : g_mount_eject_with_operation (GMount *mount,
623 : : GMountUnmountFlags flags,
624 : : GMountOperation *mount_operation,
625 : : GCancellable *cancellable,
626 : : GAsyncReadyCallback callback,
627 : : gpointer user_data)
628 : : {
629 : : GMountIface *iface;
630 : :
631 : 0 : g_return_if_fail (G_IS_MOUNT (mount));
632 : :
633 : 0 : iface = G_MOUNT_GET_IFACE (mount);
634 : :
635 : 0 : if (iface->eject == NULL && iface->eject_with_operation == NULL)
636 : : {
637 : 0 : g_task_report_new_error (mount, callback, user_data,
638 : : g_mount_eject_with_operation,
639 : : G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
640 : : /* Translators: This is an error
641 : : * message for mount objects that
642 : : * don't implement any of eject or eject_with_operation. */
643 : 0 : _("mount doesn’t implement “eject” or “eject_with_operation”"));
644 : 0 : return;
645 : : }
646 : :
647 : 0 : if (iface->eject_with_operation != NULL)
648 : 0 : (* iface->eject_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
649 : : else
650 : 0 : (* iface->eject) (mount, flags, cancellable, callback, user_data);
651 : : }
652 : :
653 : : /**
654 : : * g_mount_eject_with_operation_finish:
655 : : * @mount: a #GMount.
656 : : * @result: a #GAsyncResult.
657 : : * @error: a #GError location to store the error occurring, or %NULL to
658 : : * ignore.
659 : : *
660 : : * Finishes ejecting a mount. If any errors occurred during the operation,
661 : : * @error will be set to contain the errors and %FALSE will be returned.
662 : : *
663 : : * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise.
664 : : *
665 : : * Since: 2.22
666 : : **/
667 : : gboolean
668 : 0 : g_mount_eject_with_operation_finish (GMount *mount,
669 : : GAsyncResult *result,
670 : : GError **error)
671 : : {
672 : : GMountIface *iface;
673 : :
674 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
675 : 0 : g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
676 : :
677 : 0 : if (g_async_result_legacy_propagate_error (result, error))
678 : 0 : return FALSE;
679 : 0 : else if (g_async_result_is_tagged (result, g_mount_eject_with_operation))
680 : 0 : return g_task_propagate_boolean (G_TASK (result), error);
681 : :
682 : 0 : iface = G_MOUNT_GET_IFACE (mount);
683 : 0 : if (iface->eject_with_operation_finish != NULL)
684 : 0 : return (* iface->eject_with_operation_finish) (mount, result, error);
685 : : else
686 : 0 : return (* iface->eject_finish) (mount, result, error);
687 : : }
688 : :
689 : : /**
690 : : * g_mount_remount:
691 : : * @mount: a #GMount.
692 : : * @flags: flags affecting the operation
693 : : * @mount_operation: (nullable): a #GMountOperation or %NULL to avoid
694 : : * user interaction.
695 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
696 : : * @callback: (nullable): a #GAsyncReadyCallback, or %NULL.
697 : : * @user_data: user data passed to @callback.
698 : : *
699 : : * Remounts a mount. This is an asynchronous operation, and is
700 : : * finished by calling g_mount_remount_finish() with the @mount
701 : : * and #GAsyncResults data returned in the @callback.
702 : : *
703 : : * Remounting is useful when some setting affecting the operation
704 : : * of the volume has been changed, as these may need a remount to
705 : : * take affect. While this is semantically equivalent with unmounting
706 : : * and then remounting not all backends might need to actually be
707 : : * unmounted.
708 : : **/
709 : : void
710 : 0 : g_mount_remount (GMount *mount,
711 : : GMountMountFlags flags,
712 : : GMountOperation *mount_operation,
713 : : GCancellable *cancellable,
714 : : GAsyncReadyCallback callback,
715 : : gpointer user_data)
716 : : {
717 : : GMountIface *iface;
718 : :
719 : 0 : g_return_if_fail (G_IS_MOUNT (mount));
720 : :
721 : 0 : iface = G_MOUNT_GET_IFACE (mount);
722 : :
723 : 0 : if (iface->remount == NULL)
724 : : {
725 : 0 : g_task_report_new_error (mount, callback, user_data,
726 : : g_mount_remount,
727 : : G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
728 : : /* Translators: This is an error
729 : : * message for mount objects that
730 : : * don't implement remount. */
731 : 0 : _("mount doesn’t implement “remount”"));
732 : 0 : return;
733 : : }
734 : :
735 : 0 : (* iface->remount) (mount, flags, mount_operation, cancellable, callback, user_data);
736 : : }
737 : :
738 : : /**
739 : : * g_mount_remount_finish:
740 : : * @mount: a #GMount.
741 : : * @result: a #GAsyncResult.
742 : : * @error: a #GError location to store the error occurring, or %NULL to
743 : : * ignore.
744 : : *
745 : : * Finishes remounting a mount. If any errors occurred during the operation,
746 : : * @error will be set to contain the errors and %FALSE will be returned.
747 : : *
748 : : * Returns: %TRUE if the mount was successfully remounted. %FALSE otherwise.
749 : : **/
750 : : gboolean
751 : 0 : g_mount_remount_finish (GMount *mount,
752 : : GAsyncResult *result,
753 : : GError **error)
754 : : {
755 : : GMountIface *iface;
756 : :
757 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
758 : 0 : g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
759 : :
760 : 0 : if (g_async_result_legacy_propagate_error (result, error))
761 : 0 : return FALSE;
762 : 0 : else if (g_async_result_is_tagged (result, g_mount_remount))
763 : 0 : return g_task_propagate_boolean (G_TASK (result), error);
764 : :
765 : 0 : iface = G_MOUNT_GET_IFACE (mount);
766 : 0 : return (* iface->remount_finish) (mount, result, error);
767 : : }
768 : :
769 : : /**
770 : : * g_mount_guess_content_type:
771 : : * @mount: a #GMount
772 : : * @force_rescan: Whether to force a rescan of the content.
773 : : * Otherwise a cached result will be used if available
774 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
775 : : * @callback: a #GAsyncReadyCallback
776 : : * @user_data: user data passed to @callback
777 : : *
778 : : * Tries to guess the type of content stored on @mount. Returns one or
779 : : * more textual identifiers of well-known content types (typically
780 : : * prefixed with "x-content/"), e.g. x-content/image-dcf for camera
781 : : * memory cards. See the
782 : : * [shared-mime-info](http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec)
783 : : * specification for more on x-content types.
784 : : *
785 : : * This is an asynchronous operation (see
786 : : * g_mount_guess_content_type_sync() for the synchronous version), and
787 : : * is finished by calling g_mount_guess_content_type_finish() with the
788 : : * @mount and #GAsyncResult data returned in the @callback.
789 : : *
790 : : * Since: 2.18
791 : : */
792 : : void
793 : 0 : g_mount_guess_content_type (GMount *mount,
794 : : gboolean force_rescan,
795 : : GCancellable *cancellable,
796 : : GAsyncReadyCallback callback,
797 : : gpointer user_data)
798 : : {
799 : : GMountIface *iface;
800 : :
801 : 0 : g_return_if_fail (G_IS_MOUNT (mount));
802 : :
803 : 0 : iface = G_MOUNT_GET_IFACE (mount);
804 : :
805 : 0 : if (iface->guess_content_type == NULL)
806 : : {
807 : 0 : g_task_report_new_error (mount, callback, user_data,
808 : : g_mount_guess_content_type,
809 : : G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
810 : : /* Translators: This is an error
811 : : * message for mount objects that
812 : : * don't implement content type guessing. */
813 : 0 : _("mount doesn’t implement content type guessing"));
814 : 0 : return;
815 : : }
816 : :
817 : 0 : (* iface->guess_content_type) (mount, force_rescan, cancellable, callback, user_data);
818 : : }
819 : :
820 : : /**
821 : : * g_mount_guess_content_type_finish:
822 : : * @mount: a #GMount
823 : : * @result: a #GAsyncResult
824 : : * @error: a #GError location to store the error occurring, or %NULL to
825 : : * ignore
826 : : *
827 : : * Finishes guessing content types of @mount. If any errors occurred
828 : : * during the operation, @error will be set to contain the errors and
829 : : * %FALSE will be returned. In particular, you may get an
830 : : * %G_IO_ERROR_NOT_SUPPORTED if the mount does not support content
831 : : * guessing.
832 : : *
833 : : * Returns: (transfer full) (element-type utf8): a %NULL-terminated array of content types or %NULL on error.
834 : : * Caller should free this array with g_strfreev() when done with it.
835 : : *
836 : : * Since: 2.18
837 : : **/
838 : : gchar **
839 : 0 : g_mount_guess_content_type_finish (GMount *mount,
840 : : GAsyncResult *result,
841 : : GError **error)
842 : : {
843 : : GMountIface *iface;
844 : :
845 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
846 : 0 : g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
847 : :
848 : 0 : if (g_async_result_legacy_propagate_error (result, error))
849 : 0 : return NULL;
850 : 0 : else if (g_async_result_is_tagged (result, g_mount_guess_content_type))
851 : 0 : return g_task_propagate_pointer (G_TASK (result), error);
852 : :
853 : 0 : iface = G_MOUNT_GET_IFACE (mount);
854 : 0 : return (* iface->guess_content_type_finish) (mount, result, error);
855 : : }
856 : :
857 : : /**
858 : : * g_mount_guess_content_type_sync:
859 : : * @mount: a #GMount
860 : : * @force_rescan: Whether to force a rescan of the content.
861 : : * Otherwise a cached result will be used if available
862 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
863 : : * @error: a #GError location to store the error occurring, or %NULL to
864 : : * ignore
865 : : *
866 : : * Tries to guess the type of content stored on @mount. Returns one or
867 : : * more textual identifiers of well-known content types (typically
868 : : * prefixed with "x-content/"), e.g. x-content/image-dcf for camera
869 : : * memory cards. See the
870 : : * [shared-mime-info](http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec)
871 : : * specification for more on x-content types.
872 : : *
873 : : * This is a synchronous operation and as such may block doing IO;
874 : : * see g_mount_guess_content_type() for the asynchronous version.
875 : : *
876 : : * Returns: (transfer full) (element-type utf8): a %NULL-terminated array of content types or %NULL on error.
877 : : * Caller should free this array with g_strfreev() when done with it.
878 : : *
879 : : * Since: 2.18
880 : : */
881 : : char **
882 : 0 : g_mount_guess_content_type_sync (GMount *mount,
883 : : gboolean force_rescan,
884 : : GCancellable *cancellable,
885 : : GError **error)
886 : : {
887 : : GMountIface *iface;
888 : :
889 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
890 : :
891 : 0 : iface = G_MOUNT_GET_IFACE (mount);
892 : :
893 : 0 : if (iface->guess_content_type_sync == NULL)
894 : : {
895 : 0 : g_set_error_literal (error,
896 : : G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
897 : : /* Translators: This is an error
898 : : * message for mount objects that
899 : : * don't implement content type guessing. */
900 : : _("mount doesn’t implement synchronous content type guessing"));
901 : :
902 : 0 : return NULL;
903 : : }
904 : :
905 : 0 : return (* iface->guess_content_type_sync) (mount, force_rescan, cancellable, error);
906 : : }
907 : :
908 : : G_LOCK_DEFINE_STATIC (priv_lock);
909 : :
910 : : /* only access this structure when holding priv_lock */
911 : : typedef struct
912 : : {
913 : : gint shadow_ref_count;
914 : : } GMountPrivate;
915 : :
916 : : static void
917 : 0 : free_private (GMountPrivate *private)
918 : : {
919 : 0 : G_LOCK (priv_lock);
920 : 0 : g_free (private);
921 : 0 : G_UNLOCK (priv_lock);
922 : 0 : }
923 : :
924 : : /* may only be called when holding priv_lock */
925 : : static GMountPrivate *
926 : 0 : get_private (GMount *mount)
927 : : {
928 : : GMountPrivate *private;
929 : :
930 : 0 : private = g_object_get_data (G_OBJECT (mount), "g-mount-private");
931 : 0 : if (G_LIKELY (private != NULL))
932 : 0 : goto out;
933 : :
934 : 0 : private = g_new0 (GMountPrivate, 1);
935 : 0 : g_object_set_data_full (G_OBJECT (mount),
936 : : "g-mount-private",
937 : : private,
938 : : (GDestroyNotify) free_private);
939 : :
940 : 0 : out:
941 : 0 : return private;
942 : : }
943 : :
944 : : /**
945 : : * g_mount_is_shadowed:
946 : : * @mount: A #GMount.
947 : : *
948 : : * Determines if @mount is shadowed. Applications or libraries should
949 : : * avoid displaying @mount in the user interface if it is shadowed.
950 : : *
951 : : * A mount is said to be shadowed if there exists one or more user
952 : : * visible objects (currently #GMount objects) with a root that is
953 : : * inside the root of @mount.
954 : : *
955 : : * One application of shadow mounts is when exposing a single file
956 : : * system that is used to address several logical volumes. In this
957 : : * situation, a #GVolumeMonitor implementation would create two
958 : : * #GVolume objects (for example, one for the camera functionality of
959 : : * the device and one for a SD card reader on the device) with
960 : : * activation URIs `gphoto2://[usb:001,002]/store1/`
961 : : * and `gphoto2://[usb:001,002]/store2/`. When the
962 : : * underlying mount (with root
963 : : * `gphoto2://[usb:001,002]/`) is mounted, said
964 : : * #GVolumeMonitor implementation would create two #GMount objects
965 : : * (each with their root matching the corresponding volume activation
966 : : * root) that would shadow the original mount.
967 : : *
968 : : * The proxy monitor in GVfs 2.26 and later, automatically creates and
969 : : * manage shadow mounts (and shadows the underlying mount) if the
970 : : * activation root on a #GVolume is set.
971 : : *
972 : : * Returns: %TRUE if @mount is shadowed.
973 : : *
974 : : * Since: 2.20
975 : : **/
976 : : gboolean
977 : 0 : g_mount_is_shadowed (GMount *mount)
978 : : {
979 : : GMountPrivate *priv;
980 : : gboolean ret;
981 : :
982 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
983 : :
984 : 0 : G_LOCK (priv_lock);
985 : 0 : priv = get_private (mount);
986 : 0 : ret = (priv->shadow_ref_count > 0);
987 : 0 : G_UNLOCK (priv_lock);
988 : :
989 : 0 : return ret;
990 : : }
991 : :
992 : : /**
993 : : * g_mount_shadow:
994 : : * @mount: A #GMount.
995 : : *
996 : : * Increments the shadow count on @mount. Usually used by
997 : : * #GVolumeMonitor implementations when creating a shadow mount for
998 : : * @mount, see g_mount_is_shadowed() for more information. The caller
999 : : * will need to emit the #GMount::changed signal on @mount manually.
1000 : : *
1001 : : * Since: 2.20
1002 : : **/
1003 : : void
1004 : 0 : g_mount_shadow (GMount *mount)
1005 : : {
1006 : : GMountPrivate *priv;
1007 : :
1008 : 0 : g_return_if_fail (G_IS_MOUNT (mount));
1009 : :
1010 : 0 : G_LOCK (priv_lock);
1011 : 0 : priv = get_private (mount);
1012 : 0 : priv->shadow_ref_count += 1;
1013 : 0 : G_UNLOCK (priv_lock);
1014 : : }
1015 : :
1016 : : /**
1017 : : * g_mount_unshadow:
1018 : : * @mount: A #GMount.
1019 : : *
1020 : : * Decrements the shadow count on @mount. Usually used by
1021 : : * #GVolumeMonitor implementations when destroying a shadow mount for
1022 : : * @mount, see g_mount_is_shadowed() for more information. The caller
1023 : : * will need to emit the #GMount::changed signal on @mount manually.
1024 : : *
1025 : : * Since: 2.20
1026 : : **/
1027 : : void
1028 : 0 : g_mount_unshadow (GMount *mount)
1029 : : {
1030 : : GMountPrivate *priv;
1031 : :
1032 : 0 : g_return_if_fail (G_IS_MOUNT (mount));
1033 : :
1034 : 0 : G_LOCK (priv_lock);
1035 : 0 : priv = get_private (mount);
1036 : 0 : priv->shadow_ref_count -= 1;
1037 : 0 : if (priv->shadow_ref_count < 0)
1038 : 0 : g_warning ("Shadow ref count on GMount is negative");
1039 : 0 : G_UNLOCK (priv_lock);
1040 : : }
1041 : :
1042 : : /**
1043 : : * g_mount_get_sort_key:
1044 : : * @mount: A #GMount.
1045 : : *
1046 : : * Gets the sort key for @mount, if any.
1047 : : *
1048 : : * Returns: (nullable): Sorting key for @mount or %NULL if no such key is available.
1049 : : *
1050 : : * Since: 2.32
1051 : : */
1052 : : const gchar *
1053 : 0 : g_mount_get_sort_key (GMount *mount)
1054 : : {
1055 : 0 : const gchar *ret = NULL;
1056 : : GMountIface *iface;
1057 : :
1058 : 0 : g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
1059 : :
1060 : 0 : iface = G_MOUNT_GET_IFACE (mount);
1061 : 0 : if (iface->get_sort_key != NULL)
1062 : 0 : ret = iface->get_sort_key (mount);
1063 : :
1064 : 0 : return ret;
1065 : : }
|