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