Coverage Report

Created: 2025-07-23 08:13

/src/pango/subprojects/glib/gio/gmount.c
Line
Count
Source (jump to first uncovered line)
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
G_DEFINE_INTERFACE (GMount, g_mount, G_TYPE_OBJECT)
71
72
static void
73
g_mount_default_init (GMountInterface *iface)
74
0
{
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
0
  g_signal_new (I_("changed"),
82
0
                G_TYPE_MOUNT,
83
0
                G_SIGNAL_RUN_LAST,
84
0
                G_STRUCT_OFFSET (GMountIface, changed),
85
0
                NULL, NULL,
86
0
                NULL,
87
0
                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
0
  g_signal_new (I_("unmounted"),
99
0
                G_TYPE_MOUNT,
100
0
                G_SIGNAL_RUN_LAST,
101
0
                G_STRUCT_OFFSET (GMountIface, unmounted),
102
0
                NULL, NULL,
103
0
                NULL,
104
0
                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
0
  g_signal_new (I_("pre-unmount"),
118
0
                G_TYPE_MOUNT,
119
0
                G_SIGNAL_RUN_LAST,
120
0
                G_STRUCT_OFFSET (GMountIface, pre_unmount),
121
0
                NULL, NULL,
122
0
                NULL,
123
0
                G_TYPE_NONE, 0);
124
0
}
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
g_mount_get_root (GMount *mount)
138
0
{
139
0
  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
0
}
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
g_mount_get_default_location (GMount *mount)
162
0
{
163
0
  GMountIface *iface;
164
0
  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
0
  else
174
0
    file = (* iface->get_root) (mount);
175
176
0
  return file;
177
0
}
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
g_mount_get_name (GMount *mount)
191
0
{
192
0
  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
0
}
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
g_mount_get_icon (GMount *mount)
213
0
{
214
0
  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
0
}
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
g_mount_get_symbolic_icon (GMount *mount)
238
0
{
239
0
  GMountIface *iface;
240
0
  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
0
  else
249
0
    ret = g_themed_icon_new_with_default_fallbacks ("folder-remote-symbolic");
250
251
0
  return ret;
252
0
}
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
g_mount_get_uuid (GMount *mount)
270
0
{
271
0
  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
0
}
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
g_mount_get_volume (GMount *mount)
293
0
{
294
0
  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
0
}
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
g_mount_get_drive (GMount *mount)
319
0
{
320
0
  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
0
}
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
g_mount_can_unmount (GMount *mount)
339
0
{
340
0
  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
0
}
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
g_mount_can_eject (GMount *mount)
359
0
{
360
0
  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
0
}
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
g_mount_unmount (GMount              *mount,
385
                 GMountUnmountFlags   flags,
386
                 GCancellable        *cancellable,
387
                 GAsyncReadyCallback  callback,
388
                 gpointer             user_data)
389
0
{
390
0
  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
0
    {
398
0
      g_task_report_new_error (mount, callback, user_data,
399
0
                               g_mount_unmount_with_operation,
400
0
                               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
0
    }
407
  
408
0
  (* iface->unmount) (mount, flags, cancellable, callback, user_data);
409
0
}
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
g_mount_unmount_finish (GMount        *mount,
427
                        GAsyncResult  *result,
428
                        GError       **error)
429
0
{
430
0
  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
0
}
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
g_mount_eject (GMount              *mount,
461
               GMountUnmountFlags   flags,
462
               GCancellable        *cancellable,
463
               GAsyncReadyCallback  callback,
464
               gpointer             user_data)
465
0
{
466
0
  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
0
    {
474
0
      g_task_report_new_error (mount, callback, user_data,
475
0
                               g_mount_eject_with_operation,
476
0
                               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
0
    }
483
  
484
0
  (* iface->eject) (mount, flags, cancellable, callback, user_data);
485
0
}
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
g_mount_eject_finish (GMount        *mount,
503
                      GAsyncResult  *result,
504
                      GError       **error)
505
0
{
506
0
  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
0
}
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
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
0
{
544
0
  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
0
    {
552
0
      g_task_report_new_error (mount, callback, user_data,
553
0
                               g_mount_unmount_with_operation,
554
0
                               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
0
    }
561
562
0
  if (iface->unmount_with_operation != NULL)
563
0
    (* iface->unmount_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
564
0
  else
565
0
    (* iface->unmount) (mount, flags, cancellable, callback, user_data);
566
0
}
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
g_mount_unmount_with_operation_finish (GMount        *mount,
584
                                       GAsyncResult  *result,
585
                                       GError       **error)
586
0
{
587
0
  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
0
  else
601
0
    return (* iface->unmount_finish) (mount, result, error);
602
0
}
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
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
0
{
629
0
  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
0
    {
637
0
      g_task_report_new_error (mount, callback, user_data,
638
0
                               g_mount_eject_with_operation,
639
0
                               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
0
    }
646
647
0
  if (iface->eject_with_operation != NULL)
648
0
    (* iface->eject_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
649
0
  else
650
0
    (* iface->eject) (mount, flags, cancellable, callback, user_data);
651
0
}
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
g_mount_eject_with_operation_finish (GMount        *mount,
669
                                     GAsyncResult  *result,
670
                                     GError       **error)
671
0
{
672
0
  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
0
  else
686
0
    return (* iface->eject_finish) (mount, result, error);
687
0
}
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
g_mount_remount (GMount              *mount,
711
                 GMountMountFlags     flags,
712
                 GMountOperation     *mount_operation,
713
                 GCancellable        *cancellable,
714
                 GAsyncReadyCallback  callback,
715
                 gpointer             user_data)
716
0
{
717
0
  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
0
    { 
725
0
      g_task_report_new_error (mount, callback, user_data,
726
0
                               g_mount_remount,
727
0
                               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
0
    }
734
  
735
0
  (* iface->remount) (mount, flags, mount_operation, cancellable, callback, user_data);
736
0
}
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
g_mount_remount_finish (GMount        *mount,
752
                        GAsyncResult  *result,
753
                        GError       **error)
754
0
{
755
0
  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
0
}
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
g_mount_guess_content_type (GMount              *mount,
794
                            gboolean             force_rescan,
795
                            GCancellable        *cancellable,
796
                            GAsyncReadyCallback  callback,
797
                            gpointer             user_data)
798
0
{
799
0
  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
0
    {
807
0
      g_task_report_new_error (mount, callback, user_data,
808
0
                               g_mount_guess_content_type,
809
0
                               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
0
    }
816
  
817
0
  (* iface->guess_content_type) (mount, force_rescan, cancellable, callback, user_data);
818
0
}
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
g_mount_guess_content_type_finish (GMount        *mount,
840
                                   GAsyncResult  *result,
841
                                   GError       **error)
842
0
{
843
0
  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
0
}
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
g_mount_guess_content_type_sync (GMount              *mount,
883
                                 gboolean             force_rescan,
884
                                 GCancellable        *cancellable,
885
                                 GError             **error)
886
0
{
887
0
  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
0
    {
895
0
      g_set_error_literal (error,
896
0
                           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
0
                           _("mount doesn’t implement synchronous content type guessing"));
901
902
0
      return NULL;
903
0
    }
904
905
0
  return (* iface->guess_content_type_sync) (mount, force_rescan, cancellable, error);
906
0
}
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
free_private (GMountPrivate *private)
918
0
{
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
get_private (GMount *mount)
927
0
{
928
0
  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
0
                          "g-mount-private",
937
0
                          private,
938
0
                          (GDestroyNotify) free_private);
939
940
0
 out:
941
0
  return private;
942
0
}
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
g_mount_is_shadowed (GMount *mount)
978
0
{
979
0
  GMountPrivate *priv;
980
0
  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
0
}
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
g_mount_shadow (GMount *mount)
1005
0
{
1006
0
  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
0
}
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
g_mount_unshadow (GMount *mount)
1029
0
{
1030
0
  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
0
}
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
g_mount_get_sort_key (GMount  *mount)
1054
0
{
1055
0
  const gchar *ret = NULL;
1056
0
  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
0
}