Coverage Report

Created: 2026-07-16 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/irssi/subprojects/glib-2.74.7/gio/gfile.c
Line
Count
Source
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-2007 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
 */
24
25
#include "config.h"
26
27
#ifdef __linux__
28
#include <sys/ioctl.h>
29
#include <errno.h>
30
/* See linux.git/fs/btrfs/ioctl.h */
31
#define BTRFS_IOCTL_MAGIC 0x94
32
0
#define BTRFS_IOC_CLONE _IOW(BTRFS_IOCTL_MAGIC, 9, int)
33
#endif
34
35
#ifdef HAVE_SPLICE
36
#include <sys/stat.h>
37
#include <unistd.h>
38
#include <fcntl.h>
39
#include <errno.h>
40
41
/*
42
 * We duplicate the following Linux kernel header defines here so we can still
43
 * run at full speed on modern kernels in cases where an old toolchain was used
44
 * to build GLib. This is often done deliberately to allow shipping binaries
45
 * that need to run on a wide range of systems.
46
 */
47
#ifndef F_SETPIPE_SZ
48
#define F_SETPIPE_SZ 1031
49
#endif
50
#ifndef F_GETPIPE_SZ
51
#define F_GETPIPE_SZ 1032
52
#endif
53
54
#endif
55
56
#include <string.h>
57
#include <sys/types.h>
58
59
#include "gfile.h"
60
#include "glib/gstdio.h"
61
#ifdef G_OS_UNIX
62
#include "glib-unix.h"
63
#endif
64
#include "gvfs.h"
65
#include "gtask.h"
66
#include "gfileattribute-priv.h"
67
#include "gfiledescriptorbased.h"
68
#include "gpollfilemonitor.h"
69
#include "gappinfo.h"
70
#include "gfileinputstream.h"
71
#include "gfileoutputstream.h"
72
#include "glocalfileoutputstream.h"
73
#include "glocalfileiostream.h"
74
#include "glocalfile.h"
75
#include "gcancellable.h"
76
#include "gasyncresult.h"
77
#include "gioerror.h"
78
#include "glibintl.h"
79
80
81
/**
82
 * SECTION:gfile
83
 * @short_description: File and Directory Handling
84
 * @include: gio/gio.h
85
 * @see_also: #GFileInfo, #GFileEnumerator
86
 *
87
 * #GFile is a high level abstraction for manipulating files on a
88
 * virtual file system. #GFiles are lightweight, immutable objects
89
 * that do no I/O upon creation. It is necessary to understand that
90
 * #GFile objects do not represent files, merely an identifier for a
91
 * file. All file content I/O is implemented as streaming operations
92
 * (see #GInputStream and #GOutputStream).
93
 *
94
 * To construct a #GFile, you can use:
95
 * - g_file_new_for_path() if you have a path.
96
 * - g_file_new_for_uri() if you have a URI.
97
 * - g_file_new_for_commandline_arg() for a command line argument.
98
 * - g_file_new_tmp() to create a temporary file from a template.
99
 * - g_file_new_tmp_async() to asynchronously create a temporary file.
100
 * - g_file_new_tmp_dir_async() to asynchronously create a temporary directory.
101
 * - g_file_parse_name() from a UTF-8 string gotten from g_file_get_parse_name().
102
 * - g_file_new_build_filename() to create a file from path elements.
103
 *
104
 * One way to think of a #GFile is as an abstraction of a pathname. For
105
 * normal files the system pathname is what is stored internally, but as
106
 * #GFiles are extensible it could also be something else that corresponds
107
 * to a pathname in a userspace implementation of a filesystem.
108
 *
109
 * #GFiles make up hierarchies of directories and files that correspond to
110
 * the files on a filesystem. You can move through the file system with
111
 * #GFile using g_file_get_parent() to get an identifier for the parent
112
 * directory, g_file_get_child() to get a child within a directory,
113
 * g_file_resolve_relative_path() to resolve a relative path between two
114
 * #GFiles. There can be multiple hierarchies, so you may not end up at
115
 * the same root if you repeatedly call g_file_get_parent() on two different
116
 * files.
117
 *
118
 * All #GFiles have a basename (get with g_file_get_basename()). These names
119
 * are byte strings that are used to identify the file on the filesystem
120
 * (relative to its parent directory) and there is no guarantees that they
121
 * have any particular charset encoding or even make any sense at all. If
122
 * you want to use filenames in a user interface you should use the display
123
 * name that you can get by requesting the
124
 * %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME attribute with g_file_query_info().
125
 * This is guaranteed to be in UTF-8 and can be used in a user interface.
126
 * But always store the real basename or the #GFile to use to actually
127
 * access the file, because there is no way to go from a display name to
128
 * the actual name.
129
 *
130
 * Using #GFile as an identifier has the same weaknesses as using a path
131
 * in that there may be multiple aliases for the same file. For instance,
132
 * hard or soft links may cause two different #GFiles to refer to the same
133
 * file. Other possible causes for aliases are: case insensitive filesystems,
134
 * short and long names on FAT/NTFS, or bind mounts in Linux. If you want to
135
 * check if two #GFiles point to the same file you can query for the
136
 * %G_FILE_ATTRIBUTE_ID_FILE attribute. Note that #GFile does some trivial
137
 * canonicalization of pathnames passed in, so that trivial differences in
138
 * the path string used at creation (duplicated slashes, slash at end of
139
 * path, "." or ".." path segments, etc) does not create different #GFiles.
140
 *
141
 * Many #GFile operations have both synchronous and asynchronous versions
142
 * to suit your application. Asynchronous versions of synchronous functions
143
 * simply have _async() appended to their function names. The asynchronous
144
 * I/O functions call a #GAsyncReadyCallback which is then used to finalize
145
 * the operation, producing a GAsyncResult which is then passed to the
146
 * function's matching _finish() operation.
147
 *
148
 * It is highly recommended to use asynchronous calls when running within a
149
 * shared main loop, such as in the main thread of an application. This avoids
150
 * I/O operations blocking other sources on the main loop from being dispatched.
151
 * Synchronous I/O operations should be performed from worker threads. See the
152
 * [introduction to asynchronous programming section][async-programming] for
153
 * more.
154
 *
155
 * Some #GFile operations almost always take a noticeable amount of time, and
156
 * so do not have synchronous analogs. Notable cases include:
157
 * - g_file_mount_mountable() to mount a mountable file.
158
 * - g_file_unmount_mountable_with_operation() to unmount a mountable file.
159
 * - g_file_eject_mountable_with_operation() to eject a mountable file.
160
 *
161
 * ## Entity Tags # {#gfile-etag}
162
 *
163
 * One notable feature of #GFiles are entity tags, or "etags" for
164
 * short. Entity tags are somewhat like a more abstract version of the
165
 * traditional mtime, and can be used to quickly determine if the file
166
 * has been modified from the version on the file system. See the
167
 * HTTP 1.1 
168
 * [specification](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html)
169
 * for HTTP Etag headers, which are a very similar concept.
170
 */
171
172
static void               g_file_real_query_info_async            (GFile                  *file,
173
                                                                   const char             *attributes,
174
                                                                   GFileQueryInfoFlags     flags,
175
                                                                   int                     io_priority,
176
                                                                   GCancellable           *cancellable,
177
                                                                   GAsyncReadyCallback     callback,
178
                                                                   gpointer                user_data);
179
static GFileInfo *        g_file_real_query_info_finish           (GFile                  *file,
180
                                                                   GAsyncResult           *res,
181
                                                                   GError                **error);
182
static void               g_file_real_query_filesystem_info_async (GFile                  *file,
183
                                                                   const char             *attributes,
184
                                                                   int                     io_priority,
185
                                                                   GCancellable           *cancellable,
186
                                                                   GAsyncReadyCallback     callback,
187
                                                                   gpointer                user_data);
188
static GFileInfo *        g_file_real_query_filesystem_info_finish (GFile                  *file,
189
                                                                   GAsyncResult           *res,
190
                                                                   GError                **error);
191
static void               g_file_real_enumerate_children_async    (GFile                  *file,
192
                                                                   const char             *attributes,
193
                                                                   GFileQueryInfoFlags     flags,
194
                                                                   int                     io_priority,
195
                                                                   GCancellable           *cancellable,
196
                                                                   GAsyncReadyCallback     callback,
197
                                                                   gpointer                user_data);
198
static GFileEnumerator *  g_file_real_enumerate_children_finish   (GFile                  *file,
199
                                                                   GAsyncResult           *res,
200
                                                                   GError                **error);
201
static void               g_file_real_read_async                  (GFile                  *file,
202
                                                                   int                     io_priority,
203
                                                                   GCancellable           *cancellable,
204
                                                                   GAsyncReadyCallback     callback,
205
                                                                   gpointer                user_data);
206
static GFileInputStream * g_file_real_read_finish                 (GFile                  *file,
207
                                                                   GAsyncResult           *res,
208
                                                                   GError                **error);
209
static void               g_file_real_append_to_async             (GFile                  *file,
210
                                                                   GFileCreateFlags        flags,
211
                                                                   int                     io_priority,
212
                                                                   GCancellable           *cancellable,
213
                                                                   GAsyncReadyCallback     callback,
214
                                                                   gpointer                user_data);
215
static GFileOutputStream *g_file_real_append_to_finish            (GFile                  *file,
216
                                                                   GAsyncResult           *res,
217
                                                                   GError                **error);
218
static void               g_file_real_create_async                (GFile                  *file,
219
                                                                   GFileCreateFlags        flags,
220
                                                                   int                     io_priority,
221
                                                                   GCancellable           *cancellable,
222
                                                                   GAsyncReadyCallback     callback,
223
                                                                   gpointer                user_data);
224
static GFileOutputStream *g_file_real_create_finish               (GFile                  *file,
225
                                                                   GAsyncResult           *res,
226
                                                                   GError                **error);
227
static void               g_file_real_replace_async               (GFile                  *file,
228
                                                                   const char             *etag,
229
                                                                   gboolean                make_backup,
230
                                                                   GFileCreateFlags        flags,
231
                                                                   int                     io_priority,
232
                                                                   GCancellable           *cancellable,
233
                                                                   GAsyncReadyCallback     callback,
234
                                                                   gpointer                user_data);
235
static GFileOutputStream *g_file_real_replace_finish              (GFile                  *file,
236
                                                                   GAsyncResult           *res,
237
                                                                   GError                **error);
238
static void               g_file_real_delete_async                (GFile                  *file,
239
                                                                   int                     io_priority,
240
                                                                   GCancellable           *cancellable,
241
                                                                   GAsyncReadyCallback     callback,
242
                                                                   gpointer                user_data);
243
static gboolean           g_file_real_delete_finish               (GFile                  *file,
244
                                                                   GAsyncResult           *res,
245
                                                                   GError                **error);
246
static void               g_file_real_trash_async                 (GFile                  *file,
247
                                                                   int                     io_priority,
248
                                                                   GCancellable           *cancellable,
249
                                                                   GAsyncReadyCallback     callback,
250
                                                                   gpointer                user_data);
251
static gboolean           g_file_real_trash_finish                (GFile                  *file,
252
                                                                   GAsyncResult           *res,
253
                                                                   GError                **error);
254
static void               g_file_real_move_async                  (GFile                  *source,
255
                                                                   GFile                  *destination,
256
                                                                   GFileCopyFlags          flags,
257
                                                                   int                     io_priority,
258
                                                                   GCancellable           *cancellable,
259
                                                                   GFileProgressCallback   progress_callback,
260
                                                                   gpointer                progress_callback_data,
261
                                                                   GAsyncReadyCallback     callback,
262
                                                                   gpointer                user_data);
263
static gboolean           g_file_real_move_finish                 (GFile                  *file,
264
                                                                   GAsyncResult           *result,
265
                                                                   GError                **error);
266
static void               g_file_real_make_directory_async        (GFile                  *file,
267
                                                                   int                     io_priority,
268
                                                                   GCancellable           *cancellable,
269
                                                                   GAsyncReadyCallback     callback,
270
                                                                   gpointer                user_data);
271
static gboolean           g_file_real_make_directory_finish       (GFile                  *file,
272
                                                                   GAsyncResult           *res,
273
                                                                   GError                **error);
274
static void               g_file_real_make_symbolic_link_async    (GFile                  *file,
275
                                                                   const char             *symlink_value,
276
                                                                   int                     io_priority,
277
                                                                   GCancellable           *cancellable,
278
                                                                   GAsyncReadyCallback     callback,
279
                                                                   gpointer                user_data);
280
static gboolean           g_file_real_make_symbolic_link_finish   (GFile                  *file,
281
                                                                   GAsyncResult           *result,
282
                                                                   GError                **error);
283
static void               g_file_real_open_readwrite_async        (GFile                  *file,
284
                                                                   int                  io_priority,
285
                                                                   GCancellable           *cancellable,
286
                                                                   GAsyncReadyCallback     callback,
287
                                                                   gpointer                user_data);
288
static GFileIOStream *    g_file_real_open_readwrite_finish       (GFile                  *file,
289
                                                                   GAsyncResult           *res,
290
                                                                   GError                **error);
291
static void               g_file_real_create_readwrite_async      (GFile                  *file,
292
                                                                   GFileCreateFlags        flags,
293
                                                                   int                     io_priority,
294
                                                                   GCancellable           *cancellable,
295
                                                                   GAsyncReadyCallback     callback,
296
                                                                   gpointer                user_data);
297
static GFileIOStream *    g_file_real_create_readwrite_finish     (GFile                  *file,
298
                                                                   GAsyncResult           *res,
299
                                                                   GError                **error);
300
static void               g_file_real_replace_readwrite_async     (GFile                  *file,
301
                                                                   const char             *etag,
302
                                                                   gboolean                make_backup,
303
                                                                   GFileCreateFlags        flags,
304
                                                                   int                     io_priority,
305
                                                                   GCancellable           *cancellable,
306
                                                                   GAsyncReadyCallback     callback,
307
                                                                   gpointer                user_data);
308
static GFileIOStream *    g_file_real_replace_readwrite_finish    (GFile                  *file,
309
                                                                  GAsyncResult            *res,
310
                                                                  GError                 **error);
311
static gboolean           g_file_real_set_attributes_from_info    (GFile                  *file,
312
                                                                   GFileInfo              *info,
313
                                                                   GFileQueryInfoFlags     flags,
314
                                                                   GCancellable           *cancellable,
315
                                                                   GError                **error);
316
static void               g_file_real_set_display_name_async      (GFile                  *file,
317
                                                                   const char             *display_name,
318
                                                                   int                     io_priority,
319
                                                                   GCancellable           *cancellable,
320
                                                                   GAsyncReadyCallback     callback,
321
                                                                   gpointer                user_data);
322
static GFile *            g_file_real_set_display_name_finish     (GFile                  *file,
323
                                                                   GAsyncResult           *res,
324
                                                                   GError                **error);
325
static void               g_file_real_set_attributes_async        (GFile                  *file,
326
                                                                   GFileInfo              *info,
327
                                                                   GFileQueryInfoFlags     flags,
328
                                                                   int                     io_priority,
329
                                                                   GCancellable           *cancellable,
330
                                                                   GAsyncReadyCallback     callback,
331
                                                                   gpointer                user_data);
332
static gboolean           g_file_real_set_attributes_finish       (GFile                  *file,
333
                                                                   GAsyncResult           *res,
334
                                                                   GFileInfo             **info,
335
                                                                   GError                **error);
336
static void               g_file_real_find_enclosing_mount_async  (GFile                  *file,
337
                                                                   int                     io_priority,
338
                                                                   GCancellable           *cancellable,
339
                                                                   GAsyncReadyCallback     callback,
340
                                                                   gpointer                user_data);
341
static GMount *           g_file_real_find_enclosing_mount_finish (GFile                  *file,
342
                                                                   GAsyncResult           *res,
343
                                                                   GError                **error);
344
static void               g_file_real_copy_async                  (GFile                  *source,
345
                                                                   GFile                  *destination,
346
                                                                   GFileCopyFlags          flags,
347
                                                                   int                     io_priority,
348
                                                                   GCancellable           *cancellable,
349
                                                                   GFileProgressCallback   progress_callback,
350
                                                                   gpointer                progress_callback_data,
351
                                                                   GAsyncReadyCallback     callback,
352
                                                                   gpointer                user_data);
353
static gboolean           g_file_real_copy_finish                 (GFile                  *file,
354
                                                                   GAsyncResult           *res,
355
                                                                   GError                **error);
356
357
static gboolean           g_file_real_measure_disk_usage          (GFile                         *file,
358
                                                                   GFileMeasureFlags              flags,
359
                                                                   GCancellable                  *cancellable,
360
                                                                   GFileMeasureProgressCallback   progress_callback,
361
                                                                   gpointer                       progress_data,
362
                                                                   guint64                       *disk_usage,
363
                                                                   guint64                       *num_dirs,
364
                                                                   guint64                       *num_files,
365
                                                                   GError                       **error);
366
static void               g_file_real_measure_disk_usage_async    (GFile                         *file,
367
                                                                   GFileMeasureFlags              flags,
368
                                                                   gint                           io_priority,
369
                                                                   GCancellable                  *cancellable,
370
                                                                   GFileMeasureProgressCallback   progress_callback,
371
                                                                   gpointer                       progress_data,
372
                                                                   GAsyncReadyCallback            callback,
373
                                                                   gpointer                       user_data);
374
static gboolean           g_file_real_measure_disk_usage_finish   (GFile                         *file,
375
                                                                   GAsyncResult                  *result,
376
                                                                   guint64                       *disk_usage,
377
                                                                   guint64                       *num_dirs,
378
                                                                   guint64                       *num_files,
379
                                                                   GError                       **error);
380
381
typedef GFileIface GFileInterface;
382
0
G_DEFINE_INTERFACE (GFile, g_file, G_TYPE_OBJECT)
383
0
384
0
static void
385
0
g_file_default_init (GFileIface *iface)
386
0
{
387
0
  iface->enumerate_children_async = g_file_real_enumerate_children_async;
388
0
  iface->enumerate_children_finish = g_file_real_enumerate_children_finish;
389
0
  iface->set_display_name_async = g_file_real_set_display_name_async;
390
0
  iface->set_display_name_finish = g_file_real_set_display_name_finish;
391
0
  iface->query_info_async = g_file_real_query_info_async;
392
0
  iface->query_info_finish = g_file_real_query_info_finish;
393
0
  iface->query_filesystem_info_async = g_file_real_query_filesystem_info_async;
394
0
  iface->query_filesystem_info_finish = g_file_real_query_filesystem_info_finish;
395
0
  iface->set_attributes_async = g_file_real_set_attributes_async;
396
0
  iface->set_attributes_finish = g_file_real_set_attributes_finish;
397
0
  iface->read_async = g_file_real_read_async;
398
0
  iface->read_finish = g_file_real_read_finish;
399
0
  iface->append_to_async = g_file_real_append_to_async;
400
0
  iface->append_to_finish = g_file_real_append_to_finish;
401
0
  iface->create_async = g_file_real_create_async;
402
0
  iface->create_finish = g_file_real_create_finish;
403
0
  iface->replace_async = g_file_real_replace_async;
404
0
  iface->replace_finish = g_file_real_replace_finish;
405
0
  iface->delete_file_async = g_file_real_delete_async;
406
0
  iface->delete_file_finish = g_file_real_delete_finish;
407
0
  iface->trash_async = g_file_real_trash_async;
408
0
  iface->trash_finish = g_file_real_trash_finish;
409
0
  iface->move_async = g_file_real_move_async;
410
0
  iface->move_finish = g_file_real_move_finish;
411
0
  iface->make_directory_async = g_file_real_make_directory_async;
412
0
  iface->make_directory_finish = g_file_real_make_directory_finish;
413
0
  iface->make_symbolic_link_async = g_file_real_make_symbolic_link_async;
414
0
  iface->make_symbolic_link_finish = g_file_real_make_symbolic_link_finish;
415
0
  iface->open_readwrite_async = g_file_real_open_readwrite_async;
416
0
  iface->open_readwrite_finish = g_file_real_open_readwrite_finish;
417
0
  iface->create_readwrite_async = g_file_real_create_readwrite_async;
418
0
  iface->create_readwrite_finish = g_file_real_create_readwrite_finish;
419
0
  iface->replace_readwrite_async = g_file_real_replace_readwrite_async;
420
0
  iface->replace_readwrite_finish = g_file_real_replace_readwrite_finish;
421
0
  iface->find_enclosing_mount_async = g_file_real_find_enclosing_mount_async;
422
0
  iface->find_enclosing_mount_finish = g_file_real_find_enclosing_mount_finish;
423
0
  iface->set_attributes_from_info = g_file_real_set_attributes_from_info;
424
0
  iface->copy_async = g_file_real_copy_async;
425
0
  iface->copy_finish = g_file_real_copy_finish;
426
0
  iface->measure_disk_usage = g_file_real_measure_disk_usage;
427
0
  iface->measure_disk_usage_async = g_file_real_measure_disk_usage_async;
428
0
  iface->measure_disk_usage_finish = g_file_real_measure_disk_usage_finish;
429
0
}
430
431
432
/**
433
 * g_file_is_native:
434
 * @file: input #GFile
435
 *
436
 * Checks to see if a file is native to the platform.
437
 *
438
 * A native file is one expressed in the platform-native filename format,
439
 * e.g. "C:\Windows" or "/usr/bin/". This does not mean the file is local,
440
 * as it might be on a locally mounted remote filesystem.
441
 *
442
 * On some systems non-native files may be available using the native
443
 * filesystem via a userspace filesystem (FUSE), in these cases this call
444
 * will return %FALSE, but g_file_get_path() will still return a native path.
445
 *
446
 * This call does no blocking I/O.
447
 *
448
 * Returns: %TRUE if @file is native
449
 */
450
gboolean
451
g_file_is_native (GFile *file)
452
0
{
453
0
  GFileIface *iface;
454
455
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
456
457
0
  iface = G_FILE_GET_IFACE (file);
458
459
0
  return (* iface->is_native) (file);
460
0
}
461
462
463
/**
464
 * g_file_has_uri_scheme:
465
 * @file: input #GFile
466
 * @uri_scheme: a string containing a URI scheme
467
 *
468
 * Checks to see if a #GFile has a given URI scheme.
469
 *
470
 * This call does no blocking I/O.
471
 *
472
 * Returns: %TRUE if #GFile's backend supports the
473
 *   given URI scheme, %FALSE if URI scheme is %NULL,
474
 *   not supported, or #GFile is invalid.
475
 */
476
gboolean
477
g_file_has_uri_scheme (GFile      *file,
478
                       const char *uri_scheme)
479
0
{
480
0
  GFileIface *iface;
481
482
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
483
0
  g_return_val_if_fail (uri_scheme != NULL, FALSE);
484
485
0
  iface = G_FILE_GET_IFACE (file);
486
487
0
  return (* iface->has_uri_scheme) (file, uri_scheme);
488
0
}
489
490
491
/**
492
 * g_file_get_uri_scheme:
493
 * @file: input #GFile
494
 *
495
 * Gets the URI scheme for a #GFile.
496
 * RFC 3986 decodes the scheme as:
497
 * |[
498
 * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
499
 * ]|
500
 * Common schemes include "file", "http", "ftp", etc.
501
 *
502
 * The scheme can be different from the one used to construct the #GFile,
503
 * in that it might be replaced with one that is logically equivalent to the #GFile.
504
 *
505
 * This call does no blocking I/O.
506
 *
507
 * Returns: (nullable): a string containing the URI scheme for the given
508
 *   #GFile or %NULL if the #GFile was constructed with an invalid URI. The
509
 *   returned string should be freed with g_free() when no longer needed.
510
 */
511
char *
512
g_file_get_uri_scheme (GFile *file)
513
0
{
514
0
  GFileIface *iface;
515
516
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
517
518
0
  iface = G_FILE_GET_IFACE (file);
519
520
0
  return (* iface->get_uri_scheme) (file);
521
0
}
522
523
524
/**
525
 * g_file_get_basename: (virtual get_basename)
526
 * @file: input #GFile
527
 *
528
 * Gets the base name (the last component of the path) for a given #GFile.
529
 *
530
 * If called for the top level of a system (such as the filesystem root
531
 * or a uri like sftp://host/) it will return a single directory separator
532
 * (and on Windows, possibly a drive letter).
533
 *
534
 * The base name is a byte string (not UTF-8). It has no defined encoding
535
 * or rules other than it may not contain zero bytes.  If you want to use
536
 * filenames in a user interface you should use the display name that you
537
 * can get by requesting the %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME
538
 * attribute with g_file_query_info().
539
 *
540
 * This call does no blocking I/O.
541
 *
542
 * Returns: (type filename) (nullable): string containing the #GFile's
543
 *   base name, or %NULL if given #GFile is invalid. The returned string
544
 *   should be freed with g_free() when no longer needed.
545
 */
546
char *
547
g_file_get_basename (GFile *file)
548
0
{
549
0
  GFileIface *iface;
550
551
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
552
553
0
  iface = G_FILE_GET_IFACE (file);
554
555
0
  return (* iface->get_basename) (file);
556
0
}
557
558
/**
559
 * g_file_get_path: (virtual get_path)
560
 * @file: input #GFile
561
 *
562
 * Gets the local pathname for #GFile, if one exists. If non-%NULL, this is
563
 * guaranteed to be an absolute, canonical path. It might contain symlinks.
564
 *
565
 * This call does no blocking I/O.
566
 *
567
 * Returns: (type filename) (nullable): string containing the #GFile's path,
568
 *   or %NULL if no such path exists. The returned string should be freed
569
 *   with g_free() when no longer needed.
570
 */
571
char *
572
g_file_get_path (GFile *file)
573
0
{
574
0
  GFileIface *iface;
575
576
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
577
578
0
  iface = G_FILE_GET_IFACE (file);
579
580
0
  return (* iface->get_path) (file);
581
0
}
582
583
static const char *
584
file_peek_path_generic (GFile *file)
585
0
{
586
0
  const char *path;
587
0
  static GQuark _file_path_quark = 0;
588
589
0
  if (G_UNLIKELY (_file_path_quark) == 0)
590
0
    _file_path_quark = g_quark_from_static_string ("gio-file-path");
591
592
  /* We need to be careful about threading, as two threads calling
593
   * g_file_peek_path() on the same file could race: both would see
594
   * (g_object_get_qdata(…) == NULL) to begin with, both would generate and add
595
   * the path, but the second thread to add it would end up freeing the path
596
   * set by the first thread. The first thread would still return the pointer
597
   * to that freed path, though, resulting an a read-after-free. Handle that
598
   * with a compare-and-swap loop. The g_object_*_qdata() functions are atomic. */
599
600
0
  while (TRUE)
601
0
    {
602
0
      gchar *new_path = NULL;
603
604
0
      path = g_object_get_qdata ((GObject*)file, _file_path_quark);
605
606
0
      if (path != NULL)
607
0
        break;
608
609
0
      new_path = g_file_get_path (file);
610
0
      if (new_path == NULL)
611
0
        return NULL;
612
613
      /* By passing NULL here, we ensure we never replace existing data: */
614
0
      if (g_object_replace_qdata ((GObject *) file, _file_path_quark,
615
0
                                  NULL, (gpointer) new_path,
616
0
                                  (GDestroyNotify) g_free, NULL))
617
0
        {
618
0
          path = new_path;
619
0
          break;
620
0
        }
621
0
      else
622
0
        g_free (new_path);
623
0
    }
624
625
0
  return path;
626
0
}
627
628
/**
629
 * g_file_peek_path:
630
 * @file: input #GFile
631
 *
632
 * Exactly like g_file_get_path(), but caches the result via
633
 * g_object_set_qdata_full().  This is useful for example in C
634
 * applications which mix `g_file_*` APIs with native ones.  It
635
 * also avoids an extra duplicated string when possible, so will be
636
 * generally more efficient.
637
 *
638
 * This call does no blocking I/O.
639
 *
640
 * Returns: (type filename) (nullable): string containing the #GFile's path,
641
 *   or %NULL if no such path exists. The returned string is owned by @file.
642
 * Since: 2.56
643
 */
644
const char *
645
g_file_peek_path (GFile *file)
646
0
{
647
0
  if (G_IS_LOCAL_FILE (file))
648
0
    return _g_local_file_get_filename ((GLocalFile *) file);
649
0
  return file_peek_path_generic (file);
650
0
}
651
652
/**
653
 * g_file_get_uri:
654
 * @file: input #GFile
655
 *
656
 * Gets the URI for the @file.
657
 *
658
 * This call does no blocking I/O.
659
 *
660
 * Returns: a string containing the #GFile's URI. If the #GFile was constructed
661
 *   with an invalid URI, an invalid URI is returned.
662
 *   The returned string should be freed with g_free()
663
 *   when no longer needed.
664
 */
665
char *
666
g_file_get_uri (GFile *file)
667
0
{
668
0
  GFileIface *iface;
669
670
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
671
672
0
  iface = G_FILE_GET_IFACE (file);
673
674
0
  return (* iface->get_uri) (file);
675
0
}
676
677
/**
678
 * g_file_get_parse_name:
679
 * @file: input #GFile
680
 *
681
 * Gets the parse name of the @file.
682
 * A parse name is a UTF-8 string that describes the
683
 * file such that one can get the #GFile back using
684
 * g_file_parse_name().
685
 *
686
 * This is generally used to show the #GFile as a nice
687
 * full-pathname kind of string in a user interface,
688
 * like in a location entry.
689
 *
690
 * For local files with names that can safely be converted
691
 * to UTF-8 the pathname is used, otherwise the IRI is used
692
 * (a form of URI that allows UTF-8 characters unescaped).
693
 *
694
 * This call does no blocking I/O.
695
 *
696
 * Returns: a string containing the #GFile's parse name.
697
 *   The returned string should be freed with g_free()
698
 *   when no longer needed.
699
 */
700
char *
701
g_file_get_parse_name (GFile *file)
702
0
{
703
0
  GFileIface *iface;
704
705
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
706
707
0
  iface = G_FILE_GET_IFACE (file);
708
709
0
  return (* iface->get_parse_name) (file);
710
0
}
711
712
/**
713
 * g_file_dup:
714
 * @file: input #GFile
715
 *
716
 * Duplicates a #GFile handle. This operation does not duplicate
717
 * the actual file or directory represented by the #GFile; see
718
 * g_file_copy() if attempting to copy a file.
719
 *
720
 * g_file_dup() is useful when a second handle is needed to the same underlying
721
 * file, for use in a separate thread (#GFile is not thread-safe). For use
722
 * within the same thread, use g_object_ref() to increment the existing object’s
723
 * reference count.
724
 *
725
 * This call does no blocking I/O.
726
 *
727
 * Returns: (transfer full): a new #GFile that is a duplicate
728
 *   of the given #GFile.
729
 */
730
GFile *
731
g_file_dup (GFile *file)
732
0
{
733
0
  GFileIface *iface;
734
735
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
736
737
0
  iface = G_FILE_GET_IFACE (file);
738
739
0
  return (* iface->dup) (file);
740
0
}
741
742
/**
743
 * g_file_hash:
744
 * @file: (type GFile): #gconstpointer to a #GFile
745
 *
746
 * Creates a hash value for a #GFile.
747
 *
748
 * This call does no blocking I/O.
749
 *
750
 * Virtual: hash
751
 * Returns: 0 if @file is not a valid #GFile, otherwise an
752
 *   integer that can be used as hash value for the #GFile.
753
 *   This function is intended for easily hashing a #GFile to
754
 *   add to a #GHashTable or similar data structure.
755
 */
756
guint
757
g_file_hash (gconstpointer file)
758
0
{
759
0
  GFileIface *iface;
760
761
0
  g_return_val_if_fail (G_IS_FILE (file), 0);
762
763
0
  iface = G_FILE_GET_IFACE (file);
764
765
0
  return (* iface->hash) ((GFile *)file);
766
0
}
767
768
/**
769
 * g_file_equal:
770
 * @file1: the first #GFile
771
 * @file2: the second #GFile
772
 *
773
 * Checks if the two given #GFiles refer to the same file.
774
 *
775
 * Note that two #GFiles that differ can still refer to the same
776
 * file on the filesystem due to various forms of filename
777
 * aliasing.
778
 *
779
 * This call does no blocking I/O.
780
 *
781
 * Returns: %TRUE if @file1 and @file2 are equal.
782
 */
783
gboolean
784
g_file_equal (GFile *file1,
785
              GFile *file2)
786
0
{
787
0
  GFileIface *iface;
788
789
0
  g_return_val_if_fail (G_IS_FILE (file1), FALSE);
790
0
  g_return_val_if_fail (G_IS_FILE (file2), FALSE);
791
792
0
  if (file1 == file2)
793
0
    return TRUE;
794
795
0
  if (G_TYPE_FROM_INSTANCE (file1) != G_TYPE_FROM_INSTANCE (file2))
796
0
    return FALSE;
797
798
0
  iface = G_FILE_GET_IFACE (file1);
799
800
0
  return (* iface->equal) (file1, file2);
801
0
}
802
803
804
/**
805
 * g_file_get_parent:
806
 * @file: input #GFile
807
 *
808
 * Gets the parent directory for the @file.
809
 * If the @file represents the root directory of the
810
 * file system, then %NULL will be returned.
811
 *
812
 * This call does no blocking I/O.
813
 *
814
 * Returns: (nullable) (transfer full): a #GFile structure to the
815
 *   parent of the given #GFile or %NULL if there is no parent. Free
816
 *   the returned object with g_object_unref().
817
 */
818
GFile *
819
g_file_get_parent (GFile *file)
820
0
{
821
0
  GFileIface *iface;
822
823
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
824
825
0
  iface = G_FILE_GET_IFACE (file);
826
827
0
  return (* iface->get_parent) (file);
828
0
}
829
830
/**
831
 * g_file_has_parent:
832
 * @file: input #GFile
833
 * @parent: (nullable): the parent to check for, or %NULL
834
 *
835
 * Checks if @file has a parent, and optionally, if it is @parent.
836
 *
837
 * If @parent is %NULL then this function returns %TRUE if @file has any
838
 * parent at all.  If @parent is non-%NULL then %TRUE is only returned
839
 * if @file is an immediate child of @parent.
840
 *
841
 * Returns: %TRUE if @file is an immediate child of @parent (or any parent in
842
 *   the case that @parent is %NULL).
843
 *
844
 * Since: 2.24
845
 */
846
gboolean
847
g_file_has_parent (GFile *file,
848
                   GFile *parent)
849
0
{
850
0
  GFile *actual_parent;
851
0
  gboolean result;
852
853
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
854
0
  g_return_val_if_fail (parent == NULL || G_IS_FILE (parent), FALSE);
855
856
0
  actual_parent = g_file_get_parent (file);
857
858
0
  if (actual_parent != NULL)
859
0
    {
860
0
      if (parent != NULL)
861
0
        result = g_file_equal (parent, actual_parent);
862
0
      else
863
0
        result = TRUE;
864
865
0
      g_object_unref (actual_parent);
866
0
    }
867
0
  else
868
0
    result = FALSE;
869
870
0
  return result;
871
0
}
872
873
/**
874
 * g_file_get_child:
875
 * @file: input #GFile
876
 * @name: (type filename): string containing the child's basename
877
 *
878
 * Gets a child of @file with basename equal to @name.
879
 *
880
 * Note that the file with that specific name might not exist, but
881
 * you can still have a #GFile that points to it. You can use this
882
 * for instance to create that file.
883
 *
884
 * This call does no blocking I/O.
885
 *
886
 * Returns: (transfer full): a #GFile to a child specified by @name.
887
 *   Free the returned object with g_object_unref().
888
 */
889
GFile *
890
g_file_get_child (GFile      *file,
891
                  const char *name)
892
0
{
893
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
894
0
  g_return_val_if_fail (name != NULL, NULL);
895
0
  g_return_val_if_fail (!g_path_is_absolute (name), NULL);
896
897
0
  return g_file_resolve_relative_path (file, name);
898
0
}
899
900
/**
901
 * g_file_get_child_for_display_name:
902
 * @file: input #GFile
903
 * @display_name: string to a possible child
904
 * @error: return location for an error
905
 *
906
 * Gets the child of @file for a given @display_name (i.e. a UTF-8
907
 * version of the name). If this function fails, it returns %NULL
908
 * and @error will be set. This is very useful when constructing a
909
 * #GFile for a new file and the user entered the filename in the
910
 * user interface, for instance when you select a directory and
911
 * type a filename in the file selector.
912
 *
913
 * This call does no blocking I/O.
914
 *
915
 * Returns: (transfer full): a #GFile to the specified child, or
916
 *   %NULL if the display name couldn't be converted.
917
 *   Free the returned object with g_object_unref().
918
 */
919
GFile *
920
g_file_get_child_for_display_name (GFile      *file,
921
                                   const char *display_name,
922
                                   GError **error)
923
0
{
924
0
  GFileIface *iface;
925
926
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
927
0
  g_return_val_if_fail (display_name != NULL, NULL);
928
929
0
  iface = G_FILE_GET_IFACE (file);
930
931
0
  return (* iface->get_child_for_display_name) (file, display_name, error);
932
0
}
933
934
/**
935
 * g_file_has_prefix:
936
 * @file: input #GFile
937
 * @prefix: input #GFile
938
 *
939
 * Checks whether @file has the prefix specified by @prefix.
940
 *
941
 * In other words, if the names of initial elements of @file's
942
 * pathname match @prefix. Only full pathname elements are matched,
943
 * so a path like /foo is not considered a prefix of /foobar, only
944
 * of /foo/bar.
945
 *
946
 * A #GFile is not a prefix of itself. If you want to check for
947
 * equality, use g_file_equal().
948
 *
949
 * This call does no I/O, as it works purely on names. As such it can
950
 * sometimes return %FALSE even if @file is inside a @prefix (from a
951
 * filesystem point of view), because the prefix of @file is an alias
952
 * of @prefix.
953
 *
954
 * Virtual: prefix_matches
955
 * Returns:  %TRUE if the @file's parent, grandparent, etc is @prefix,
956
 *   %FALSE otherwise.
957
 */
958
gboolean
959
g_file_has_prefix (GFile *file,
960
                   GFile *prefix)
961
0
{
962
0
  GFileIface *iface;
963
964
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
965
0
  g_return_val_if_fail (G_IS_FILE (prefix), FALSE);
966
967
0
  if (G_TYPE_FROM_INSTANCE (file) != G_TYPE_FROM_INSTANCE (prefix))
968
0
    return FALSE;
969
970
0
  iface = G_FILE_GET_IFACE (file);
971
972
  /* The vtable function differs in arg order since
973
   * we're using the old contains_file call
974
   */
975
0
  return (* iface->prefix_matches) (prefix, file);
976
0
}
977
978
/**
979
 * g_file_get_relative_path: (virtual get_relative_path)
980
 * @parent: input #GFile
981
 * @descendant: input #GFile
982
 *
983
 * Gets the path for @descendant relative to @parent.
984
 *
985
 * This call does no blocking I/O.
986
 *
987
 * Returns: (type filename) (nullable): string with the relative path from
988
 *   @descendant to @parent, or %NULL if @descendant doesn't have @parent as
989
 *   prefix. The returned string should be freed with g_free() when
990
 *   no longer needed.
991
 */
992
char *
993
g_file_get_relative_path (GFile *parent,
994
                          GFile *descendant)
995
0
{
996
0
  GFileIface *iface;
997
998
0
  g_return_val_if_fail (G_IS_FILE (parent), NULL);
999
0
  g_return_val_if_fail (G_IS_FILE (descendant), NULL);
1000
1001
0
  if (G_TYPE_FROM_INSTANCE (parent) != G_TYPE_FROM_INSTANCE (descendant))
1002
0
    return NULL;
1003
1004
0
  iface = G_FILE_GET_IFACE (parent);
1005
1006
0
  return (* iface->get_relative_path) (parent, descendant);
1007
0
}
1008
1009
/**
1010
 * g_file_resolve_relative_path:
1011
 * @file: input #GFile
1012
 * @relative_path: (type filename): a given relative path string
1013
 *
1014
 * Resolves a relative path for @file to an absolute path.
1015
 *
1016
 * This call does no blocking I/O.
1017
 *
1018
 * If the @relative_path is an absolute path name, the resolution
1019
 * is done absolutely (without taking @file path as base).
1020
 *
1021
 * Returns: (transfer full): a #GFile for the resolved path.
1022
 */
1023
GFile *
1024
g_file_resolve_relative_path (GFile      *file,
1025
                              const char *relative_path)
1026
0
{
1027
0
  GFileIface *iface;
1028
1029
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1030
0
  g_return_val_if_fail (relative_path != NULL, NULL);
1031
1032
0
  iface = G_FILE_GET_IFACE (file);
1033
1034
0
  return (* iface->resolve_relative_path) (file, relative_path);
1035
0
}
1036
1037
/**
1038
 * g_file_enumerate_children:
1039
 * @file: input #GFile
1040
 * @attributes: an attribute query string
1041
 * @flags: a set of #GFileQueryInfoFlags
1042
 * @cancellable: (nullable): optional #GCancellable object,
1043
 *   %NULL to ignore
1044
 * @error: #GError for error reporting
1045
 *
1046
 * Gets the requested information about the files in a directory.
1047
 * The result is a #GFileEnumerator object that will give out
1048
 * #GFileInfo objects for all the files in the directory.
1049
 *
1050
 * The @attributes value is a string that specifies the file
1051
 * attributes that should be gathered. It is not an error if
1052
 * it's not possible to read a particular requested attribute
1053
 * from a file - it just won't be set. @attributes should
1054
 * be a comma-separated list of attributes or attribute wildcards.
1055
 * The wildcard "*" means all attributes, and a wildcard like
1056
 * "standard::*" means all attributes in the standard namespace.
1057
 * An example attribute query be "standard::*,owner::user".
1058
 * The standard attributes are available as defines, like
1059
 * %G_FILE_ATTRIBUTE_STANDARD_NAME. %G_FILE_ATTRIBUTE_STANDARD_NAME should
1060
 * always be specified if you plan to call g_file_enumerator_get_child() or
1061
 * g_file_enumerator_iterate() on the returned enumerator.
1062
 *
1063
 * If @cancellable is not %NULL, then the operation can be cancelled
1064
 * by triggering the cancellable object from another thread. If the
1065
 * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be
1066
 * returned.
1067
 *
1068
 * If the file does not exist, the %G_IO_ERROR_NOT_FOUND error will
1069
 * be returned. If the file is not a directory, the %G_IO_ERROR_NOT_DIRECTORY
1070
 * error will be returned. Other errors are possible too.
1071
 *
1072
 * Returns: (transfer full): A #GFileEnumerator if successful,
1073
 *   %NULL on error. Free the returned object with g_object_unref().
1074
 */
1075
GFileEnumerator *
1076
g_file_enumerate_children (GFile                *file,
1077
                           const char           *attributes,
1078
                           GFileQueryInfoFlags   flags,
1079
                           GCancellable         *cancellable,
1080
                           GError              **error)
1081
0
{
1082
0
  GFileIface *iface;
1083
1084
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1085
1086
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1087
0
    return NULL;
1088
1089
0
  iface = G_FILE_GET_IFACE (file);
1090
1091
0
  if (iface->enumerate_children == NULL)
1092
0
    {
1093
0
      g_set_error_literal (error, G_IO_ERROR,
1094
0
                           G_IO_ERROR_NOT_SUPPORTED,
1095
0
                           _("Operation not supported"));
1096
0
      return NULL;
1097
0
    }
1098
1099
0
  return (* iface->enumerate_children) (file, attributes, flags,
1100
0
                                        cancellable, error);
1101
0
}
1102
1103
/**
1104
 * g_file_enumerate_children_async:
1105
 * @file: input #GFile
1106
 * @attributes: an attribute query string
1107
 * @flags: a set of #GFileQueryInfoFlags
1108
 * @io_priority: the [I/O priority][io-priority] of the request
1109
 * @cancellable: (nullable): optional #GCancellable object,
1110
 *   %NULL to ignore
1111
 * @callback: (scope async): a #GAsyncReadyCallback to call when the
1112
 *   request is satisfied
1113
 * @user_data: (closure): the data to pass to callback function
1114
 *
1115
 * Asynchronously gets the requested information about the files
1116
 * in a directory. The result is a #GFileEnumerator object that will
1117
 * give out #GFileInfo objects for all the files in the directory.
1118
 *
1119
 * For more details, see g_file_enumerate_children() which is
1120
 * the synchronous version of this call.
1121
 *
1122
 * When the operation is finished, @callback will be called. You can
1123
 * then call g_file_enumerate_children_finish() to get the result of
1124
 * the operation.
1125
 */
1126
void
1127
g_file_enumerate_children_async (GFile               *file,
1128
                                 const char          *attributes,
1129
                                 GFileQueryInfoFlags  flags,
1130
                                 int                  io_priority,
1131
                                 GCancellable        *cancellable,
1132
                                 GAsyncReadyCallback  callback,
1133
                                 gpointer             user_data)
1134
0
{
1135
0
  GFileIface *iface;
1136
1137
0
  g_return_if_fail (G_IS_FILE (file));
1138
1139
0
  iface = G_FILE_GET_IFACE (file);
1140
0
  (* iface->enumerate_children_async) (file,
1141
0
                                       attributes,
1142
0
                                       flags,
1143
0
                                       io_priority,
1144
0
                                       cancellable,
1145
0
                                       callback,
1146
0
                                       user_data);
1147
0
}
1148
1149
/**
1150
 * g_file_enumerate_children_finish:
1151
 * @file: input #GFile
1152
 * @res: a #GAsyncResult
1153
 * @error: a #GError
1154
 *
1155
 * Finishes an async enumerate children operation.
1156
 * See g_file_enumerate_children_async().
1157
 *
1158
 * Returns: (transfer full): a #GFileEnumerator or %NULL
1159
 *   if an error occurred.
1160
 *   Free the returned object with g_object_unref().
1161
 */
1162
GFileEnumerator *
1163
g_file_enumerate_children_finish (GFile         *file,
1164
                                  GAsyncResult  *res,
1165
                                  GError       **error)
1166
0
{
1167
0
  GFileIface *iface;
1168
1169
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1170
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1171
1172
0
  if (g_async_result_legacy_propagate_error (res, error))
1173
0
    return NULL;
1174
1175
0
  iface = G_FILE_GET_IFACE (file);
1176
0
  return (* iface->enumerate_children_finish) (file, res, error);
1177
0
}
1178
1179
/**
1180
 * g_file_query_exists:
1181
 * @file: input #GFile
1182
 * @cancellable: (nullable): optional #GCancellable object,
1183
 *   %NULL to ignore
1184
 *
1185
 * Utility function to check if a particular file exists. This is
1186
 * implemented using g_file_query_info() and as such does blocking I/O.
1187
 *
1188
 * Note that in many cases it is [racy to first check for file existence](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use)
1189
 * and then execute something based on the outcome of that, because the
1190
 * file might have been created or removed in between the operations. The
1191
 * general approach to handling that is to not check, but just do the
1192
 * operation and handle the errors as they come.
1193
 *
1194
 * As an example of race-free checking, take the case of reading a file,
1195
 * and if it doesn't exist, creating it. There are two racy versions: read
1196
 * it, and on error create it; and: check if it exists, if not create it.
1197
 * These can both result in two processes creating the file (with perhaps
1198
 * a partially written file as the result). The correct approach is to
1199
 * always try to create the file with g_file_create() which will either
1200
 * atomically create the file or fail with a %G_IO_ERROR_EXISTS error.
1201
 *
1202
 * However, in many cases an existence check is useful in a user interface,
1203
 * for instance to make a menu item sensitive/insensitive, so that you don't
1204
 * have to fool users that something is possible and then just show an error
1205
 * dialog. If you do this, you should make sure to also handle the errors
1206
 * that can happen due to races when you execute the operation.
1207
 *
1208
 * Returns: %TRUE if the file exists (and can be detected without error),
1209
 *   %FALSE otherwise (or if cancelled).
1210
 */
1211
gboolean
1212
g_file_query_exists (GFile        *file,
1213
                     GCancellable *cancellable)
1214
0
{
1215
0
  GFileInfo *info;
1216
1217
0
  g_return_val_if_fail (G_IS_FILE(file), FALSE);
1218
1219
0
  info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE,
1220
0
                            G_FILE_QUERY_INFO_NONE, cancellable, NULL);
1221
0
  if (info != NULL)
1222
0
    {
1223
0
      g_object_unref (info);
1224
0
      return TRUE;
1225
0
    }
1226
1227
0
  return FALSE;
1228
0
}
1229
1230
/**
1231
 * g_file_query_file_type:
1232
 * @file: input #GFile
1233
 * @flags: a set of #GFileQueryInfoFlags passed to g_file_query_info()
1234
 * @cancellable: (nullable): optional #GCancellable object,
1235
 *   %NULL to ignore
1236
 *
1237
 * Utility function to inspect the #GFileType of a file. This is
1238
 * implemented using g_file_query_info() and as such does blocking I/O.
1239
 *
1240
 * The primary use case of this method is to check if a file is
1241
 * a regular file, directory, or symlink.
1242
 *
1243
 * Returns: The #GFileType of the file and %G_FILE_TYPE_UNKNOWN
1244
 *   if the file does not exist
1245
 *
1246
 * Since: 2.18
1247
 */
1248
GFileType
1249
g_file_query_file_type (GFile               *file,
1250
                        GFileQueryInfoFlags  flags,
1251
                        GCancellable        *cancellable)
1252
0
{
1253
0
  GFileInfo *info;
1254
0
  GFileType file_type;
1255
1256
0
  g_return_val_if_fail (G_IS_FILE(file), G_FILE_TYPE_UNKNOWN);
1257
0
  info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, flags,
1258
0
                            cancellable, NULL);
1259
0
  if (info != NULL)
1260
0
    {
1261
0
      file_type = g_file_info_get_file_type (info);
1262
0
      g_object_unref (info);
1263
0
    }
1264
0
  else
1265
0
    file_type = G_FILE_TYPE_UNKNOWN;
1266
1267
0
  return file_type;
1268
0
}
1269
1270
/**
1271
 * g_file_query_info:
1272
 * @file: input #GFile
1273
 * @attributes: an attribute query string
1274
 * @flags: a set of #GFileQueryInfoFlags
1275
 * @cancellable: (nullable): optional #GCancellable object,
1276
 *   %NULL to ignore
1277
 * @error: a #GError
1278
 *
1279
 * Gets the requested information about specified @file.
1280
 * The result is a #GFileInfo object that contains key-value
1281
 * attributes (such as the type or size of the file).
1282
 *
1283
 * The @attributes value is a string that specifies the file
1284
 * attributes that should be gathered. It is not an error if
1285
 * it's not possible to read a particular requested attribute
1286
 * from a file - it just won't be set. @attributes should be a
1287
 * comma-separated list of attributes or attribute wildcards.
1288
 * The wildcard "*" means all attributes, and a wildcard like
1289
 * "standard::*" means all attributes in the standard namespace.
1290
 * An example attribute query be "standard::*,owner::user".
1291
 * The standard attributes are available as defines, like
1292
 * %G_FILE_ATTRIBUTE_STANDARD_NAME.
1293
 *
1294
 * If @cancellable is not %NULL, then the operation can be cancelled
1295
 * by triggering the cancellable object from another thread. If the
1296
 * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be
1297
 * returned.
1298
 *
1299
 * For symlinks, normally the information about the target of the
1300
 * symlink is returned, rather than information about the symlink
1301
 * itself. However if you pass %G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS
1302
 * in @flags the information about the symlink itself will be returned.
1303
 * Also, for symlinks that point to non-existing files the information
1304
 * about the symlink itself will be returned.
1305
 *
1306
 * If the file does not exist, the %G_IO_ERROR_NOT_FOUND error will be
1307
 * returned. Other errors are possible too, and depend on what kind of
1308
 * filesystem the file is on.
1309
 *
1310
 * Returns: (transfer full): a #GFileInfo for the given @file, or %NULL
1311
 *   on error. Free the returned object with g_object_unref().
1312
 */
1313
GFileInfo *
1314
g_file_query_info (GFile                *file,
1315
                   const char           *attributes,
1316
                   GFileQueryInfoFlags   flags,
1317
                   GCancellable         *cancellable,
1318
                   GError              **error)
1319
0
{
1320
0
  GFileIface *iface;
1321
1322
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1323
1324
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1325
0
    return NULL;
1326
1327
0
  iface = G_FILE_GET_IFACE (file);
1328
1329
0
  if (iface->query_info == NULL)
1330
0
    {
1331
0
      g_set_error_literal (error, G_IO_ERROR,
1332
0
                           G_IO_ERROR_NOT_SUPPORTED,
1333
0
                           _("Operation not supported"));
1334
0
      return NULL;
1335
0
    }
1336
1337
0
  return (* iface->query_info) (file, attributes, flags, cancellable, error);
1338
0
}
1339
1340
/**
1341
 * g_file_query_info_async:
1342
 * @file: input #GFile
1343
 * @attributes: an attribute query string
1344
 * @flags: a set of #GFileQueryInfoFlags
1345
 * @io_priority: the [I/O priority][io-priority] of the request
1346
 * @cancellable: (nullable): optional #GCancellable object,
1347
 *   %NULL to ignore
1348
 * @callback: (scope async): a #GAsyncReadyCallback to call when the
1349
 *   request is satisfied
1350
 * @user_data: (closure): the data to pass to callback function
1351
 *
1352
 * Asynchronously gets the requested information about specified @file.
1353
 * The result is a #GFileInfo object that contains key-value attributes
1354
 * (such as type or size for the file).
1355
 *
1356
 * For more details, see g_file_query_info() which is the synchronous
1357
 * version of this call.
1358
 *
1359
 * When the operation is finished, @callback will be called. You can
1360
 * then call g_file_query_info_finish() to get the result of the operation.
1361
 */
1362
void
1363
g_file_query_info_async (GFile               *file,
1364
                         const char          *attributes,
1365
                         GFileQueryInfoFlags  flags,
1366
                         int                  io_priority,
1367
                         GCancellable        *cancellable,
1368
                         GAsyncReadyCallback  callback,
1369
                         gpointer             user_data)
1370
0
{
1371
0
  GFileIface *iface;
1372
1373
0
  g_return_if_fail (G_IS_FILE (file));
1374
1375
0
  iface = G_FILE_GET_IFACE (file);
1376
0
  (* iface->query_info_async) (file,
1377
0
                               attributes,
1378
0
                               flags,
1379
0
                               io_priority,
1380
0
                               cancellable,
1381
0
                               callback,
1382
0
                               user_data);
1383
0
}
1384
1385
/**
1386
 * g_file_query_info_finish:
1387
 * @file: input #GFile
1388
 * @res: a #GAsyncResult
1389
 * @error: a #GError
1390
 *
1391
 * Finishes an asynchronous file info query.
1392
 * See g_file_query_info_async().
1393
 *
1394
 * Returns: (transfer full): #GFileInfo for given @file
1395
 *   or %NULL on error. Free the returned object with
1396
 *   g_object_unref().
1397
 */
1398
GFileInfo *
1399
g_file_query_info_finish (GFile         *file,
1400
                          GAsyncResult  *res,
1401
                          GError       **error)
1402
0
{
1403
0
  GFileIface *iface;
1404
1405
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1406
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1407
1408
0
  if (g_async_result_legacy_propagate_error (res, error))
1409
0
    return NULL;
1410
1411
0
  iface = G_FILE_GET_IFACE (file);
1412
0
  return (* iface->query_info_finish) (file, res, error);
1413
0
}
1414
1415
/**
1416
 * g_file_query_filesystem_info:
1417
 * @file: input #GFile
1418
 * @attributes:  an attribute query string
1419
 * @cancellable: (nullable): optional #GCancellable object,
1420
 *   %NULL to ignore
1421
 * @error: a #GError
1422
 *
1423
 * Similar to g_file_query_info(), but obtains information
1424
 * about the filesystem the @file is on, rather than the file itself.
1425
 * For instance the amount of space available and the type of
1426
 * the filesystem.
1427
 *
1428
 * The @attributes value is a string that specifies the attributes
1429
 * that should be gathered. It is not an error if it's not possible
1430
 * to read a particular requested attribute from a file - it just
1431
 * won't be set. @attributes should be a comma-separated list of
1432
 * attributes or attribute wildcards. The wildcard "*" means all
1433
 * attributes, and a wildcard like "filesystem::*" means all attributes
1434
 * in the filesystem namespace. The standard namespace for filesystem
1435
 * attributes is "filesystem". Common attributes of interest are
1436
 * %G_FILE_ATTRIBUTE_FILESYSTEM_SIZE (the total size of the filesystem
1437
 * in bytes), %G_FILE_ATTRIBUTE_FILESYSTEM_FREE (number of bytes available),
1438
 * and %G_FILE_ATTRIBUTE_FILESYSTEM_TYPE (type of the filesystem).
1439
 *
1440
 * If @cancellable is not %NULL, then the operation can be cancelled
1441
 * by triggering the cancellable object from another thread. If the
1442
 * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be
1443
 * returned.
1444
 *
1445
 * If the file does not exist, the %G_IO_ERROR_NOT_FOUND error will
1446
 * be returned. Other errors are possible too, and depend on what
1447
 * kind of filesystem the file is on.
1448
 *
1449
 * Returns: (transfer full): a #GFileInfo or %NULL if there was an error.
1450
 *   Free the returned object with g_object_unref().
1451
 */
1452
GFileInfo *
1453
g_file_query_filesystem_info (GFile         *file,
1454
                              const char    *attributes,
1455
                              GCancellable  *cancellable,
1456
                              GError       **error)
1457
0
{
1458
0
  GFileIface *iface;
1459
1460
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1461
1462
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1463
0
    return NULL;
1464
1465
0
  iface = G_FILE_GET_IFACE (file);
1466
1467
0
  if (iface->query_filesystem_info == NULL)
1468
0
    {
1469
0
      g_set_error_literal (error, G_IO_ERROR,
1470
0
                           G_IO_ERROR_NOT_SUPPORTED,
1471
0
                           _("Operation not supported"));
1472
0
      return NULL;
1473
0
    }
1474
1475
0
  return (* iface->query_filesystem_info) (file, attributes, cancellable, error);
1476
0
}
1477
1478
/**
1479
 * g_file_query_filesystem_info_async:
1480
 * @file: input #GFile
1481
 * @attributes: an attribute query string
1482
 * @io_priority: the [I/O priority][io-priority] of the request
1483
 * @cancellable: (nullable): optional #GCancellable object,
1484
 *   %NULL to ignore
1485
 * @callback: (scope async): a #GAsyncReadyCallback to call
1486
 *   when the request is satisfied
1487
 * @user_data: (closure): the data to pass to callback function
1488
 *
1489
 * Asynchronously gets the requested information about the filesystem
1490
 * that the specified @file is on. The result is a #GFileInfo object
1491
 * that contains key-value attributes (such as type or size for the
1492
 * file).
1493
 *
1494
 * For more details, see g_file_query_filesystem_info() which is the
1495
 * synchronous version of this call.
1496
 *
1497
 * When the operation is finished, @callback will be called. You can
1498
 * then call g_file_query_info_finish() to get the result of the
1499
 * operation.
1500
 */
1501
void
1502
g_file_query_filesystem_info_async (GFile               *file,
1503
                                    const char          *attributes,
1504
                                    int                  io_priority,
1505
                                    GCancellable        *cancellable,
1506
                                    GAsyncReadyCallback  callback,
1507
                                    gpointer             user_data)
1508
0
{
1509
0
  GFileIface *iface;
1510
1511
0
  g_return_if_fail (G_IS_FILE (file));
1512
1513
0
  iface = G_FILE_GET_IFACE (file);
1514
0
  (* iface->query_filesystem_info_async) (file,
1515
0
                                          attributes,
1516
0
                                          io_priority,
1517
0
                                          cancellable,
1518
0
                                          callback,
1519
0
                                          user_data);
1520
0
}
1521
1522
/**
1523
 * g_file_query_filesystem_info_finish:
1524
 * @file: input #GFile
1525
 * @res: a #GAsyncResult
1526
 * @error: a #GError
1527
 *
1528
 * Finishes an asynchronous filesystem info query.
1529
 * See g_file_query_filesystem_info_async().
1530
 *
1531
 * Returns: (transfer full): #GFileInfo for given @file
1532
 *   or %NULL on error.
1533
 *   Free the returned object with g_object_unref().
1534
 */
1535
GFileInfo *
1536
g_file_query_filesystem_info_finish (GFile         *file,
1537
                                     GAsyncResult  *res,
1538
                                     GError       **error)
1539
0
{
1540
0
  GFileIface *iface;
1541
1542
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1543
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1544
1545
0
  if (g_async_result_legacy_propagate_error (res, error))
1546
0
    return NULL;
1547
1548
0
  iface = G_FILE_GET_IFACE (file);
1549
0
  return (* iface->query_filesystem_info_finish) (file, res, error);
1550
0
}
1551
1552
/**
1553
 * g_file_find_enclosing_mount:
1554
 * @file: input #GFile
1555
 * @cancellable: (nullable): optional #GCancellable object,
1556
 *   %NULL to ignore
1557
 * @error: a #GError
1558
 *
1559
 * Gets a #GMount for the #GFile.
1560
 *
1561
 * #GMount is returned only for user interesting locations, see
1562
 * #GVolumeMonitor. If the #GFileIface for @file does not have a #mount,
1563
 * @error will be set to %G_IO_ERROR_NOT_FOUND and %NULL #will be returned.
1564
 *
1565
 * If @cancellable is not %NULL, then the operation can be cancelled by
1566
 * triggering the cancellable object from another thread. If the operation
1567
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
1568
 *
1569
 * Returns: (transfer full): a #GMount where the @file is located
1570
 *   or %NULL on error.
1571
 *   Free the returned object with g_object_unref().
1572
 */
1573
GMount *
1574
g_file_find_enclosing_mount (GFile         *file,
1575
                             GCancellable  *cancellable,
1576
                             GError       **error)
1577
0
{
1578
0
  GFileIface *iface;
1579
1580
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1581
1582
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1583
0
    return NULL;
1584
1585
0
  iface = G_FILE_GET_IFACE (file);
1586
0
  if (iface->find_enclosing_mount == NULL)
1587
0
    {
1588
1589
0
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
1590
                           /* Translators: This is an error message when
1591
                            * trying to find the enclosing (user visible)
1592
                            * mount of a file, but none exists.
1593
                            */
1594
0
                           _("Containing mount does not exist"));
1595
0
      return NULL;
1596
0
    }
1597
1598
0
  return (* iface->find_enclosing_mount) (file, cancellable, error);
1599
0
}
1600
1601
/**
1602
 * g_file_find_enclosing_mount_async:
1603
 * @file: a #GFile
1604
 * @io_priority: the [I/O priority][io-priority] of the request
1605
 * @cancellable: (nullable): optional #GCancellable object,
1606
 *   %NULL to ignore
1607
 * @callback: (scope async): a #GAsyncReadyCallback to call
1608
 *   when the request is satisfied
1609
 * @user_data: (closure): the data to pass to callback function
1610
 *
1611
 * Asynchronously gets the mount for the file.
1612
 *
1613
 * For more details, see g_file_find_enclosing_mount() which is
1614
 * the synchronous version of this call.
1615
 *
1616
 * When the operation is finished, @callback will be called.
1617
 * You can then call g_file_find_enclosing_mount_finish() to
1618
 * get the result of the operation.
1619
 */
1620
void
1621
g_file_find_enclosing_mount_async (GFile              *file,
1622
                                   int                   io_priority,
1623
                                   GCancellable         *cancellable,
1624
                                   GAsyncReadyCallback   callback,
1625
                                   gpointer              user_data)
1626
0
{
1627
0
  GFileIface *iface;
1628
1629
0
  g_return_if_fail (G_IS_FILE (file));
1630
1631
0
  iface = G_FILE_GET_IFACE (file);
1632
0
  (* iface->find_enclosing_mount_async) (file,
1633
0
                                         io_priority,
1634
0
                                         cancellable,
1635
0
                                         callback,
1636
0
                                         user_data);
1637
0
}
1638
1639
/**
1640
 * g_file_find_enclosing_mount_finish:
1641
 * @file: a #GFile
1642
 * @res: a #GAsyncResult
1643
 * @error: a #GError
1644
 *
1645
 * Finishes an asynchronous find mount request.
1646
 * See g_file_find_enclosing_mount_async().
1647
 *
1648
 * Returns: (transfer full): #GMount for given @file or %NULL on error.
1649
 *   Free the returned object with g_object_unref().
1650
 */
1651
GMount *
1652
g_file_find_enclosing_mount_finish (GFile         *file,
1653
                                    GAsyncResult  *res,
1654
                                    GError       **error)
1655
0
{
1656
0
  GFileIface *iface;
1657
1658
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1659
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1660
1661
0
  if (g_async_result_legacy_propagate_error (res, error))
1662
0
    return NULL;
1663
1664
0
  iface = G_FILE_GET_IFACE (file);
1665
0
  return (* iface->find_enclosing_mount_finish) (file, res, error);
1666
0
}
1667
1668
1669
/**
1670
 * g_file_read:
1671
 * @file: #GFile to read
1672
 * @cancellable: (nullable): a #GCancellable
1673
 * @error: a #GError, or %NULL
1674
 *
1675
 * Opens a file for reading. The result is a #GFileInputStream that
1676
 * can be used to read the contents of the file.
1677
 *
1678
 * If @cancellable is not %NULL, then the operation can be cancelled by
1679
 * triggering the cancellable object from another thread. If the operation
1680
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
1681
 *
1682
 * If the file does not exist, the %G_IO_ERROR_NOT_FOUND error will be
1683
 * returned. If the file is a directory, the %G_IO_ERROR_IS_DIRECTORY
1684
 * error will be returned. Other errors are possible too, and depend
1685
 * on what kind of filesystem the file is on.
1686
 *
1687
 * Virtual: read_fn
1688
 * Returns: (transfer full): #GFileInputStream or %NULL on error.
1689
 *   Free the returned object with g_object_unref().
1690
 */
1691
GFileInputStream *
1692
g_file_read (GFile         *file,
1693
             GCancellable  *cancellable,
1694
             GError       **error)
1695
0
{
1696
0
  GFileIface *iface;
1697
1698
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1699
1700
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1701
0
    return NULL;
1702
1703
0
  iface = G_FILE_GET_IFACE (file);
1704
1705
0
  if (iface->read_fn == NULL)
1706
0
    {
1707
0
      g_set_error_literal (error, G_IO_ERROR,
1708
0
                           G_IO_ERROR_NOT_SUPPORTED,
1709
0
                           _("Operation not supported"));
1710
0
      return NULL;
1711
0
    }
1712
1713
0
  return (* iface->read_fn) (file, cancellable, error);
1714
0
}
1715
1716
/**
1717
 * g_file_append_to:
1718
 * @file: input #GFile
1719
 * @flags: a set of #GFileCreateFlags
1720
 * @cancellable: (nullable): optional #GCancellable object,
1721
 *   %NULL to ignore
1722
 * @error: a #GError, or %NULL
1723
 *
1724
 * Gets an output stream for appending data to the file.
1725
 * If the file doesn't already exist it is created.
1726
 *
1727
 * By default files created are generally readable by everyone,
1728
 * but if you pass %G_FILE_CREATE_PRIVATE in @flags the file
1729
 * will be made readable only to the current user, to the level that
1730
 * is supported on the target filesystem.
1731
 *
1732
 * If @cancellable is not %NULL, then the operation can be cancelled
1733
 * by triggering the cancellable object from another thread. If the
1734
 * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be
1735
 * returned.
1736
 *
1737
 * Some file systems don't allow all file names, and may return an
1738
 * %G_IO_ERROR_INVALID_FILENAME error. If the file is a directory the
1739
 * %G_IO_ERROR_IS_DIRECTORY error will be returned. Other errors are
1740
 * possible too, and depend on what kind of filesystem the file is on.
1741
 *
1742
 * Returns: (transfer full): a #GFileOutputStream, or %NULL on error.
1743
 *   Free the returned object with g_object_unref().
1744
 */
1745
GFileOutputStream *
1746
g_file_append_to (GFile             *file,
1747
                  GFileCreateFlags   flags,
1748
                  GCancellable      *cancellable,
1749
                  GError           **error)
1750
0
{
1751
0
  GFileIface *iface;
1752
1753
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1754
1755
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1756
0
    return NULL;
1757
1758
0
  iface = G_FILE_GET_IFACE (file);
1759
1760
0
  if (iface->append_to == NULL)
1761
0
    {
1762
0
      g_set_error_literal (error, G_IO_ERROR,
1763
0
                           G_IO_ERROR_NOT_SUPPORTED,
1764
0
                           _("Operation not supported"));
1765
0
      return NULL;
1766
0
    }
1767
1768
0
  return (* iface->append_to) (file, flags, cancellable, error);
1769
0
}
1770
1771
/**
1772
 * g_file_create:
1773
 * @file: input #GFile
1774
 * @flags: a set of #GFileCreateFlags
1775
 * @cancellable: (nullable): optional #GCancellable object,
1776
 *   %NULL to ignore
1777
 * @error: a #GError, or %NULL
1778
 *
1779
 * Creates a new file and returns an output stream for writing to it.
1780
 * The file must not already exist.
1781
 *
1782
 * By default files created are generally readable by everyone,
1783
 * but if you pass %G_FILE_CREATE_PRIVATE in @flags the file
1784
 * will be made readable only to the current user, to the level
1785
 * that is supported on the target filesystem.
1786
 *
1787
 * If @cancellable is not %NULL, then the operation can be cancelled
1788
 * by triggering the cancellable object from another thread. If the
1789
 * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be
1790
 * returned.
1791
 *
1792
 * If a file or directory with this name already exists the
1793
 * %G_IO_ERROR_EXISTS error will be returned. Some file systems don't
1794
 * allow all file names, and may return an %G_IO_ERROR_INVALID_FILENAME
1795
 * error, and if the name is to long %G_IO_ERROR_FILENAME_TOO_LONG will
1796
 * be returned. Other errors are possible too, and depend on what kind
1797
 * of filesystem the file is on.
1798
 *
1799
 * Returns: (transfer full): a #GFileOutputStream for the newly created
1800
 *   file, or %NULL on error.
1801
 *   Free the returned object with g_object_unref().
1802
 */
1803
GFileOutputStream *
1804
g_file_create (GFile             *file,
1805
               GFileCreateFlags   flags,
1806
               GCancellable      *cancellable,
1807
               GError           **error)
1808
0
{
1809
0
  GFileIface *iface;
1810
1811
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1812
1813
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1814
0
    return NULL;
1815
1816
0
  iface = G_FILE_GET_IFACE (file);
1817
1818
0
  if (iface->create == NULL)
1819
0
    {
1820
0
      g_set_error_literal (error, G_IO_ERROR,
1821
0
                           G_IO_ERROR_NOT_SUPPORTED,
1822
0
                           _("Operation not supported"));
1823
0
      return NULL;
1824
0
    }
1825
1826
0
  return (* iface->create) (file, flags, cancellable, error);
1827
0
}
1828
1829
/**
1830
 * g_file_replace:
1831
 * @file: input #GFile
1832
 * @etag: (nullable): an optional [entity tag][gfile-etag]
1833
 *   for the current #GFile, or #NULL to ignore
1834
 * @make_backup: %TRUE if a backup should be created
1835
 * @flags: a set of #GFileCreateFlags
1836
 * @cancellable: (nullable): optional #GCancellable object,
1837
 *   %NULL to ignore
1838
 * @error: a #GError, or %NULL
1839
 *
1840
 * Returns an output stream for overwriting the file, possibly
1841
 * creating a backup copy of the file first. If the file doesn't exist,
1842
 * it will be created.
1843
 *
1844
 * This will try to replace the file in the safest way possible so
1845
 * that any errors during the writing will not affect an already
1846
 * existing copy of the file. For instance, for local files it
1847
 * may write to a temporary file and then atomically rename over
1848
 * the destination when the stream is closed.
1849
 *
1850
 * By default files created are generally readable by everyone,
1851
 * but if you pass %G_FILE_CREATE_PRIVATE in @flags the file
1852
 * will be made readable only to the current user, to the level that
1853
 * is supported on the target filesystem.
1854
 *
1855
 * If @cancellable is not %NULL, then the operation can be cancelled
1856
 * by triggering the cancellable object from another thread. If the
1857
 * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be
1858
 * returned.
1859
 *
1860
 * If you pass in a non-%NULL @etag value and @file already exists, then
1861
 * this value is compared to the current entity tag of the file, and if
1862
 * they differ an %G_IO_ERROR_WRONG_ETAG error is returned. This
1863
 * generally means that the file has been changed since you last read
1864
 * it. You can get the new etag from g_file_output_stream_get_etag()
1865
 * after you've finished writing and closed the #GFileOutputStream. When
1866
 * you load a new file you can use g_file_input_stream_query_info() to
1867
 * get the etag of the file.
1868
 *
1869
 * If @make_backup is %TRUE, this function will attempt to make a
1870
 * backup of the current file before overwriting it. If this fails
1871
 * a %G_IO_ERROR_CANT_CREATE_BACKUP error will be returned. If you
1872
 * want to replace anyway, try again with @make_backup set to %FALSE.
1873
 *
1874
 * If the file is a directory the %G_IO_ERROR_IS_DIRECTORY error will
1875
 * be returned, and if the file is some other form of non-regular file
1876
 * then a %G_IO_ERROR_NOT_REGULAR_FILE error will be returned. Some
1877
 * file systems don't allow all file names, and may return an
1878
 * %G_IO_ERROR_INVALID_FILENAME error, and if the name is to long
1879
 * %G_IO_ERROR_FILENAME_TOO_LONG will be returned. Other errors are
1880
 * possible too, and depend on what kind of filesystem the file is on.
1881
 *
1882
 * Returns: (transfer full): a #GFileOutputStream or %NULL on error.
1883
 *   Free the returned object with g_object_unref().
1884
 */
1885
GFileOutputStream *
1886
g_file_replace (GFile             *file,
1887
                const char        *etag,
1888
                gboolean           make_backup,
1889
                GFileCreateFlags   flags,
1890
                GCancellable      *cancellable,
1891
                GError           **error)
1892
0
{
1893
0
  GFileIface *iface;
1894
1895
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1896
1897
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1898
0
    return NULL;
1899
1900
0
  iface = G_FILE_GET_IFACE (file);
1901
1902
0
  if (iface->replace == NULL)
1903
0
    {
1904
0
      g_set_error_literal (error, G_IO_ERROR,
1905
0
                           G_IO_ERROR_NOT_SUPPORTED,
1906
0
                           _("Operation not supported"));
1907
0
      return NULL;
1908
0
    }
1909
1910
  /* Handle empty tag string as NULL in consistent way. */
1911
0
  if (etag && *etag == 0)
1912
0
    etag = NULL;
1913
1914
0
  return (* iface->replace) (file, etag, make_backup, flags, cancellable, error);
1915
0
}
1916
1917
/**
1918
 * g_file_open_readwrite:
1919
 * @file: #GFile to open
1920
 * @cancellable: (nullable): a #GCancellable
1921
 * @error: a #GError, or %NULL
1922
 *
1923
 * Opens an existing file for reading and writing. The result is
1924
 * a #GFileIOStream that can be used to read and write the contents
1925
 * of the file.
1926
 *
1927
 * If @cancellable is not %NULL, then the operation can be cancelled
1928
 * by triggering the cancellable object from another thread. If the
1929
 * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be
1930
 * returned.
1931
 *
1932
 * If the file does not exist, the %G_IO_ERROR_NOT_FOUND error will
1933
 * be returned. If the file is a directory, the %G_IO_ERROR_IS_DIRECTORY
1934
 * error will be returned. Other errors are possible too, and depend on
1935
 * what kind of filesystem the file is on. Note that in many non-local
1936
 * file cases read and write streams are not supported, so make sure you
1937
 * really need to do read and write streaming, rather than just opening
1938
 * for reading or writing.
1939
 *
1940
 * Returns: (transfer full): #GFileIOStream or %NULL on error.
1941
 *   Free the returned object with g_object_unref().
1942
 *
1943
 * Since: 2.22
1944
 */
1945
GFileIOStream *
1946
g_file_open_readwrite (GFile         *file,
1947
                       GCancellable  *cancellable,
1948
                       GError       **error)
1949
0
{
1950
0
  GFileIface *iface;
1951
1952
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
1953
1954
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1955
0
    return NULL;
1956
1957
0
  iface = G_FILE_GET_IFACE (file);
1958
1959
0
  if (iface->open_readwrite == NULL)
1960
0
    {
1961
0
      g_set_error_literal (error, G_IO_ERROR,
1962
0
                           G_IO_ERROR_NOT_SUPPORTED,
1963
0
                           _("Operation not supported"));
1964
0
      return NULL;
1965
0
    }
1966
1967
0
  return (* iface->open_readwrite) (file, cancellable, error);
1968
0
}
1969
1970
/**
1971
 * g_file_create_readwrite:
1972
 * @file: a #GFile
1973
 * @flags: a set of #GFileCreateFlags
1974
 * @cancellable: (nullable): optional #GCancellable object,
1975
 *   %NULL to ignore
1976
 * @error: return location for a #GError, or %NULL
1977
 *
1978
 * Creates a new file and returns a stream for reading and
1979
 * writing to it. The file must not already exist.
1980
 *
1981
 * By default files created are generally readable by everyone,
1982
 * but if you pass %G_FILE_CREATE_PRIVATE in @flags the file
1983
 * will be made readable only to the current user, to the level
1984
 * that is supported on the target filesystem.
1985
 *
1986
 * If @cancellable is not %NULL, then the operation can be cancelled
1987
 * by triggering the cancellable object from another thread. If the
1988
 * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be
1989
 * returned.
1990
 *
1991
 * If a file or directory with this name already exists, the
1992
 * %G_IO_ERROR_EXISTS error will be returned. Some file systems don't
1993
 * allow all file names, and may return an %G_IO_ERROR_INVALID_FILENAME
1994
 * error, and if the name is too long, %G_IO_ERROR_FILENAME_TOO_LONG
1995
 * will be returned. Other errors are possible too, and depend on what
1996
 * kind of filesystem the file is on.
1997
 *
1998
 * Note that in many non-local file cases read and write streams are
1999
 * not supported, so make sure you really need to do read and write
2000
 * streaming, rather than just opening for reading or writing.
2001
 *
2002
 * Returns: (transfer full): a #GFileIOStream for the newly created
2003
 *   file, or %NULL on error.
2004
 *   Free the returned object with g_object_unref().
2005
 *
2006
 * Since: 2.22
2007
 */
2008
GFileIOStream *
2009
g_file_create_readwrite (GFile             *file,
2010
                         GFileCreateFlags   flags,
2011
                         GCancellable      *cancellable,
2012
                         GError           **error)
2013
0
{
2014
0
  GFileIface *iface;
2015
2016
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
2017
2018
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
2019
0
    return NULL;
2020
2021
0
  iface = G_FILE_GET_IFACE (file);
2022
2023
0
  if (iface->create_readwrite == NULL)
2024
0
    {
2025
0
      g_set_error_literal (error, G_IO_ERROR,
2026
0
                           G_IO_ERROR_NOT_SUPPORTED,
2027
0
                           _("Operation not supported"));
2028
0
      return NULL;
2029
0
    }
2030
2031
0
  return (* iface->create_readwrite) (file, flags, cancellable, error);
2032
0
}
2033
2034
/**
2035
 * g_file_replace_readwrite:
2036
 * @file: a #GFile
2037
 * @etag: (nullable): an optional [entity tag][gfile-etag]
2038
 *   for the current #GFile, or #NULL to ignore
2039
 * @make_backup: %TRUE if a backup should be created
2040
 * @flags: a set of #GFileCreateFlags
2041
 * @cancellable: (nullable): optional #GCancellable object,
2042
 *   %NULL to ignore
2043
 * @error: return location for a #GError, or %NULL
2044
 *
2045
 * Returns an output stream for overwriting the file in readwrite mode,
2046
 * possibly creating a backup copy of the file first. If the file doesn't
2047
 * exist, it will be created.
2048
 *
2049
 * For details about the behaviour, see g_file_replace() which does the
2050
 * same thing but returns an output stream only.
2051
 *
2052
 * Note that in many non-local file cases read and write streams are not
2053
 * supported, so make sure you really need to do read and write streaming,
2054
 * rather than just opening for reading or writing.
2055
 *
2056
 * Returns: (transfer full): a #GFileIOStream or %NULL on error.
2057
 *   Free the returned object with g_object_unref().
2058
 *
2059
 * Since: 2.22
2060
 */
2061
GFileIOStream *
2062
g_file_replace_readwrite (GFile             *file,
2063
                          const char        *etag,
2064
                          gboolean           make_backup,
2065
                          GFileCreateFlags   flags,
2066
                          GCancellable      *cancellable,
2067
                          GError           **error)
2068
0
{
2069
0
  GFileIface *iface;
2070
2071
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
2072
2073
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
2074
0
    return NULL;
2075
2076
0
  iface = G_FILE_GET_IFACE (file);
2077
2078
0
  if (iface->replace_readwrite == NULL)
2079
0
    {
2080
0
      g_set_error_literal (error, G_IO_ERROR,
2081
0
                           G_IO_ERROR_NOT_SUPPORTED,
2082
0
                           _("Operation not supported"));
2083
0
      return NULL;
2084
0
    }
2085
2086
0
  return (* iface->replace_readwrite) (file, etag, make_backup, flags, cancellable, error);
2087
0
}
2088
2089
/**
2090
 * g_file_read_async:
2091
 * @file: input #GFile
2092
 * @io_priority: the [I/O priority][io-priority] of the request
2093
 * @cancellable: (nullable): optional #GCancellable object,
2094
 *   %NULL to ignore
2095
 * @callback: (scope async): a #GAsyncReadyCallback to call
2096
 *   when the request is satisfied
2097
 * @user_data: (closure): the data to pass to callback function
2098
 *
2099
 * Asynchronously opens @file for reading.
2100
 *
2101
 * For more details, see g_file_read() which is
2102
 * the synchronous version of this call.
2103
 *
2104
 * When the operation is finished, @callback will be called.
2105
 * You can then call g_file_read_finish() to get the result
2106
 * of the operation.
2107
 */
2108
void
2109
g_file_read_async (GFile               *file,
2110
                   int                  io_priority,
2111
                   GCancellable        *cancellable,
2112
                   GAsyncReadyCallback  callback,
2113
                   gpointer             user_data)
2114
0
{
2115
0
  GFileIface *iface;
2116
2117
0
  g_return_if_fail (G_IS_FILE (file));
2118
2119
0
  iface = G_FILE_GET_IFACE (file);
2120
0
  (* iface->read_async) (file,
2121
0
                         io_priority,
2122
0
                         cancellable,
2123
0
                         callback,
2124
0
                         user_data);
2125
0
}
2126
2127
/**
2128
 * g_file_read_finish:
2129
 * @file: input #GFile
2130
 * @res: a #GAsyncResult
2131
 * @error: a #GError, or %NULL
2132
 *
2133
 * Finishes an asynchronous file read operation started with
2134
 * g_file_read_async().
2135
 *
2136
 * Returns: (transfer full): a #GFileInputStream or %NULL on error.
2137
 *   Free the returned object with g_object_unref().
2138
 */
2139
GFileInputStream *
2140
g_file_read_finish (GFile         *file,
2141
                    GAsyncResult  *res,
2142
                    GError       **error)
2143
0
{
2144
0
  GFileIface *iface;
2145
2146
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
2147
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2148
2149
0
  if (g_async_result_legacy_propagate_error (res, error))
2150
0
    return NULL;
2151
2152
0
  iface = G_FILE_GET_IFACE (file);
2153
0
  return (* iface->read_finish) (file, res, error);
2154
0
}
2155
2156
/**
2157
 * g_file_append_to_async:
2158
 * @file: input #GFile
2159
 * @flags: a set of #GFileCreateFlags
2160
 * @io_priority: the [I/O priority][io-priority] of the request
2161
 * @cancellable: (nullable): optional #GCancellable object,
2162
 *   %NULL to ignore
2163
 * @callback: (scope async): a #GAsyncReadyCallback to call
2164
 *   when the request is satisfied
2165
 * @user_data: (closure): the data to pass to callback function
2166
 *
2167
 * Asynchronously opens @file for appending.
2168
 *
2169
 * For more details, see g_file_append_to() which is
2170
 * the synchronous version of this call.
2171
 *
2172
 * When the operation is finished, @callback will be called.
2173
 * You can then call g_file_append_to_finish() to get the result
2174
 * of the operation.
2175
 */
2176
void
2177
g_file_append_to_async (GFile               *file,
2178
                        GFileCreateFlags     flags,
2179
                        int                  io_priority,
2180
                        GCancellable        *cancellable,
2181
                        GAsyncReadyCallback  callback,
2182
                        gpointer             user_data)
2183
0
{
2184
0
  GFileIface *iface;
2185
2186
0
  g_return_if_fail (G_IS_FILE (file));
2187
2188
0
  iface = G_FILE_GET_IFACE (file);
2189
0
  (* iface->append_to_async) (file,
2190
0
                              flags,
2191
0
                              io_priority,
2192
0
                              cancellable,
2193
0
                              callback,
2194
0
                              user_data);
2195
0
}
2196
2197
/**
2198
 * g_file_append_to_finish:
2199
 * @file: input #GFile
2200
 * @res: #GAsyncResult
2201
 * @error: a #GError, or %NULL
2202
 *
2203
 * Finishes an asynchronous file append operation started with
2204
 * g_file_append_to_async().
2205
 *
2206
 * Returns: (transfer full): a valid #GFileOutputStream
2207
 *   or %NULL on error.
2208
 *   Free the returned object with g_object_unref().
2209
 */
2210
GFileOutputStream *
2211
g_file_append_to_finish (GFile         *file,
2212
                         GAsyncResult  *res,
2213
                         GError       **error)
2214
0
{
2215
0
  GFileIface *iface;
2216
2217
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
2218
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2219
2220
0
  if (g_async_result_legacy_propagate_error (res, error))
2221
0
    return NULL;
2222
2223
0
  iface = G_FILE_GET_IFACE (file);
2224
0
  return (* iface->append_to_finish) (file, res, error);
2225
0
}
2226
2227
/**
2228
 * g_file_create_async:
2229
 * @file: input #GFile
2230
 * @flags: a set of #GFileCreateFlags
2231
 * @io_priority: the [I/O priority][io-priority] of the request
2232
 * @cancellable: (nullable): optional #GCancellable object,
2233
 *   %NULL to ignore
2234
 * @callback: (scope async): a #GAsyncReadyCallback to call
2235
 *   when the request is satisfied
2236
 * @user_data: (closure): the data to pass to callback function
2237
 *
2238
 * Asynchronously creates a new file and returns an output stream
2239
 * for writing to it. The file must not already exist.
2240
 *
2241
 * For more details, see g_file_create() which is
2242
 * the synchronous version of this call.
2243
 *
2244
 * When the operation is finished, @callback will be called.
2245
 * You can then call g_file_create_finish() to get the result
2246
 * of the operation.
2247
 */
2248
void
2249
g_file_create_async (GFile               *file,
2250
                     GFileCreateFlags     flags,
2251
                     int                  io_priority,
2252
                     GCancellable        *cancellable,
2253
                     GAsyncReadyCallback  callback,
2254
                     gpointer             user_data)
2255
0
{
2256
0
  GFileIface *iface;
2257
2258
0
  g_return_if_fail (G_IS_FILE (file));
2259
2260
0
  iface = G_FILE_GET_IFACE (file);
2261
0
  (* iface->create_async) (file,
2262
0
                           flags,
2263
0
                           io_priority,
2264
0
                           cancellable,
2265
0
                           callback,
2266
0
                           user_data);
2267
0
}
2268
2269
/**
2270
 * g_file_create_finish:
2271
 * @file: input #GFile
2272
 * @res: a #GAsyncResult
2273
 * @error: a #GError, or %NULL
2274
 *
2275
 * Finishes an asynchronous file create operation started with
2276
 * g_file_create_async().
2277
 *
2278
 * Returns: (transfer full): a #GFileOutputStream or %NULL on error.
2279
 *   Free the returned object with g_object_unref().
2280
 */
2281
GFileOutputStream *
2282
g_file_create_finish (GFile         *file,
2283
                      GAsyncResult  *res,
2284
                      GError       **error)
2285
0
{
2286
0
  GFileIface *iface;
2287
2288
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
2289
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2290
2291
0
  if (g_async_result_legacy_propagate_error (res, error))
2292
0
    return NULL;
2293
2294
0
  iface = G_FILE_GET_IFACE (file);
2295
0
  return (* iface->create_finish) (file, res, error);
2296
0
}
2297
2298
/**
2299
 * g_file_replace_async:
2300
 * @file: input #GFile
2301
 * @etag: (nullable): an [entity tag][gfile-etag] for the current #GFile,
2302
 *   or %NULL to ignore
2303
 * @make_backup: %TRUE if a backup should be created
2304
 * @flags: a set of #GFileCreateFlags
2305
 * @io_priority: the [I/O priority][io-priority] of the request
2306
 * @cancellable: (nullable): optional #GCancellable object,
2307
 *   %NULL to ignore
2308
 * @callback: (scope async): a #GAsyncReadyCallback to call
2309
 *   when the request is satisfied
2310
 * @user_data: (closure): the data to pass to callback function
2311
 *
2312
 * Asynchronously overwrites the file, replacing the contents,
2313
 * possibly creating a backup copy of the file first.
2314
 *
2315
 * For more details, see g_file_replace() which is
2316
 * the synchronous version of this call.
2317
 *
2318
 * When the operation is finished, @callback will be called.
2319
 * You can then call g_file_replace_finish() to get the result
2320
 * of the operation.
2321
 */
2322
void
2323
g_file_replace_async (GFile               *file,
2324
                      const char          *etag,
2325
                      gboolean             make_backup,
2326
                      GFileCreateFlags     flags,
2327
                      int                  io_priority,
2328
                      GCancellable        *cancellable,
2329
                      GAsyncReadyCallback  callback,
2330
                      gpointer             user_data)
2331
0
{
2332
0
  GFileIface *iface;
2333
2334
0
  g_return_if_fail (G_IS_FILE (file));
2335
2336
0
  iface = G_FILE_GET_IFACE (file);
2337
0
  (* iface->replace_async) (file,
2338
0
                            etag,
2339
0
                            make_backup,
2340
0
                            flags,
2341
0
                            io_priority,
2342
0
                            cancellable,
2343
0
                            callback,
2344
0
                            user_data);
2345
0
}
2346
2347
/**
2348
 * g_file_replace_finish:
2349
 * @file: input #GFile
2350
 * @res: a #GAsyncResult
2351
 * @error: a #GError, or %NULL
2352
 *
2353
 * Finishes an asynchronous file replace operation started with
2354
 * g_file_replace_async().
2355
 *
2356
 * Returns: (transfer full): a #GFileOutputStream, or %NULL on error.
2357
 *   Free the returned object with g_object_unref().
2358
 */
2359
GFileOutputStream *
2360
g_file_replace_finish (GFile         *file,
2361
                       GAsyncResult  *res,
2362
                       GError       **error)
2363
0
{
2364
0
  GFileIface *iface;
2365
2366
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
2367
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2368
2369
0
  if (g_async_result_legacy_propagate_error (res, error))
2370
0
    return NULL;
2371
2372
0
  iface = G_FILE_GET_IFACE (file);
2373
0
  return (* iface->replace_finish) (file, res, error);
2374
0
}
2375
2376
/**
2377
 * g_file_open_readwrite_async
2378
 * @file: input #GFile
2379
 * @io_priority: the [I/O priority][io-priority] of the request
2380
 * @cancellable: (nullable): optional #GCancellable object,
2381
 *   %NULL to ignore
2382
 * @callback: (scope async): a #GAsyncReadyCallback to call
2383
 *   when the request is satisfied
2384
 * @user_data: (closure): the data to pass to callback function
2385
 *
2386
 * Asynchronously opens @file for reading and writing.
2387
 *
2388
 * For more details, see g_file_open_readwrite() which is
2389
 * the synchronous version of this call.
2390
 *
2391
 * When the operation is finished, @callback will be called.
2392
 * You can then call g_file_open_readwrite_finish() to get
2393
 * the result of the operation.
2394
 *
2395
 * Since: 2.22
2396
 */
2397
void
2398
g_file_open_readwrite_async (GFile               *file,
2399
                             int                  io_priority,
2400
                             GCancellable        *cancellable,
2401
                             GAsyncReadyCallback  callback,
2402
                             gpointer             user_data)
2403
0
{
2404
0
  GFileIface *iface;
2405
2406
0
  g_return_if_fail (G_IS_FILE (file));
2407
2408
0
  iface = G_FILE_GET_IFACE (file);
2409
0
  (* iface->open_readwrite_async) (file,
2410
0
                                   io_priority,
2411
0
                                   cancellable,
2412
0
                                   callback,
2413
0
                                   user_data);
2414
0
}
2415
2416
/**
2417
 * g_file_open_readwrite_finish:
2418
 * @file: input #GFile
2419
 * @res: a #GAsyncResult
2420
 * @error: a #GError, or %NULL
2421
 *
2422
 * Finishes an asynchronous file read operation started with
2423
 * g_file_open_readwrite_async().
2424
 *
2425
 * Returns: (transfer full): a #GFileIOStream or %NULL on error.
2426
 *   Free the returned object with g_object_unref().
2427
 *
2428
 * Since: 2.22
2429
 */
2430
GFileIOStream *
2431
g_file_open_readwrite_finish (GFile         *file,
2432
                              GAsyncResult  *res,
2433
                              GError       **error)
2434
0
{
2435
0
  GFileIface *iface;
2436
2437
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
2438
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2439
2440
0
  if (g_async_result_legacy_propagate_error (res, error))
2441
0
    return NULL;
2442
2443
0
  iface = G_FILE_GET_IFACE (file);
2444
0
  return (* iface->open_readwrite_finish) (file, res, error);
2445
0
}
2446
2447
/**
2448
 * g_file_create_readwrite_async:
2449
 * @file: input #GFile
2450
 * @flags: a set of #GFileCreateFlags
2451
 * @io_priority: the [I/O priority][io-priority] of the request
2452
 * @cancellable: (nullable): optional #GCancellable object,
2453
 *   %NULL to ignore
2454
 * @callback: (scope async): a #GAsyncReadyCallback to call
2455
 *   when the request is satisfied
2456
 * @user_data: (closure): the data to pass to callback function
2457
 *
2458
 * Asynchronously creates a new file and returns a stream
2459
 * for reading and writing to it. The file must not already exist.
2460
 *
2461
 * For more details, see g_file_create_readwrite() which is
2462
 * the synchronous version of this call.
2463
 *
2464
 * When the operation is finished, @callback will be called.
2465
 * You can then call g_file_create_readwrite_finish() to get
2466
 * the result of the operation.
2467
 *
2468
 * Since: 2.22
2469
 */
2470
void
2471
g_file_create_readwrite_async (GFile               *file,
2472
                               GFileCreateFlags     flags,
2473
                               int                  io_priority,
2474
                               GCancellable        *cancellable,
2475
                               GAsyncReadyCallback  callback,
2476
                               gpointer             user_data)
2477
0
{
2478
0
  GFileIface *iface;
2479
2480
0
  g_return_if_fail (G_IS_FILE (file));
2481
2482
0
  iface = G_FILE_GET_IFACE (file);
2483
0
  (* iface->create_readwrite_async) (file,
2484
0
                                     flags,
2485
0
                                     io_priority,
2486
0
                                     cancellable,
2487
0
                                     callback,
2488
0
                                     user_data);
2489
0
}
2490
2491
/**
2492
 * g_file_create_readwrite_finish:
2493
 * @file: input #GFile
2494
 * @res: a #GAsyncResult
2495
 * @error: a #GError, or %NULL
2496
 *
2497
 * Finishes an asynchronous file create operation started with
2498
 * g_file_create_readwrite_async().
2499
 *
2500
 * Returns: (transfer full): a #GFileIOStream or %NULL on error.
2501
 *   Free the returned object with g_object_unref().
2502
 *
2503
 * Since: 2.22
2504
 */
2505
GFileIOStream *
2506
g_file_create_readwrite_finish (GFile         *file,
2507
                                GAsyncResult  *res,
2508
                                GError       **error)
2509
0
{
2510
0
  GFileIface *iface;
2511
2512
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
2513
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2514
2515
0
  if (g_async_result_legacy_propagate_error (res, error))
2516
0
    return NULL;
2517
2518
0
  iface = G_FILE_GET_IFACE (file);
2519
0
  return (* iface->create_readwrite_finish) (file, res, error);
2520
0
}
2521
2522
/**
2523
 * g_file_replace_readwrite_async:
2524
 * @file: input #GFile
2525
 * @etag: (nullable): an [entity tag][gfile-etag] for the current #GFile,
2526
 *   or %NULL to ignore
2527
 * @make_backup: %TRUE if a backup should be created
2528
 * @flags: a set of #GFileCreateFlags
2529
 * @io_priority: the [I/O priority][io-priority] of the request
2530
 * @cancellable: (nullable): optional #GCancellable object,
2531
 *   %NULL to ignore
2532
 * @callback: (scope async): a #GAsyncReadyCallback to call
2533
 *   when the request is satisfied
2534
 * @user_data: (closure): the data to pass to callback function
2535
 *
2536
 * Asynchronously overwrites the file in read-write mode,
2537
 * replacing the contents, possibly creating a backup copy
2538
 * of the file first.
2539
 *
2540
 * For more details, see g_file_replace_readwrite() which is
2541
 * the synchronous version of this call.
2542
 *
2543
 * When the operation is finished, @callback will be called.
2544
 * You can then call g_file_replace_readwrite_finish() to get
2545
 * the result of the operation.
2546
 *
2547
 * Since: 2.22
2548
 */
2549
void
2550
g_file_replace_readwrite_async (GFile               *file,
2551
                                const char          *etag,
2552
                                gboolean             make_backup,
2553
                                GFileCreateFlags     flags,
2554
                                int                  io_priority,
2555
                                GCancellable        *cancellable,
2556
                                GAsyncReadyCallback  callback,
2557
                                gpointer             user_data)
2558
0
{
2559
0
  GFileIface *iface;
2560
2561
0
  g_return_if_fail (G_IS_FILE (file));
2562
2563
0
  iface = G_FILE_GET_IFACE (file);
2564
0
  (* iface->replace_readwrite_async) (file,
2565
0
                                      etag,
2566
0
                                      make_backup,
2567
0
                                      flags,
2568
0
                                      io_priority,
2569
0
                                      cancellable,
2570
0
                                      callback,
2571
0
                                      user_data);
2572
0
}
2573
2574
/**
2575
 * g_file_replace_readwrite_finish:
2576
 * @file: input #GFile
2577
 * @res: a #GAsyncResult
2578
 * @error: a #GError, or %NULL
2579
 *
2580
 * Finishes an asynchronous file replace operation started with
2581
 * g_file_replace_readwrite_async().
2582
 *
2583
 * Returns: (transfer full): a #GFileIOStream, or %NULL on error.
2584
 *   Free the returned object with g_object_unref().
2585
 *
2586
 * Since: 2.22
2587
 */
2588
GFileIOStream *
2589
g_file_replace_readwrite_finish (GFile         *file,
2590
                                 GAsyncResult  *res,
2591
                                 GError       **error)
2592
0
{
2593
0
  GFileIface *iface;
2594
2595
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
2596
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2597
2598
0
  if (g_async_result_legacy_propagate_error (res, error))
2599
0
    return NULL;
2600
2601
0
  iface = G_FILE_GET_IFACE (file);
2602
0
  return (* iface->replace_readwrite_finish) (file, res, error);
2603
0
}
2604
2605
static gboolean
2606
copy_symlink (GFile           *destination,
2607
              GFileCopyFlags   flags,
2608
              GCancellable    *cancellable,
2609
              const char      *target,
2610
              GError         **error)
2611
0
{
2612
0
  GError *my_error;
2613
0
  gboolean tried_delete;
2614
0
  GFileInfo *info;
2615
0
  GFileType file_type;
2616
2617
0
  tried_delete = FALSE;
2618
2619
0
 retry:
2620
0
  my_error = NULL;
2621
0
  if (!g_file_make_symbolic_link (destination, target, cancellable, &my_error))
2622
0
    {
2623
      /* Maybe it already existed, and we want to overwrite? */
2624
0
      if (!tried_delete && (flags & G_FILE_COPY_OVERWRITE) &&
2625
0
          my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_EXISTS)
2626
0
        {
2627
0
          g_clear_error (&my_error);
2628
2629
          /* Don't overwrite if the destination is a directory */
2630
0
          info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_TYPE,
2631
0
                                    G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
2632
0
                                    cancellable, &my_error);
2633
0
          if (info != NULL)
2634
0
            {
2635
0
              file_type = g_file_info_get_file_type (info);
2636
0
              g_object_unref (info);
2637
2638
0
              if (file_type == G_FILE_TYPE_DIRECTORY)
2639
0
                {
2640
0
                  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY,
2641
0
                                       _("Can’t copy over directory"));
2642
0
                  return FALSE;
2643
0
                }
2644
0
            }
2645
2646
0
          if (!g_file_delete (destination, cancellable, error))
2647
0
            return FALSE;
2648
2649
0
          tried_delete = TRUE;
2650
0
          goto retry;
2651
0
        }
2652
            /* Nah, fail */
2653
0
      g_propagate_error (error, my_error);
2654
0
      return FALSE;
2655
0
    }
2656
2657
0
  return TRUE;
2658
0
}
2659
2660
static GFileInputStream *
2661
open_source_for_copy (GFile           *source,
2662
                      GFile           *destination,
2663
                      GFileCopyFlags   flags,
2664
                      GCancellable    *cancellable,
2665
                      GError         **error)
2666
0
{
2667
0
  GError *my_error;
2668
0
  GFileInputStream *ret;
2669
0
  GFileInfo *info;
2670
0
  GFileType file_type;
2671
2672
0
  my_error = NULL;
2673
0
  ret = g_file_read (source, cancellable, &my_error);
2674
0
  if (ret != NULL)
2675
0
    return ret;
2676
2677
  /* There was an error opening the source, try to set a good error for it: */
2678
0
  if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_IS_DIRECTORY)
2679
0
    {
2680
      /* The source is a directory, don't fail with WOULD_RECURSE immediately,
2681
       * as that is less useful to the app. Better check for errors on the
2682
       * target instead.
2683
       */
2684
0
      g_error_free (my_error);
2685
0
      my_error = NULL;
2686
2687
0
      info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_TYPE,
2688
0
                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
2689
0
                                cancellable, &my_error);
2690
0
      if (info != NULL &&
2691
0
          g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE))
2692
0
        {
2693
0
          file_type = g_file_info_get_file_type (info);
2694
0
          g_object_unref (info);
2695
2696
0
          if (flags & G_FILE_COPY_OVERWRITE)
2697
0
            {
2698
0
              if (file_type == G_FILE_TYPE_DIRECTORY)
2699
0
                {
2700
0
                  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_MERGE,
2701
0
                                       _("Can’t copy directory over directory"));
2702
0
                  return NULL;
2703
0
                }
2704
              /* continue to would_recurse error */
2705
0
            }
2706
0
          else
2707
0
            {
2708
0
              g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
2709
0
                                   _("Target file exists"));
2710
0
              return NULL;
2711
0
            }
2712
0
        }
2713
0
      else
2714
0
        {
2715
          /* Error getting info from target, return that error
2716
           * (except for NOT_FOUND, which is no error here)
2717
           */
2718
0
          g_clear_object (&info);
2719
0
          if (my_error != NULL && !g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
2720
0
            {
2721
0
              g_propagate_error (error, my_error);
2722
0
              return NULL;
2723
0
            }
2724
0
          g_clear_error (&my_error);
2725
0
        }
2726
2727
0
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE,
2728
0
                           _("Can’t recursively copy directory"));
2729
0
      return NULL;
2730
0
    }
2731
2732
0
  g_propagate_error (error, my_error);
2733
0
  return NULL;
2734
0
}
2735
2736
static gboolean
2737
should_copy (GFileAttributeInfo *info,
2738
             gboolean            copy_all_attributes,
2739
             gboolean            skip_perms)
2740
0
{
2741
0
  if (skip_perms && strcmp(info->name, "unix::mode") == 0)
2742
0
        return FALSE;
2743
2744
0
  if (copy_all_attributes)
2745
0
    return info->flags & G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED;
2746
0
  return info->flags & G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE;
2747
0
}
2748
2749
/**
2750
 * g_file_build_attribute_list_for_copy:
2751
 * @file: a #GFile to copy attributes to
2752
 * @flags: a set of #GFileCopyFlags
2753
 * @cancellable: (nullable): optional #GCancellable object,
2754
 *   %NULL to ignore
2755
 * @error: a #GError, %NULL to ignore
2756
 *
2757
 * Prepares the file attribute query string for copying to @file.
2758
 *
2759
 * This function prepares an attribute query string to be
2760
 * passed to g_file_query_info() to get a list of attributes
2761
 * normally copied with the file (see g_file_copy_attributes()
2762
 * for the detailed description). This function is used by the
2763
 * implementation of g_file_copy_attributes() and is useful
2764
 * when one needs to query and set the attributes in two
2765
 * stages (e.g., for recursive move of a directory).
2766
 *
2767
 * Returns: an attribute query string for g_file_query_info(),
2768
 *   or %NULL if an error occurs.
2769
 *
2770
 * Since: 2.68
2771
 */
2772
char *
2773
g_file_build_attribute_list_for_copy (GFile                  *file,
2774
                                      GFileCopyFlags          flags,
2775
                                      GCancellable           *cancellable,
2776
                                      GError                **error)
2777
0
{
2778
0
  char *ret = NULL;
2779
0
  GFileAttributeInfoList *attributes = NULL, *namespaces = NULL;
2780
0
  GString *s = NULL;
2781
0
  gboolean first;
2782
0
  int i;
2783
0
  gboolean copy_all_attributes;
2784
0
  gboolean skip_perms;
2785
2786
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
2787
0
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
2788
0
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2789
2790
0
  copy_all_attributes = flags & G_FILE_COPY_ALL_METADATA;
2791
0
  skip_perms = (flags & G_FILE_COPY_TARGET_DEFAULT_PERMS) != 0;
2792
2793
  /* Ignore errors here, if the target supports no attributes there is
2794
   * nothing to copy.  We still honor the cancellable though.
2795
   */
2796
0
  attributes = g_file_query_settable_attributes (file, cancellable, NULL);
2797
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
2798
0
    goto out;
2799
2800
0
  namespaces = g_file_query_writable_namespaces (file, cancellable, NULL);
2801
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
2802
0
    goto out;
2803
2804
0
  if (attributes == NULL && namespaces == NULL)
2805
0
    goto out;
2806
2807
0
  first = TRUE;
2808
0
  s = g_string_new ("");
2809
2810
0
  if (attributes)
2811
0
    {
2812
0
      for (i = 0; i < attributes->n_infos; i++)
2813
0
        {
2814
0
          if (should_copy (&attributes->infos[i], copy_all_attributes, skip_perms))
2815
0
            {
2816
0
              if (first)
2817
0
                first = FALSE;
2818
0
              else
2819
0
                g_string_append_c (s, ',');
2820
2821
0
              g_string_append (s, attributes->infos[i].name);
2822
0
            }
2823
0
        }
2824
0
    }
2825
2826
0
  if (namespaces)
2827
0
    {
2828
0
      for (i = 0; i < namespaces->n_infos; i++)
2829
0
        {
2830
0
          if (should_copy (&namespaces->infos[i], copy_all_attributes, FALSE))
2831
0
            {
2832
0
              if (first)
2833
0
                first = FALSE;
2834
0
              else
2835
0
                g_string_append_c (s, ',');
2836
2837
0
              g_string_append (s, namespaces->infos[i].name);
2838
0
              g_string_append (s, "::*");
2839
0
            }
2840
0
        }
2841
0
    }
2842
2843
0
  ret = g_string_free (s, FALSE);
2844
0
  s = NULL;
2845
0
 out:
2846
0
  if (s)
2847
0
    g_string_free (s, TRUE);
2848
0
  if (attributes)
2849
0
    g_file_attribute_info_list_unref (attributes);
2850
0
  if (namespaces)
2851
0
    g_file_attribute_info_list_unref (namespaces);
2852
  
2853
0
  return ret;
2854
0
}
2855
2856
/**
2857
 * g_file_copy_attributes:
2858
 * @source: a #GFile with attributes
2859
 * @destination: a #GFile to copy attributes to
2860
 * @flags: a set of #GFileCopyFlags
2861
 * @cancellable: (nullable): optional #GCancellable object,
2862
 *   %NULL to ignore
2863
 * @error: a #GError, %NULL to ignore
2864
 *
2865
 * Copies the file attributes from @source to @destination.
2866
 *
2867
 * Normally only a subset of the file attributes are copied,
2868
 * those that are copies in a normal file copy operation
2869
 * (which for instance does not include e.g. owner). However
2870
 * if %G_FILE_COPY_ALL_METADATA is specified in @flags, then
2871
 * all the metadata that is possible to copy is copied. This
2872
 * is useful when implementing move by copy + delete source.
2873
 *
2874
 * Returns: %TRUE if the attributes were copied successfully,
2875
 *   %FALSE otherwise.
2876
 */
2877
gboolean
2878
g_file_copy_attributes (GFile           *source,
2879
                        GFile           *destination,
2880
                        GFileCopyFlags   flags,
2881
                        GCancellable    *cancellable,
2882
                        GError         **error)
2883
0
{
2884
0
  char *attrs_to_read;
2885
0
  gboolean res;
2886
0
  GFileInfo *info;
2887
0
  gboolean source_nofollow_symlinks;
2888
2889
0
  attrs_to_read = g_file_build_attribute_list_for_copy (destination, flags,
2890
0
                                                        cancellable, error);
2891
0
  if (!attrs_to_read)
2892
0
    return FALSE;
2893
2894
0
  source_nofollow_symlinks = flags & G_FILE_COPY_NOFOLLOW_SYMLINKS;
2895
2896
  /* Ignore errors here, if we can't read some info (e.g. if it doesn't exist)
2897
   * we just don't copy it.
2898
   */
2899
0
  info = g_file_query_info (source, attrs_to_read,
2900
0
                            source_nofollow_symlinks ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS:0,
2901
0
                            cancellable,
2902
0
                            NULL);
2903
2904
0
  g_free (attrs_to_read);
2905
2906
0
  res = TRUE;
2907
0
  if  (info)
2908
0
    {
2909
0
      res = g_file_set_attributes_from_info (destination,
2910
0
                                             info,
2911
0
                                             G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
2912
0
                                             cancellable,
2913
0
                                             error);
2914
0
      g_object_unref (info);
2915
0
    }
2916
2917
0
  return res;
2918
0
}
2919
2920
/* 256k minus malloc overhead */
2921
0
#define STREAM_BUFFER_SIZE (1024*256 - 2 *sizeof(gpointer))
2922
2923
static gboolean
2924
copy_stream_with_progress (GInputStream           *in,
2925
                           GOutputStream          *out,
2926
                           GFile                  *source,
2927
                           GCancellable           *cancellable,
2928
                           GFileProgressCallback   progress_callback,
2929
                           gpointer                progress_callback_data,
2930
                           GError                **error)
2931
0
{
2932
0
  gssize n_read;
2933
0
  gsize n_written;
2934
0
  goffset current_size;
2935
0
  char *buffer;
2936
0
  gboolean res;
2937
0
  goffset total_size;
2938
0
  GFileInfo *info;
2939
2940
0
  total_size = -1;
2941
  /* avoid performance impact of querying total size when it's not needed */
2942
0
  if (progress_callback)
2943
0
    {
2944
0
      info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (in),
2945
0
                                             G_FILE_ATTRIBUTE_STANDARD_SIZE,
2946
0
                                             cancellable, NULL);
2947
0
      if (info)
2948
0
        {
2949
0
          if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE))
2950
0
            total_size = g_file_info_get_size (info);
2951
0
          g_object_unref (info);
2952
0
        }
2953
2954
0
      if (total_size == -1)
2955
0
        {
2956
0
          info = g_file_query_info (source,
2957
0
                                    G_FILE_ATTRIBUTE_STANDARD_SIZE,
2958
0
                                    G_FILE_QUERY_INFO_NONE,
2959
0
                                    cancellable, NULL);
2960
0
          if (info)
2961
0
            {
2962
0
              if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE))
2963
0
                total_size = g_file_info_get_size (info);
2964
0
              g_object_unref (info);
2965
0
            }
2966
0
        }
2967
0
    }
2968
2969
0
  if (total_size == -1)
2970
0
    total_size = 0;
2971
2972
0
  buffer = g_malloc0 (STREAM_BUFFER_SIZE);
2973
0
  current_size = 0;
2974
0
  res = TRUE;
2975
0
  while (TRUE)
2976
0
    {
2977
0
      n_read = g_input_stream_read (in, buffer, STREAM_BUFFER_SIZE, cancellable, error);
2978
0
      if (n_read == -1)
2979
0
        {
2980
0
          res = FALSE;
2981
0
          break;
2982
0
        }
2983
2984
0
      if (n_read == 0)
2985
0
        break;
2986
2987
0
      current_size += n_read;
2988
2989
0
      res = g_output_stream_write_all (out, buffer, n_read, &n_written, cancellable, error);
2990
0
      if (!res)
2991
0
        break;
2992
2993
0
      if (progress_callback)
2994
0
        progress_callback (current_size, total_size, progress_callback_data);
2995
0
    }
2996
0
  g_free (buffer);
2997
2998
  /* Make sure we send full copied size */
2999
0
  if (progress_callback)
3000
0
    progress_callback (current_size, total_size, progress_callback_data);
3001
3002
0
  return res;
3003
0
}
3004
3005
#ifdef HAVE_SPLICE
3006
3007
static gboolean
3008
do_splice (int     fd_in,
3009
           loff_t *off_in,
3010
           int     fd_out,
3011
           loff_t *off_out,
3012
           size_t  len,
3013
           long   *bytes_transferd,
3014
           GError **error)
3015
0
{
3016
0
  long result;
3017
3018
0
retry:
3019
0
  result = splice (fd_in, off_in, fd_out, off_out, len, SPLICE_F_MORE);
3020
3021
0
  if (result == -1)
3022
0
    {
3023
0
      int errsv = errno;
3024
3025
0
      if (errsv == EINTR)
3026
0
        goto retry;
3027
0
      else if (errsv == ENOSYS || errsv == EINVAL || errsv == EOPNOTSUPP)
3028
0
        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
3029
0
                             _("Splice not supported"));
3030
0
      else
3031
0
        g_set_error (error, G_IO_ERROR,
3032
0
                     g_io_error_from_errno (errsv),
3033
0
                     _("Error splicing file: %s"),
3034
0
                     g_strerror (errsv));
3035
3036
0
      return FALSE;
3037
0
    }
3038
3039
0
  *bytes_transferd = result;
3040
0
  return TRUE;
3041
0
}
3042
3043
static gboolean
3044
splice_stream_with_progress (GInputStream           *in,
3045
                             GOutputStream          *out,
3046
                             GCancellable           *cancellable,
3047
                             GFileProgressCallback   progress_callback,
3048
                             gpointer                progress_callback_data,
3049
                             GError                **error)
3050
0
{
3051
0
  int buffer[2] = { -1, -1 };
3052
0
  int buffer_size;
3053
0
  gboolean res;
3054
0
  goffset total_size;
3055
0
  loff_t offset_in;
3056
0
  loff_t offset_out;
3057
0
  int fd_in, fd_out;
3058
3059
0
  fd_in = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (in));
3060
0
  fd_out = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (out));
3061
3062
0
  if (!g_unix_open_pipe (buffer, FD_CLOEXEC, error))
3063
0
    return FALSE;
3064
3065
  /* Try a 1MiB buffer for improved throughput. If that fails, use the default
3066
   * pipe size. See: https://bugzilla.gnome.org/791457 */
3067
0
  buffer_size = fcntl (buffer[1], F_SETPIPE_SZ, 1024 * 1024);
3068
0
  if (buffer_size <= 0)
3069
0
    {
3070
0
      buffer_size = fcntl (buffer[1], F_GETPIPE_SZ);
3071
0
      if (buffer_size <= 0)
3072
0
        {
3073
          /* If #F_GETPIPE_SZ isn’t available, assume we’re on Linux < 2.6.35,
3074
           * but ≥ 2.6.11, meaning the pipe capacity is 64KiB. Ignore the
3075
           * possibility of running on Linux < 2.6.11 (where the capacity was
3076
           * the system page size, typically 4KiB) because it’s ancient.
3077
           * See pipe(7). */
3078
0
          buffer_size = 1024 * 64;
3079
0
        }
3080
0
    }
3081
3082
0
  g_assert (buffer_size > 0);
3083
3084
0
  total_size = -1;
3085
  /* avoid performance impact of querying total size when it's not needed */
3086
0
  if (progress_callback)
3087
0
    {
3088
0
      struct stat sbuf;
3089
3090
0
      if (fstat (fd_in, &sbuf) == 0)
3091
0
        total_size = sbuf.st_size;
3092
0
    }
3093
3094
0
  if (total_size == -1)
3095
0
    total_size = 0;
3096
3097
0
  offset_in = offset_out = 0;
3098
0
  res = FALSE;
3099
0
  while (TRUE)
3100
0
    {
3101
0
      long n_read;
3102
0
      long n_written;
3103
3104
0
      if (g_cancellable_set_error_if_cancelled (cancellable, error))
3105
0
        break;
3106
3107
0
      if (!do_splice (fd_in, &offset_in, buffer[1], NULL, buffer_size, &n_read, error))
3108
0
        break;
3109
3110
0
      if (n_read == 0)
3111
0
        {
3112
0
          res = TRUE;
3113
0
          break;
3114
0
        }
3115
3116
0
      while (n_read > 0)
3117
0
        {
3118
0
          if (g_cancellable_set_error_if_cancelled (cancellable, error))
3119
0
            goto out;
3120
3121
0
          if (!do_splice (buffer[0], NULL, fd_out, &offset_out, n_read, &n_written, error))
3122
0
            goto out;
3123
3124
0
          n_read -= n_written;
3125
0
        }
3126
3127
0
      if (progress_callback)
3128
0
        progress_callback (offset_in, total_size, progress_callback_data);
3129
0
    }
3130
3131
  /* Make sure we send full copied size */
3132
0
  if (progress_callback)
3133
0
    progress_callback (offset_in, total_size, progress_callback_data);
3134
3135
0
  if (!g_close (buffer[0], error))
3136
0
    goto out;
3137
0
  buffer[0] = -1;
3138
0
  if (!g_close (buffer[1], error))
3139
0
    goto out;
3140
0
  buffer[1] = -1;
3141
0
 out:
3142
0
  if (buffer[0] != -1)
3143
0
    (void) g_close (buffer[0], NULL);
3144
0
  if (buffer[1] != -1)
3145
0
    (void) g_close (buffer[1], NULL);
3146
3147
0
  return res;
3148
0
}
3149
#endif
3150
3151
#ifdef __linux__
3152
static gboolean
3153
btrfs_reflink_with_progress (GInputStream           *in,
3154
                             GOutputStream          *out,
3155
                             GFileInfo              *info,
3156
                             GCancellable           *cancellable,
3157
                             GFileProgressCallback   progress_callback,
3158
                             gpointer                progress_callback_data,
3159
                             GError                **error)
3160
0
{
3161
0
  goffset source_size;
3162
0
  int fd_in, fd_out;
3163
0
  int ret, errsv;
3164
3165
0
  fd_in = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (in));
3166
0
  fd_out = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (out));
3167
3168
0
  if (progress_callback)
3169
0
    source_size = g_file_info_get_size (info);
3170
3171
  /* Btrfs clone ioctl properties:
3172
   *  - Works at the inode level
3173
   *  - Doesn't work with directories
3174
   *  - Always follows symlinks (source and destination)
3175
   *
3176
   * By the time we get here, *in and *out are both regular files */
3177
0
  ret = ioctl (fd_out, BTRFS_IOC_CLONE, fd_in);
3178
0
  errsv = errno;
3179
3180
0
  if (ret < 0)
3181
0
    {
3182
0
      if (errsv == EXDEV)
3183
0
  g_set_error_literal (error, G_IO_ERROR,
3184
0
           G_IO_ERROR_NOT_SUPPORTED,
3185
0
           _("Copy (reflink/clone) between mounts is not supported"));
3186
0
      else if (errsv == EINVAL)
3187
0
  g_set_error_literal (error, G_IO_ERROR,
3188
0
           G_IO_ERROR_NOT_SUPPORTED,
3189
0
           _("Copy (reflink/clone) is not supported or invalid"));
3190
0
      else
3191
  /* Most probably something odd happened; retry with fallback */
3192
0
  g_set_error_literal (error, G_IO_ERROR,
3193
0
           G_IO_ERROR_NOT_SUPPORTED,
3194
0
           _("Copy (reflink/clone) is not supported or didn’t work"));
3195
      /* We retry with fallback for all error cases because Btrfs is currently
3196
       * unstable, and so we can't trust it to do clone properly.
3197
       * In addition, any hard errors here would cause the same failure in the
3198
       * fallback manual copy as well. */
3199
0
      return FALSE;
3200
0
    }
3201
3202
  /* Make sure we send full copied size */
3203
0
  if (progress_callback)
3204
0
    progress_callback (source_size, source_size, progress_callback_data);
3205
3206
0
  return TRUE;
3207
0
}
3208
#endif
3209
3210
static gboolean
3211
file_copy_fallback (GFile                  *source,
3212
                    GFile                  *destination,
3213
                    GFileCopyFlags          flags,
3214
                    GCancellable           *cancellable,
3215
                    GFileProgressCallback   progress_callback,
3216
                    gpointer                progress_callback_data,
3217
                    GError                **error)
3218
0
{
3219
0
  gboolean ret = FALSE;
3220
0
  GFileInputStream *file_in = NULL;
3221
0
  GInputStream *in = NULL;
3222
0
  GOutputStream *out = NULL;
3223
0
  GFileInfo *info = NULL;
3224
0
  const char *target;
3225
0
  char *attrs_to_read;
3226
0
  gboolean do_set_attributes = FALSE;
3227
0
  GFileCreateFlags create_flags;
3228
0
  GError *tmp_error = NULL;
3229
3230
  /* need to know the file type */
3231
0
  info = g_file_query_info (source,
3232
0
                            G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
3233
0
                            G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
3234
0
                            cancellable,
3235
0
                            error);
3236
0
  if (!info)
3237
0
    goto out;
3238
3239
  /* Maybe copy the symlink? */
3240
0
  if ((flags & G_FILE_COPY_NOFOLLOW_SYMLINKS) &&
3241
0
      g_file_info_get_file_type (info) == G_FILE_TYPE_SYMBOLIC_LINK)
3242
0
    {
3243
0
      target = g_file_info_get_symlink_target (info);
3244
0
      if (target)
3245
0
        {
3246
0
          if (!copy_symlink (destination, flags, cancellable, target, error))
3247
0
            goto out;
3248
3249
0
          ret = TRUE;
3250
0
          goto out;
3251
0
        }
3252
        /* ... else fall back on a regular file copy */
3253
0
    }
3254
  /* Handle "special" files (pipes, device nodes, ...)? */
3255
0
  else if (g_file_info_get_file_type (info) == G_FILE_TYPE_SPECIAL)
3256
0
    {
3257
      /* FIXME: could try to recreate device nodes and others? */
3258
0
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
3259
0
                           _("Can’t copy special file"));
3260
0
      goto out;
3261
0
    }
3262
3263
  /* Everything else should just fall back on a regular copy. */
3264
3265
0
  file_in = open_source_for_copy (source, destination, flags, cancellable, error);
3266
0
  if (!file_in)
3267
0
    goto out;
3268
0
  in = G_INPUT_STREAM (file_in);
3269
3270
0
  attrs_to_read = g_file_build_attribute_list_for_copy (destination, flags,
3271
0
                                                        cancellable, error);
3272
0
  if (!attrs_to_read)
3273
0
    goto out;
3274
3275
  /* Ok, ditch the previous lightweight info (on Unix we just
3276
   * called lstat()); at this point we gather all the information
3277
   * we need about the source from the opened file descriptor.
3278
   */
3279
0
  g_object_unref (info);
3280
3281
0
  info = g_file_input_stream_query_info (file_in, attrs_to_read,
3282
0
                                         cancellable, &tmp_error);
3283
0
  if (!info)
3284
0
    {
3285
      /* Not all gvfs backends implement query_info_on_read(), we
3286
       * can just fall back to the pathname again.
3287
       * https://bugzilla.gnome.org/706254
3288
       */
3289
0
      if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
3290
0
        {
3291
0
          g_clear_error (&tmp_error);
3292
0
          info = g_file_query_info (source, attrs_to_read, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
3293
0
                                    cancellable, error);
3294
0
        }
3295
0
      else
3296
0
        {
3297
0
          g_free (attrs_to_read);
3298
0
          g_propagate_error (error, tmp_error);
3299
0
          goto out;
3300
0
        }
3301
0
    }
3302
0
  g_free (attrs_to_read);
3303
0
  if (!info)
3304
0
    goto out;
3305
3306
0
  do_set_attributes = TRUE;
3307
3308
  /* In the local file path, we pass down the source info which
3309
   * includes things like unix::mode, to ensure that the target file
3310
   * is not created with different permissions from the source file.
3311
   *
3312
   * If a future API like g_file_replace_with_info() is added, switch
3313
   * this code to use that.
3314
   *
3315
   * Use %G_FILE_CREATE_PRIVATE unless
3316
   *  - we were told to create the file with default permissions (i.e. the
3317
   *    process’ umask),
3318
   *  - or if the source file is on a file system which doesn’t support
3319
   *    `unix::mode` (in which case it probably also makes sense to create the
3320
   *    destination with default permissions because the source cannot be
3321
   *    private),
3322
   *  - or if the destination file is a `GLocalFile`, in which case we can
3323
   *    directly open() it with the permissions from the source file.
3324
   */
3325
0
  create_flags = G_FILE_CREATE_NONE;
3326
0
  if (!(flags & G_FILE_COPY_TARGET_DEFAULT_PERMS) &&
3327
0
      g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_UNIX_MODE) &&
3328
0
      !G_IS_LOCAL_FILE (destination))
3329
0
    create_flags |= G_FILE_CREATE_PRIVATE;
3330
0
  if (flags & G_FILE_COPY_OVERWRITE)
3331
0
    create_flags |= G_FILE_CREATE_REPLACE_DESTINATION;
3332
3333
0
  if (G_IS_LOCAL_FILE (destination))
3334
0
    {
3335
0
      if (flags & G_FILE_COPY_OVERWRITE)
3336
0
        out = (GOutputStream*)_g_local_file_output_stream_replace (_g_local_file_get_filename (G_LOCAL_FILE (destination)),
3337
0
                                                                   FALSE, NULL,
3338
0
                                                                   flags & G_FILE_COPY_BACKUP,
3339
0
                                                                   create_flags,
3340
0
                                                                   (flags & G_FILE_COPY_TARGET_DEFAULT_PERMS) ? NULL : info,
3341
0
                                                                   cancellable, error);
3342
0
      else
3343
0
        out = (GOutputStream*)_g_local_file_output_stream_create (_g_local_file_get_filename (G_LOCAL_FILE (destination)),
3344
0
                                                                  FALSE, create_flags,
3345
0
                                                                  (flags & G_FILE_COPY_TARGET_DEFAULT_PERMS) ? NULL : info,
3346
0
                                                                  cancellable, error);
3347
0
    }
3348
0
  else if (flags & G_FILE_COPY_OVERWRITE)
3349
0
    {
3350
0
      out = (GOutputStream *)g_file_replace (destination,
3351
0
                                             NULL,
3352
0
                                             flags & G_FILE_COPY_BACKUP,
3353
0
                                             create_flags,
3354
0
                                             cancellable, error);
3355
0
    }
3356
0
  else
3357
0
    {
3358
0
      out = (GOutputStream *)g_file_create (destination, create_flags, cancellable, error);
3359
0
    }
3360
3361
0
  if (!out)
3362
0
    goto out;
3363
3364
0
#ifdef __linux__
3365
0
  if (G_IS_FILE_DESCRIPTOR_BASED (in) && G_IS_FILE_DESCRIPTOR_BASED (out))
3366
0
    {
3367
0
      GError *reflink_err = NULL;
3368
3369
0
      if (!btrfs_reflink_with_progress (in, out, info, cancellable,
3370
0
                                        progress_callback, progress_callback_data,
3371
0
                                        &reflink_err))
3372
0
        {
3373
0
          if (g_error_matches (reflink_err, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
3374
0
            {
3375
0
              g_clear_error (&reflink_err);
3376
0
            }
3377
0
          else
3378
0
            {
3379
0
              g_propagate_error (error, reflink_err);
3380
0
              goto out;
3381
0
            }
3382
0
        }
3383
0
      else
3384
0
        {
3385
0
          ret = TRUE;
3386
0
          goto out;
3387
0
        }
3388
0
    }
3389
0
#endif
3390
3391
0
#ifdef HAVE_SPLICE
3392
0
  if (G_IS_FILE_DESCRIPTOR_BASED (in) && G_IS_FILE_DESCRIPTOR_BASED (out))
3393
0
    {
3394
0
      GError *splice_err = NULL;
3395
3396
0
      if (!splice_stream_with_progress (in, out, cancellable,
3397
0
                                        progress_callback, progress_callback_data,
3398
0
                                        &splice_err))
3399
0
        {
3400
0
          if (g_error_matches (splice_err, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
3401
0
            {
3402
0
              g_clear_error (&splice_err);
3403
0
            }
3404
0
          else
3405
0
            {
3406
0
              g_propagate_error (error, splice_err);
3407
0
              goto out;
3408
0
            }
3409
0
        }
3410
0
      else
3411
0
        {
3412
0
          ret = TRUE;
3413
0
          goto out;
3414
0
        }
3415
0
    }
3416
3417
0
#endif
3418
3419
  /* A plain read/write loop */
3420
0
  if (!copy_stream_with_progress (in, out, source, cancellable,
3421
0
                                  progress_callback, progress_callback_data,
3422
0
                                  error))
3423
0
    goto out;
3424
3425
0
  ret = TRUE;
3426
0
 out:
3427
0
  if (in)
3428
0
    {
3429
      /* Don't care about errors in source here */
3430
0
      (void) g_input_stream_close (in, cancellable, NULL);
3431
0
      g_object_unref (in);
3432
0
    }
3433
3434
0
  if (out)
3435
0
    {
3436
      /* But write errors on close are bad! */
3437
0
      if (!g_output_stream_close (out, cancellable, ret ? error : NULL))
3438
0
        ret = FALSE;
3439
0
      g_object_unref (out);
3440
0
    }
3441
3442
  /* Ignore errors here. Failure to copy metadata is not a hard error */
3443
  /* TODO: set these attributes /before/ we do the rename() on Unix */
3444
0
  if (ret && do_set_attributes)
3445
0
    {
3446
0
      g_file_set_attributes_from_info (destination,
3447
0
                                       info,
3448
0
                                       G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
3449
0
                                       cancellable,
3450
0
                                       NULL);
3451
0
    }
3452
3453
0
  g_clear_object (&info);
3454
3455
0
  return ret;
3456
0
}
3457
3458
/**
3459
 * g_file_copy:
3460
 * @source: input #GFile
3461
 * @destination: destination #GFile
3462
 * @flags: set of #GFileCopyFlags
3463
 * @cancellable: (nullable): optional #GCancellable object,
3464
 *   %NULL to ignore
3465
 * @progress_callback: (nullable) (scope call): function to callback with
3466
 *   progress information, or %NULL if progress information is not needed
3467
 * @progress_callback_data: (closure): user data to pass to @progress_callback
3468
 * @error: #GError to set on error, or %NULL
3469
 *
3470
 * Copies the file @source to the location specified by @destination.
3471
 * Can not handle recursive copies of directories.
3472
 *
3473
 * If the flag %G_FILE_COPY_OVERWRITE is specified an already
3474
 * existing @destination file is overwritten.
3475
 *
3476
 * If the flag %G_FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks
3477
 * will be copied as symlinks, otherwise the target of the
3478
 * @source symlink will be copied.
3479
 *
3480
 * If the flag %G_FILE_COPY_ALL_METADATA is specified then all the metadata
3481
 * that is possible to copy is copied, not just the default subset (which,
3482
 * for instance, does not include the owner, see #GFileInfo).
3483
 *
3484
 * If @cancellable is not %NULL, then the operation can be cancelled by
3485
 * triggering the cancellable object from another thread. If the operation
3486
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3487
 *
3488
 * If @progress_callback is not %NULL, then the operation can be monitored
3489
 * by setting this to a #GFileProgressCallback function.
3490
 * @progress_callback_data will be passed to this function. It is guaranteed
3491
 * that this callback will be called after all data has been transferred with
3492
 * the total number of bytes copied during the operation.
3493
 *
3494
 * If the @source file does not exist, then the %G_IO_ERROR_NOT_FOUND error
3495
 * is returned, independent on the status of the @destination.
3496
 *
3497
 * If %G_FILE_COPY_OVERWRITE is not specified and the target exists, then
3498
 * the error %G_IO_ERROR_EXISTS is returned.
3499
 *
3500
 * If trying to overwrite a file over a directory, the %G_IO_ERROR_IS_DIRECTORY
3501
 * error is returned. If trying to overwrite a directory with a directory the
3502
 * %G_IO_ERROR_WOULD_MERGE error is returned.
3503
 *
3504
 * If the source is a directory and the target does not exist, or
3505
 * %G_FILE_COPY_OVERWRITE is specified and the target is a file, then the
3506
 * %G_IO_ERROR_WOULD_RECURSE error is returned.
3507
 *
3508
 * If you are interested in copying the #GFile object itself (not the on-disk
3509
 * file), see g_file_dup().
3510
 *
3511
 * Returns: %TRUE on success, %FALSE otherwise.
3512
 */
3513
gboolean
3514
g_file_copy (GFile                  *source,
3515
             GFile                  *destination,
3516
             GFileCopyFlags          flags,
3517
             GCancellable           *cancellable,
3518
             GFileProgressCallback   progress_callback,
3519
             gpointer                progress_callback_data,
3520
             GError                **error)
3521
0
{
3522
0
  GFileIface *iface;
3523
0
  GError *my_error;
3524
0
  gboolean res;
3525
3526
0
  g_return_val_if_fail (G_IS_FILE (source), FALSE);
3527
0
  g_return_val_if_fail (G_IS_FILE (destination), FALSE);
3528
3529
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
3530
0
    return FALSE;
3531
3532
0
  iface = G_FILE_GET_IFACE (destination);
3533
0
  if (iface->copy)
3534
0
    {
3535
0
      my_error = NULL;
3536
0
      res = (* iface->copy) (source, destination,
3537
0
                             flags, cancellable,
3538
0
                             progress_callback, progress_callback_data,
3539
0
                             &my_error);
3540
3541
0
      if (res)
3542
0
        return TRUE;
3543
3544
0
      if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
3545
0
        {
3546
0
          g_propagate_error (error, my_error);
3547
0
              return FALSE;
3548
0
        }
3549
0
      else
3550
0
        g_clear_error (&my_error);
3551
0
    }
3552
3553
  /* If the types are different, and the destination method failed
3554
   * also try the source method
3555
   */
3556
0
  if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination))
3557
0
    {
3558
0
      iface = G_FILE_GET_IFACE (source);
3559
3560
0
      if (iface->copy)
3561
0
        {
3562
0
          my_error = NULL;
3563
0
          res = (* iface->copy) (source, destination,
3564
0
                                 flags, cancellable,
3565
0
                                 progress_callback, progress_callback_data,
3566
0
                                 &my_error);
3567
3568
0
          if (res)
3569
0
            return TRUE;
3570
3571
0
          if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
3572
0
            {
3573
0
              g_propagate_error (error, my_error);
3574
0
              return FALSE;
3575
0
            }
3576
0
          else
3577
0
            g_clear_error (&my_error);
3578
0
        }
3579
0
    }
3580
3581
0
  return file_copy_fallback (source, destination, flags, cancellable,
3582
0
                             progress_callback, progress_callback_data,
3583
0
                             error);
3584
0
}
3585
3586
/**
3587
 * g_file_copy_async:
3588
 * @source: input #GFile
3589
 * @destination: destination #GFile
3590
 * @flags: set of #GFileCopyFlags
3591
 * @io_priority: the [I/O priority][io-priority] of the request
3592
 * @cancellable: (nullable): optional #GCancellable object,
3593
 *   %NULL to ignore
3594
 * @progress_callback: (nullable) (scope notified): function to callback with progress
3595
 *   information, or %NULL if progress information is not needed
3596
 * @progress_callback_data: (closure progress_callback) (nullable): user data to pass to @progress_callback
3597
 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
3598
 * @user_data: (closure callback): the data to pass to callback function
3599
 *
3600
 * Copies the file @source to the location specified by @destination
3601
 * asynchronously. For details of the behaviour, see g_file_copy().
3602
 *
3603
 * If @progress_callback is not %NULL, then that function that will be called
3604
 * just like in g_file_copy(). The callback will run in the default main context
3605
 * of the thread calling g_file_copy_async() — the same context as @callback is
3606
 * run in.
3607
 *
3608
 * When the operation is finished, @callback will be called. You can then call
3609
 * g_file_copy_finish() to get the result of the operation.
3610
 */
3611
void
3612
g_file_copy_async (GFile                  *source,
3613
                   GFile                  *destination,
3614
                   GFileCopyFlags          flags,
3615
                   int                     io_priority,
3616
                   GCancellable           *cancellable,
3617
                   GFileProgressCallback   progress_callback,
3618
                   gpointer                progress_callback_data,
3619
                   GAsyncReadyCallback     callback,
3620
                   gpointer                user_data)
3621
0
{
3622
0
  GFileIface *iface;
3623
3624
0
  g_return_if_fail (G_IS_FILE (source));
3625
0
  g_return_if_fail (G_IS_FILE (destination));
3626
3627
0
  iface = G_FILE_GET_IFACE (source);
3628
0
  (* iface->copy_async) (source,
3629
0
                         destination,
3630
0
                         flags,
3631
0
                         io_priority,
3632
0
                         cancellable,
3633
0
                         progress_callback,
3634
0
                         progress_callback_data,
3635
0
                         callback,
3636
0
                         user_data);
3637
0
}
3638
3639
/**
3640
 * g_file_copy_finish:
3641
 * @file: input #GFile
3642
 * @res: a #GAsyncResult
3643
 * @error: a #GError, or %NULL
3644
 *
3645
 * Finishes copying the file started with g_file_copy_async().
3646
 *
3647
 * Returns: a %TRUE on success, %FALSE on error.
3648
 */
3649
gboolean
3650
g_file_copy_finish (GFile         *file,
3651
                    GAsyncResult  *res,
3652
                    GError       **error)
3653
0
{
3654
0
  GFileIface *iface;
3655
3656
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
3657
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
3658
3659
0
  if (g_async_result_legacy_propagate_error (res, error))
3660
0
    return FALSE;
3661
3662
0
  iface = G_FILE_GET_IFACE (file);
3663
0
  return (* iface->copy_finish) (file, res, error);
3664
0
}
3665
3666
/**
3667
 * g_file_move:
3668
 * @source: #GFile pointing to the source location
3669
 * @destination: #GFile pointing to the destination location
3670
 * @flags: set of #GFileCopyFlags
3671
 * @cancellable: (nullable): optional #GCancellable object,
3672
 *   %NULL to ignore
3673
 * @progress_callback: (nullable) (scope call): #GFileProgressCallback
3674
 *   function for updates
3675
 * @progress_callback_data: (closure): gpointer to user data for
3676
 *   the callback function
3677
 * @error: #GError for returning error conditions, or %NULL
3678
 *
3679
 * Tries to move the file or directory @source to the location specified
3680
 * by @destination. If native move operations are supported then this is
3681
 * used, otherwise a copy + delete fallback is used. The native
3682
 * implementation may support moving directories (for instance on moves
3683
 * inside the same filesystem), but the fallback code does not.
3684
 *
3685
 * If the flag %G_FILE_COPY_OVERWRITE is specified an already
3686
 * existing @destination file is overwritten.
3687
 *
3688
 * If @cancellable is not %NULL, then the operation can be cancelled by
3689
 * triggering the cancellable object from another thread. If the operation
3690
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3691
 *
3692
 * If @progress_callback is not %NULL, then the operation can be monitored
3693
 * by setting this to a #GFileProgressCallback function.
3694
 * @progress_callback_data will be passed to this function. It is
3695
 * guaranteed that this callback will be called after all data has been
3696
 * transferred with the total number of bytes copied during the operation.
3697
 *
3698
 * If the @source file does not exist, then the %G_IO_ERROR_NOT_FOUND
3699
 * error is returned, independent on the status of the @destination.
3700
 *
3701
 * If %G_FILE_COPY_OVERWRITE is not specified and the target exists,
3702
 * then the error %G_IO_ERROR_EXISTS is returned.
3703
 *
3704
 * If trying to overwrite a file over a directory, the %G_IO_ERROR_IS_DIRECTORY
3705
 * error is returned. If trying to overwrite a directory with a directory the
3706
 * %G_IO_ERROR_WOULD_MERGE error is returned.
3707
 *
3708
 * If the source is a directory and the target does not exist, or
3709
 * %G_FILE_COPY_OVERWRITE is specified and the target is a file, then
3710
 * the %G_IO_ERROR_WOULD_RECURSE error may be returned (if the native
3711
 * move operation isn't available).
3712
 *
3713
 * Returns: %TRUE on successful move, %FALSE otherwise.
3714
 */
3715
gboolean
3716
g_file_move (GFile                  *source,
3717
             GFile                  *destination,
3718
             GFileCopyFlags          flags,
3719
             GCancellable           *cancellable,
3720
             GFileProgressCallback   progress_callback,
3721
             gpointer                progress_callback_data,
3722
             GError                **error)
3723
0
{
3724
0
  GFileIface *iface;
3725
0
  GError *my_error;
3726
0
  gboolean res;
3727
3728
0
  g_return_val_if_fail (G_IS_FILE (source), FALSE);
3729
0
  g_return_val_if_fail (G_IS_FILE (destination), FALSE);
3730
3731
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
3732
0
    return FALSE;
3733
3734
0
  iface = G_FILE_GET_IFACE (destination);
3735
0
  if (iface->move)
3736
0
    {
3737
0
      my_error = NULL;
3738
0
      res = (* iface->move) (source, destination,
3739
0
                             flags, cancellable,
3740
0
                             progress_callback, progress_callback_data,
3741
0
                             &my_error);
3742
3743
0
      if (res)
3744
0
        return TRUE;
3745
3746
0
      if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
3747
0
        {
3748
0
          g_propagate_error (error, my_error);
3749
0
          return FALSE;
3750
0
        }
3751
0
      else
3752
0
        g_clear_error (&my_error);
3753
0
    }
3754
3755
  /* If the types are different, and the destination method failed
3756
   * also try the source method
3757
   */
3758
0
  if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination))
3759
0
    {
3760
0
      iface = G_FILE_GET_IFACE (source);
3761
3762
0
      if (iface->move)
3763
0
        {
3764
0
          my_error = NULL;
3765
0
          res = (* iface->move) (source, destination,
3766
0
                                 flags, cancellable,
3767
0
                                 progress_callback, progress_callback_data,
3768
0
                                 &my_error);
3769
3770
0
          if (res)
3771
0
            return TRUE;
3772
3773
0
          if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
3774
0
            {
3775
0
              g_propagate_error (error, my_error);
3776
0
              return FALSE;
3777
0
            }
3778
0
          else
3779
0
            g_clear_error (&my_error);
3780
0
        }
3781
0
    }
3782
3783
0
  if (flags & G_FILE_COPY_NO_FALLBACK_FOR_MOVE)
3784
0
    {
3785
0
      g_set_error_literal (error, G_IO_ERROR,
3786
0
                           G_IO_ERROR_NOT_SUPPORTED,
3787
0
                           _("Operation not supported"));
3788
0
      return FALSE;
3789
0
    }
3790
3791
0
  flags |= G_FILE_COPY_ALL_METADATA | G_FILE_COPY_NOFOLLOW_SYMLINKS;
3792
0
  if (!g_file_copy (source, destination, flags, cancellable,
3793
0
                    progress_callback, progress_callback_data,
3794
0
                    error))
3795
0
    return FALSE;
3796
3797
0
  return g_file_delete (source, cancellable, error);
3798
0
}
3799
3800
/**
3801
 * g_file_move_async:
3802
 * @source: #GFile pointing to the source location
3803
 * @destination: #GFile pointing to the destination location
3804
 * @flags: set of #GFileCopyFlags
3805
 * @io_priority: the [I/O priority][io-priority] of the request
3806
 * @cancellable: (nullable): optional #GCancellable object,
3807
 *   %NULL to ignore
3808
 * @progress_callback: (nullable) (scope call): #GFileProgressCallback
3809
 *   function for updates
3810
 * @progress_callback_data: (closure): gpointer to user data for
3811
 *   the callback function
3812
 * @callback: a #GAsyncReadyCallback to call
3813
 *   when the request is satisfied
3814
 * @user_data: the data to pass to callback function
3815
 *
3816
 * Asynchronously moves a file @source to the location of @destination. For details of the behaviour, see g_file_move().
3817
 *
3818
 * If @progress_callback is not %NULL, then that function that will be called
3819
 * just like in g_file_move(). The callback will run in the default main context
3820
 * of the thread calling g_file_move_async() — the same context as @callback is
3821
 * run in.
3822
 *
3823
 * When the operation is finished, @callback will be called. You can then call
3824
 * g_file_move_finish() to get the result of the operation.
3825
 *
3826
 * Since: 2.72
3827
 */
3828
void
3829
g_file_move_async (GFile                *source,
3830
                   GFile                *destination,
3831
                   GFileCopyFlags        flags,
3832
                   int                   io_priority,
3833
                   GCancellable         *cancellable,
3834
                   GFileProgressCallback progress_callback,
3835
                   gpointer              progress_callback_data,
3836
                   GAsyncReadyCallback   callback,
3837
                   gpointer              user_data)
3838
0
{
3839
0
  GFileIface *iface;
3840
3841
0
  g_return_if_fail (G_IS_FILE (source));
3842
0
  g_return_if_fail (G_IS_FILE (destination));
3843
0
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
3844
3845
0
  iface = G_FILE_GET_IFACE (source);
3846
0
  (* iface->move_async) (source,
3847
0
                         destination,
3848
0
                         flags,
3849
0
                         io_priority,
3850
0
                         cancellable,
3851
0
                         progress_callback,
3852
0
                         progress_callback_data,
3853
0
                         callback,
3854
0
                         user_data);
3855
0
}
3856
3857
/**
3858
 * g_file_move_finish:
3859
 * @file: input source #GFile
3860
 * @result: a #GAsyncResult
3861
 * @error: a #GError, or %NULL
3862
 *
3863
 * Finishes an asynchronous file movement, started with
3864
 * g_file_move_async().
3865
 *
3866
 * Returns: %TRUE on successful file move, %FALSE otherwise.
3867
 *
3868
 * Since: 2.72
3869
 */
3870
gboolean
3871
g_file_move_finish (GFile         *file,
3872
                    GAsyncResult  *result,
3873
                    GError       **error)
3874
0
{
3875
0
  GFileIface *iface;
3876
3877
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
3878
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3879
0
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
3880
3881
0
  iface = G_FILE_GET_IFACE (file);
3882
0
  return (* iface->move_finish) (file, result, error);
3883
0
}
3884
3885
/**
3886
 * g_file_make_directory:
3887
 * @file: input #GFile
3888
 * @cancellable: (nullable): optional #GCancellable object,
3889
 *   %NULL to ignore
3890
 * @error: a #GError, or %NULL
3891
 *
3892
 * Creates a directory. Note that this will only create a child directory
3893
 * of the immediate parent directory of the path or URI given by the #GFile.
3894
 * To recursively create directories, see g_file_make_directory_with_parents().
3895
 * This function will fail if the parent directory does not exist, setting
3896
 * @error to %G_IO_ERROR_NOT_FOUND. If the file system doesn't support
3897
 * creating directories, this function will fail, setting @error to
3898
 * %G_IO_ERROR_NOT_SUPPORTED.
3899
 *
3900
 * For a local #GFile the newly created directory will have the default
3901
 * (current) ownership and permissions of the current process.
3902
 *
3903
 * If @cancellable is not %NULL, then the operation can be cancelled by
3904
 * triggering the cancellable object from another thread. If the operation
3905
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3906
 *
3907
 * Returns: %TRUE on successful creation, %FALSE otherwise.
3908
 */
3909
gboolean
3910
g_file_make_directory (GFile         *file,
3911
                       GCancellable  *cancellable,
3912
                       GError       **error)
3913
0
{
3914
0
  GFileIface *iface;
3915
3916
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
3917
3918
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
3919
0
    return FALSE;
3920
3921
0
  iface = G_FILE_GET_IFACE (file);
3922
3923
0
  if (iface->make_directory == NULL)
3924
0
    {
3925
0
      g_set_error_literal (error, G_IO_ERROR,
3926
0
                           G_IO_ERROR_NOT_SUPPORTED,
3927
0
                           _("Operation not supported"));
3928
0
      return FALSE;
3929
0
    }
3930
3931
0
  return (* iface->make_directory) (file, cancellable, error);
3932
0
}
3933
3934
/**
3935
 * g_file_make_directory_async:
3936
 * @file: input #GFile
3937
 * @io_priority: the [I/O priority][io-priority] of the request
3938
 * @cancellable: (nullable): optional #GCancellable object,
3939
 *   %NULL to ignore
3940
 * @callback: a #GAsyncReadyCallback to call
3941
 *   when the request is satisfied
3942
 * @user_data: the data to pass to callback function
3943
 *
3944
 * Asynchronously creates a directory.
3945
 *
3946
 * Virtual: make_directory_async
3947
 * Since: 2.38
3948
 */
3949
void
3950
g_file_make_directory_async (GFile               *file,
3951
                             int                  io_priority,
3952
                             GCancellable        *cancellable,
3953
                             GAsyncReadyCallback  callback,
3954
                             gpointer             user_data)
3955
0
{
3956
0
  GFileIface *iface;
3957
3958
0
  g_return_if_fail (G_IS_FILE (file));
3959
3960
0
  iface = G_FILE_GET_IFACE (file);
3961
0
  (* iface->make_directory_async) (file,
3962
0
                                   io_priority,
3963
0
                                   cancellable,
3964
0
                                   callback,
3965
0
                                   user_data);
3966
0
}
3967
3968
/**
3969
 * g_file_make_directory_finish:
3970
 * @file: input #GFile
3971
 * @result: a #GAsyncResult
3972
 * @error: a #GError, or %NULL
3973
 *
3974
 * Finishes an asynchronous directory creation, started with
3975
 * g_file_make_directory_async().
3976
 *
3977
 * Virtual: make_directory_finish
3978
 * Returns: %TRUE on successful directory creation, %FALSE otherwise.
3979
 * Since: 2.38
3980
 */
3981
gboolean
3982
g_file_make_directory_finish (GFile         *file,
3983
                              GAsyncResult  *result,
3984
                              GError       **error)
3985
0
{
3986
0
  GFileIface *iface;
3987
3988
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
3989
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3990
3991
0
  iface = G_FILE_GET_IFACE (file);
3992
0
  return (* iface->make_directory_finish) (file, result, error);
3993
0
}
3994
3995
/**
3996
 * g_file_make_directory_with_parents:
3997
 * @file: input #GFile
3998
 * @cancellable: (nullable): optional #GCancellable object,
3999
 *   %NULL to ignore
4000
 * @error: a #GError, or %NULL
4001
 *
4002
 * Creates a directory and any parent directories that may not
4003
 * exist similar to 'mkdir -p'. If the file system does not support
4004
 * creating directories, this function will fail, setting @error to
4005
 * %G_IO_ERROR_NOT_SUPPORTED. If the directory itself already exists,
4006
 * this function will fail setting @error to %G_IO_ERROR_EXISTS, unlike
4007
 * the similar g_mkdir_with_parents().
4008
 *
4009
 * For a local #GFile the newly created directories will have the default
4010
 * (current) ownership and permissions of the current process.
4011
 *
4012
 * If @cancellable is not %NULL, then the operation can be cancelled by
4013
 * triggering the cancellable object from another thread. If the operation
4014
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4015
 *
4016
 * Returns: %TRUE if all directories have been successfully created, %FALSE
4017
 * otherwise.
4018
 *
4019
 * Since: 2.18
4020
 */
4021
gboolean
4022
g_file_make_directory_with_parents (GFile         *file,
4023
                                    GCancellable  *cancellable,
4024
                                    GError       **error)
4025
0
{
4026
0
  GFile *work_file = NULL;
4027
0
  GList *list = NULL, *l;
4028
0
  GError *my_error = NULL;
4029
4030
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
4031
4032
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
4033
0
    return FALSE;
4034
4035
  /* Try for the simple case of not having to create any parent
4036
   * directories.  If any parent directory needs to be created, this
4037
   * call will fail with NOT_FOUND. If that happens, then that value of
4038
   * my_error persists into the while loop below.
4039
   */
4040
0
  g_file_make_directory (file, cancellable, &my_error);
4041
0
  if (!g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
4042
0
    {
4043
0
      if (my_error)
4044
0
        g_propagate_error (error, my_error);
4045
0
      return my_error == NULL;
4046
0
    }
4047
4048
0
  work_file = g_object_ref (file);
4049
4050
  /* Creates the parent directories as needed. In case any particular
4051
   * creation operation fails for lack of other parent directories
4052
   * (NOT_FOUND), the directory is added to a list of directories to
4053
   * create later, and the value of my_error is retained until the next
4054
   * iteration of the loop.  After the loop my_error should either be
4055
   * empty or contain a real failure condition.
4056
   */
4057
0
  while (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
4058
0
    {
4059
0
      GFile *parent_file;
4060
4061
0
      parent_file = g_file_get_parent (work_file);
4062
0
      if (parent_file == NULL)
4063
0
        break;
4064
4065
0
      g_clear_error (&my_error);
4066
0
      g_file_make_directory (parent_file, cancellable, &my_error);
4067
      /* Another process may have created the directory in between the
4068
       * G_IO_ERROR_NOT_FOUND and now
4069
       */
4070
0
      if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
4071
0
        g_clear_error (&my_error);
4072
4073
0
      g_object_unref (work_file);
4074
0
      work_file = g_object_ref (parent_file);
4075
4076
0
      if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
4077
0
        list = g_list_prepend (list, parent_file);  /* Transfer ownership of ref */
4078
0
      else
4079
0
        g_object_unref (parent_file);
4080
0
    }
4081
4082
  /* All directories should be able to be created now, so an error at
4083
   * this point means the whole operation must fail -- except an EXISTS
4084
   * error, which means that another process already created the
4085
   * directory in between the previous failure and now.
4086
   */
4087
0
  for (l = list; my_error == NULL && l; l = l->next)
4088
0
    {
4089
0
      g_file_make_directory ((GFile *) l->data, cancellable, &my_error);
4090
0
      if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
4091
0
        g_clear_error (&my_error);
4092
0
    }
4093
4094
0
  if (work_file)
4095
0
    g_object_unref (work_file);
4096
4097
  /* Clean up */
4098
0
  while (list != NULL)
4099
0
    {
4100
0
      g_object_unref ((GFile *) list->data);
4101
0
      list = g_list_remove (list, list->data);
4102
0
    }
4103
4104
  /* At this point an error in my_error means a that something
4105
   * unexpected failed in either of the loops above, so the whole
4106
   * operation must fail.
4107
   */
4108
0
  if (my_error != NULL)
4109
0
    {
4110
0
      g_propagate_error (error, my_error);
4111
0
      return FALSE;
4112
0
    }
4113
4114
0
  return g_file_make_directory (file, cancellable, error);
4115
0
}
4116
4117
/**
4118
 * g_file_make_symbolic_link:
4119
 * @file: a #GFile with the name of the symlink to create
4120
 * @symlink_value: (type filename): a string with the path for the target
4121
 *   of the new symlink
4122
 * @cancellable: (nullable): optional #GCancellable object,
4123
 *   %NULL to ignore
4124
 * @error: a #GError
4125
 *
4126
 * Creates a symbolic link named @file which contains the string
4127
 * @symlink_value.
4128
 *
4129
 * If @cancellable is not %NULL, then the operation can be cancelled by
4130
 * triggering the cancellable object from another thread. If the operation
4131
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4132
 *
4133
 * Returns: %TRUE on the creation of a new symlink, %FALSE otherwise.
4134
 */
4135
gboolean
4136
g_file_make_symbolic_link (GFile         *file,
4137
                           const char    *symlink_value,
4138
                           GCancellable  *cancellable,
4139
                           GError       **error)
4140
0
{
4141
0
  GFileIface *iface;
4142
4143
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
4144
0
  g_return_val_if_fail (symlink_value != NULL, FALSE);
4145
4146
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
4147
0
    return FALSE;
4148
4149
0
  if (*symlink_value == '\0')
4150
0
    {
4151
0
      g_set_error_literal (error, G_IO_ERROR,
4152
0
                           G_IO_ERROR_INVALID_ARGUMENT,
4153
0
                           _("Invalid symlink value given"));
4154
0
      return FALSE;
4155
0
    }
4156
4157
0
  iface = G_FILE_GET_IFACE (file);
4158
4159
0
  if (iface->make_symbolic_link == NULL)
4160
0
    {
4161
0
      g_set_error_literal (error, G_IO_ERROR,
4162
0
                           G_IO_ERROR_NOT_SUPPORTED,
4163
0
                           _("Symbolic links not supported"));
4164
0
      return FALSE;
4165
0
    }
4166
4167
0
  return (* iface->make_symbolic_link) (file, symlink_value, cancellable, error);
4168
0
}
4169
4170
static void
4171
make_symbolic_link_async_thread (GTask         *task,
4172
                                 gpointer       object,
4173
                                 gpointer       task_data,
4174
                                 GCancellable  *cancellable)
4175
0
{
4176
0
  const char *symlink_value = task_data;
4177
0
  GError *error = NULL;
4178
4179
0
  if (g_file_make_symbolic_link (G_FILE (object), symlink_value, cancellable, &error))
4180
0
    g_task_return_boolean (task, TRUE);
4181
0
  else
4182
0
    g_task_return_error (task, g_steal_pointer (&error));
4183
0
}
4184
4185
static void
4186
g_file_real_make_symbolic_link_async (GFile               *file,
4187
                                      const char          *symlink_value,
4188
                                      int                  io_priority,
4189
                                      GCancellable        *cancellable,
4190
                                      GAsyncReadyCallback  callback,
4191
                                      gpointer             user_data)
4192
0
{
4193
0
  GTask *task;
4194
4195
0
  g_return_if_fail (G_IS_FILE (file));
4196
0
  g_return_if_fail (symlink_value != NULL);
4197
0
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
4198
4199
0
  task = g_task_new (file, cancellable, callback, user_data);
4200
0
  g_task_set_source_tag (task, g_file_real_make_symbolic_link_async);
4201
0
  g_task_set_task_data (task, g_strdup (symlink_value), g_free);
4202
0
  g_task_set_priority (task, io_priority);
4203
4204
0
  g_task_run_in_thread (task, make_symbolic_link_async_thread);
4205
0
  g_object_unref (task);
4206
0
}
4207
4208
/**
4209
 * g_file_make_symbolic_link_async:
4210
 * @file: a #GFile with the name of the symlink to create
4211
 * @symlink_value: (type filename): a string with the path for the target
4212
 *   of the new symlink
4213
 * @io_priority: the [I/O priority][io-priority] of the request
4214
 * @cancellable: (nullable): optional #GCancellable object,
4215
 *   %NULL to ignore
4216
 * @callback: a #GAsyncReadyCallback to call
4217
 *   when the request is satisfied
4218
 * @user_data: the data to pass to callback function
4219
 *
4220
 * Asynchronously creates a symbolic link named @file which contains the
4221
 * string @symlink_value.
4222
 *
4223
 * Virtual: make_symbolic_link_async
4224
 * Since: 2.74
4225
 */
4226
void
4227
g_file_make_symbolic_link_async (GFile               *file,
4228
                                 const char          *symlink_value,
4229
                                 int                  io_priority,
4230
                                 GCancellable        *cancellable,
4231
                                 GAsyncReadyCallback  callback,
4232
                                 gpointer             user_data)
4233
0
{
4234
0
  GFileIface *iface;
4235
4236
0
  g_return_if_fail (G_IS_FILE (file));
4237
0
  g_return_if_fail (symlink_value != NULL);
4238
0
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
4239
4240
0
  iface = G_FILE_GET_IFACE (file);
4241
4242
  /* Default implementation should always be provided by GFileIface */
4243
0
  g_assert (iface->make_symbolic_link_async != NULL);
4244
4245
0
  (* iface->make_symbolic_link_async) (file, symlink_value, io_priority,
4246
0
                                       cancellable, callback, user_data);
4247
0
}
4248
4249
static gboolean
4250
g_file_real_make_symbolic_link_finish (GFile         *file,
4251
                                       GAsyncResult  *result,
4252
                                       GError       **error)
4253
0
{
4254
0
  g_return_val_if_fail (g_task_is_valid (result, file), FALSE);
4255
4256
0
  return g_task_propagate_boolean (G_TASK (result), error);
4257
0
}
4258
4259
/**
4260
 * g_file_make_symbolic_link_finish:
4261
 * @file: input #GFile
4262
 * @result: a #GAsyncResult
4263
 * @error: a #GError, or %NULL
4264
 *
4265
 * Finishes an asynchronous symbolic link creation, started with
4266
 * g_file_make_symbolic_link_async().
4267
 *
4268
 * Virtual: make_symbolic_link_finish
4269
 * Returns: %TRUE on successful directory creation, %FALSE otherwise.
4270
 * Since: 2.74
4271
 */
4272
gboolean
4273
g_file_make_symbolic_link_finish (GFile         *file,
4274
                                  GAsyncResult  *result,
4275
                                  GError       **error)
4276
0
{
4277
0
  GFileIface *iface;
4278
4279
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
4280
0
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
4281
4282
0
  iface = G_FILE_GET_IFACE (file);
4283
  /* Default implementation should always be provided by GFileIface */
4284
0
  g_assert (iface->make_symbolic_link_finish != NULL);
4285
4286
0
  return (* iface->make_symbolic_link_finish) (file, result, error);
4287
0
}
4288
4289
/**
4290
 * g_file_delete:
4291
 * @file: input #GFile
4292
 * @cancellable: (nullable): optional #GCancellable object,
4293
 *   %NULL to ignore
4294
 * @error: a #GError, or %NULL
4295
 *
4296
 * Deletes a file. If the @file is a directory, it will only be
4297
 * deleted if it is empty. This has the same semantics as g_unlink().
4298
 *
4299
 * If @file doesn’t exist, %G_IO_ERROR_NOT_FOUND will be returned. This allows
4300
 * for deletion to be implemented avoiding
4301
 * [time-of-check to time-of-use races](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use):
4302
 * |[
4303
 * g_autoptr(GError) local_error = NULL;
4304
 * if (!g_file_delete (my_file, my_cancellable, &local_error) &&
4305
 *     !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
4306
 *   {
4307
 *     // deletion failed for some reason other than the file not existing:
4308
 *     // so report the error
4309
 *     g_warning ("Failed to delete %s: %s",
4310
 *                g_file_peek_path (my_file), local_error->message);
4311
 *   }
4312
 * ]|
4313
 *
4314
 * If @cancellable is not %NULL, then the operation can be cancelled by
4315
 * triggering the cancellable object from another thread. If the operation
4316
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4317
 *
4318
 * Virtual: delete_file
4319
 * Returns: %TRUE if the file was deleted. %FALSE otherwise.
4320
 */
4321
gboolean
4322
g_file_delete (GFile         *file,
4323
               GCancellable  *cancellable,
4324
               GError       **error)
4325
0
{
4326
0
  GFileIface *iface;
4327
4328
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
4329
4330
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
4331
0
    return FALSE;
4332
4333
0
  iface = G_FILE_GET_IFACE (file);
4334
4335
0
  if (iface->delete_file == NULL)
4336
0
    {
4337
0
      g_set_error_literal (error, G_IO_ERROR,
4338
0
                           G_IO_ERROR_NOT_SUPPORTED,
4339
0
                           _("Operation not supported"));
4340
0
      return FALSE;
4341
0
    }
4342
4343
0
  return (* iface->delete_file) (file, cancellable, error);
4344
0
}
4345
4346
/**
4347
 * g_file_delete_async:
4348
 * @file: input #GFile
4349
 * @io_priority: the [I/O priority][io-priority] of the request
4350
 * @cancellable: (nullable): optional #GCancellable object,
4351
 *   %NULL to ignore
4352
 * @callback: a #GAsyncReadyCallback to call
4353
 *   when the request is satisfied
4354
 * @user_data: the data to pass to callback function
4355
 *
4356
 * Asynchronously delete a file. If the @file is a directory, it will
4357
 * only be deleted if it is empty.  This has the same semantics as
4358
 * g_unlink().
4359
 *
4360
 * Virtual: delete_file_async
4361
 * Since: 2.34
4362
 */
4363
void
4364
g_file_delete_async (GFile               *file,
4365
                     int                  io_priority,
4366
                     GCancellable        *cancellable,
4367
                     GAsyncReadyCallback  callback,
4368
                     gpointer             user_data)
4369
0
{
4370
0
  GFileIface *iface;
4371
4372
0
  g_return_if_fail (G_IS_FILE (file));
4373
4374
0
  iface = G_FILE_GET_IFACE (file);
4375
0
  (* iface->delete_file_async) (file,
4376
0
                                io_priority,
4377
0
                                cancellable,
4378
0
                                callback,
4379
0
                                user_data);
4380
0
}
4381
4382
/**
4383
 * g_file_delete_finish:
4384
 * @file: input #GFile
4385
 * @result: a #GAsyncResult
4386
 * @error: a #GError, or %NULL
4387
 *
4388
 * Finishes deleting a file started with g_file_delete_async().
4389
 *
4390
 * Virtual: delete_file_finish
4391
 * Returns: %TRUE if the file was deleted. %FALSE otherwise.
4392
 * Since: 2.34
4393
 **/
4394
gboolean
4395
g_file_delete_finish (GFile         *file,
4396
                      GAsyncResult  *result,
4397
                      GError       **error)
4398
0
{
4399
0
  GFileIface *iface;
4400
4401
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
4402
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4403
4404
0
  if (g_async_result_legacy_propagate_error (result, error))
4405
0
    return FALSE;
4406
4407
0
  iface = G_FILE_GET_IFACE (file);
4408
0
  return (* iface->delete_file_finish) (file, result, error);
4409
0
}
4410
4411
/**
4412
 * g_file_trash:
4413
 * @file: #GFile to send to trash
4414
 * @cancellable: (nullable): optional #GCancellable object,
4415
 *   %NULL to ignore
4416
 * @error: a #GError, or %NULL
4417
 *
4418
 * Sends @file to the "Trashcan", if possible. This is similar to
4419
 * deleting it, but the user can recover it before emptying the trashcan.
4420
 * Not all file systems support trashing, so this call can return the
4421
 * %G_IO_ERROR_NOT_SUPPORTED error. Since GLib 2.66, the `x-gvfs-notrash` unix
4422
 * mount option can be used to disable g_file_trash() support for certain
4423
 * mounts, the %G_IO_ERROR_NOT_SUPPORTED error will be returned in that case.
4424
 *
4425
 * If @cancellable is not %NULL, then the operation can be cancelled by
4426
 * triggering the cancellable object from another thread. If the operation
4427
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4428
 *
4429
 * Virtual: trash
4430
 * Returns: %TRUE on successful trash, %FALSE otherwise.
4431
 */
4432
gboolean
4433
g_file_trash (GFile         *file,
4434
              GCancellable  *cancellable,
4435
              GError       **error)
4436
0
{
4437
0
  GFileIface *iface;
4438
4439
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
4440
4441
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
4442
0
    return FALSE;
4443
4444
0
  iface = G_FILE_GET_IFACE (file);
4445
4446
0
  if (iface->trash == NULL)
4447
0
    {
4448
0
      g_set_error_literal (error,
4449
0
                           G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
4450
0
                           _("Trash not supported"));
4451
0
      return FALSE;
4452
0
    }
4453
4454
0
  return (* iface->trash) (file, cancellable, error);
4455
0
}
4456
4457
/**
4458
 * g_file_trash_async:
4459
 * @file: input #GFile
4460
 * @io_priority: the [I/O priority][io-priority] of the request
4461
 * @cancellable: (nullable): optional #GCancellable object,
4462
 *   %NULL to ignore
4463
 * @callback: a #GAsyncReadyCallback to call
4464
 *   when the request is satisfied
4465
 * @user_data: the data to pass to callback function
4466
 *
4467
 * Asynchronously sends @file to the Trash location, if possible.
4468
 *
4469
 * Virtual: trash_async
4470
 * Since: 2.38
4471
 */
4472
void
4473
g_file_trash_async (GFile               *file,
4474
                    int                  io_priority,
4475
                    GCancellable        *cancellable,
4476
                    GAsyncReadyCallback  callback,
4477
                    gpointer             user_data)
4478
0
{
4479
0
  GFileIface *iface;
4480
4481
0
  g_return_if_fail (G_IS_FILE (file));
4482
4483
0
  iface = G_FILE_GET_IFACE (file);
4484
0
  (* iface->trash_async) (file,
4485
0
                          io_priority,
4486
0
                          cancellable,
4487
0
                          callback,
4488
0
                          user_data);
4489
0
}
4490
4491
/**
4492
 * g_file_trash_finish:
4493
 * @file: input #GFile
4494
 * @result: a #GAsyncResult
4495
 * @error: a #GError, or %NULL
4496
 *
4497
 * Finishes an asynchronous file trashing operation, started with
4498
 * g_file_trash_async().
4499
 *
4500
 * Virtual: trash_finish
4501
 * Returns: %TRUE on successful trash, %FALSE otherwise.
4502
 * Since: 2.38
4503
 */
4504
gboolean
4505
g_file_trash_finish (GFile         *file,
4506
                     GAsyncResult  *result,
4507
                     GError       **error)
4508
0
{
4509
0
  GFileIface *iface;
4510
4511
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
4512
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4513
4514
0
  iface = G_FILE_GET_IFACE (file);
4515
0
  return (* iface->trash_finish) (file, result, error);
4516
0
}
4517
4518
/**
4519
 * g_file_set_display_name:
4520
 * @file: input #GFile
4521
 * @display_name: a string
4522
 * @cancellable: (nullable): optional #GCancellable object,
4523
 *   %NULL to ignore
4524
 * @error: a #GError, or %NULL
4525
 *
4526
 * Renames @file to the specified display name.
4527
 *
4528
 * The display name is converted from UTF-8 to the correct encoding
4529
 * for the target filesystem if possible and the @file is renamed to this.
4530
 *
4531
 * If you want to implement a rename operation in the user interface the
4532
 * edit name (%G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME) should be used as the
4533
 * initial value in the rename widget, and then the result after editing
4534
 * should be passed to g_file_set_display_name().
4535
 *
4536
 * On success the resulting converted filename is returned.
4537
 *
4538
 * If @cancellable is not %NULL, then the operation can be cancelled by
4539
 * triggering the cancellable object from another thread. If the operation
4540
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4541
 *
4542
 * Returns: (transfer full): a #GFile specifying what @file was renamed to,
4543
 *   or %NULL if there was an error.
4544
 *   Free the returned object with g_object_unref().
4545
 */
4546
GFile *
4547
g_file_set_display_name (GFile         *file,
4548
                         const gchar   *display_name,
4549
                         GCancellable  *cancellable,
4550
                         GError       **error)
4551
0
{
4552
0
  GFileIface *iface;
4553
4554
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
4555
0
  g_return_val_if_fail (display_name != NULL, NULL);
4556
4557
0
  if (strchr (display_name, G_DIR_SEPARATOR) != NULL)
4558
0
    {
4559
0
      g_set_error (error,
4560
0
                   G_IO_ERROR,
4561
0
                   G_IO_ERROR_INVALID_ARGUMENT,
4562
0
                   _("File names cannot contain “%c”"), G_DIR_SEPARATOR);
4563
0
      return NULL;
4564
0
    }
4565
4566
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
4567
0
    return NULL;
4568
4569
0
  iface = G_FILE_GET_IFACE (file);
4570
4571
0
  return (* iface->set_display_name) (file, display_name, cancellable, error);
4572
0
}
4573
4574
/**
4575
 * g_file_set_display_name_async:
4576
 * @file: input #GFile
4577
 * @display_name: a string
4578
 * @io_priority: the [I/O priority][io-priority] of the request
4579
 * @cancellable: (nullable): optional #GCancellable object,
4580
 *   %NULL to ignore
4581
 * @callback: (scope async): a #GAsyncReadyCallback to call
4582
 *   when the request is satisfied
4583
 * @user_data: (closure): the data to pass to callback function
4584
 *
4585
 * Asynchronously sets the display name for a given #GFile.
4586
 *
4587
 * For more details, see g_file_set_display_name() which is
4588
 * the synchronous version of this call.
4589
 *
4590
 * When the operation is finished, @callback will be called.
4591
 * You can then call g_file_set_display_name_finish() to get
4592
 * the result of the operation.
4593
 */
4594
void
4595
g_file_set_display_name_async (GFile               *file,
4596
                               const gchar         *display_name,
4597
                               gint                 io_priority,
4598
                               GCancellable        *cancellable,
4599
                               GAsyncReadyCallback  callback,
4600
                               gpointer             user_data)
4601
0
{
4602
0
  GFileIface *iface;
4603
4604
0
  g_return_if_fail (G_IS_FILE (file));
4605
0
  g_return_if_fail (display_name != NULL);
4606
4607
0
  iface = G_FILE_GET_IFACE (file);
4608
0
  (* iface->set_display_name_async) (file,
4609
0
                                     display_name,
4610
0
                                     io_priority,
4611
0
                                     cancellable,
4612
0
                                     callback,
4613
0
                                     user_data);
4614
0
}
4615
4616
/**
4617
 * g_file_set_display_name_finish:
4618
 * @file: input #GFile
4619
 * @res: a #GAsyncResult
4620
 * @error: a #GError, or %NULL
4621
 *
4622
 * Finishes setting a display name started with
4623
 * g_file_set_display_name_async().
4624
 *
4625
 * Returns: (transfer full): a #GFile or %NULL on error.
4626
 *   Free the returned object with g_object_unref().
4627
 */
4628
GFile *
4629
g_file_set_display_name_finish (GFile         *file,
4630
                                GAsyncResult  *res,
4631
                                GError       **error)
4632
0
{
4633
0
  GFileIface *iface;
4634
4635
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
4636
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
4637
4638
0
  if (g_async_result_legacy_propagate_error (res, error))
4639
0
    return NULL;
4640
4641
0
  iface = G_FILE_GET_IFACE (file);
4642
0
  return (* iface->set_display_name_finish) (file, res, error);
4643
0
}
4644
4645
/**
4646
 * g_file_query_settable_attributes:
4647
 * @file: input #GFile
4648
 * @cancellable: (nullable): optional #GCancellable object,
4649
 *   %NULL to ignore
4650
 * @error: a #GError, or %NULL
4651
 *
4652
 * Obtain the list of settable attributes for the file.
4653
 *
4654
 * Returns the type and full attribute name of all the attributes
4655
 * that can be set on this file. This doesn't mean setting it will
4656
 * always succeed though, you might get an access failure, or some
4657
 * specific file may not support a specific attribute.
4658
 *
4659
 * If @cancellable is not %NULL, then the operation can be cancelled by
4660
 * triggering the cancellable object from another thread. If the operation
4661
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4662
 *
4663
 * Returns: (transfer full): a #GFileAttributeInfoList describing the settable attributes.
4664
 *   When you are done with it, release it with
4665
 *   g_file_attribute_info_list_unref()
4666
 */
4667
GFileAttributeInfoList *
4668
g_file_query_settable_attributes (GFile         *file,
4669
                                  GCancellable  *cancellable,
4670
                                  GError       **error)
4671
0
{
4672
0
  GFileIface *iface;
4673
0
  GError *my_error;
4674
0
  GFileAttributeInfoList *list;
4675
4676
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
4677
4678
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
4679
0
    return NULL;
4680
4681
0
  iface = G_FILE_GET_IFACE (file);
4682
4683
0
  if (iface->query_settable_attributes == NULL)
4684
0
    return g_file_attribute_info_list_new ();
4685
4686
0
  my_error = NULL;
4687
0
  list = (* iface->query_settable_attributes) (file, cancellable, &my_error);
4688
4689
0
  if (list == NULL)
4690
0
    {
4691
0
      if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
4692
0
        {
4693
0
          list = g_file_attribute_info_list_new ();
4694
0
          g_error_free (my_error);
4695
0
        }
4696
0
      else
4697
0
        g_propagate_error (error, my_error);
4698
0
    }
4699
4700
0
  return list;
4701
0
}
4702
4703
/**
4704
 * g_file_query_writable_namespaces:
4705
 * @file: input #GFile
4706
 * @cancellable: (nullable): optional #GCancellable object,
4707
 *   %NULL to ignore
4708
 * @error: a #GError, or %NULL
4709
 *
4710
 * Obtain the list of attribute namespaces where new attributes
4711
 * can be created by a user. An example of this is extended
4712
 * attributes (in the "xattr" namespace).
4713
 *
4714
 * If @cancellable is not %NULL, then the operation can be cancelled by
4715
 * triggering the cancellable object from another thread. If the operation
4716
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4717
 *
4718
 * Returns: (transfer full): a #GFileAttributeInfoList describing the writable namespaces.
4719
 *   When you are done with it, release it with
4720
 *   g_file_attribute_info_list_unref()
4721
 */
4722
GFileAttributeInfoList *
4723
g_file_query_writable_namespaces (GFile         *file,
4724
                                  GCancellable  *cancellable,
4725
                                  GError       **error)
4726
0
{
4727
0
  GFileIface *iface;
4728
0
  GError *my_error;
4729
0
  GFileAttributeInfoList *list;
4730
4731
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
4732
4733
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
4734
0
    return NULL;
4735
4736
0
  iface = G_FILE_GET_IFACE (file);
4737
4738
0
  if (iface->query_writable_namespaces == NULL)
4739
0
    return g_file_attribute_info_list_new ();
4740
4741
0
  my_error = NULL;
4742
0
  list = (* iface->query_writable_namespaces) (file, cancellable, &my_error);
4743
4744
0
  if (list == NULL)
4745
0
    {
4746
0
      g_warn_if_reached();
4747
0
      list = g_file_attribute_info_list_new ();
4748
0
    }
4749
4750
0
  if (my_error != NULL)
4751
0
    {
4752
0
      if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
4753
0
        {
4754
0
          g_error_free (my_error);
4755
0
        }
4756
0
      else
4757
0
        g_propagate_error (error, my_error);
4758
0
    }
4759
4760
0
  return list;
4761
0
}
4762
4763
/**
4764
 * g_file_set_attribute:
4765
 * @file: input #GFile
4766
 * @attribute: a string containing the attribute's name
4767
 * @type: The type of the attribute
4768
 * @value_p: (nullable): a pointer to the value (or the pointer
4769
 *   itself if the type is a pointer type)
4770
 * @flags: a set of #GFileQueryInfoFlags
4771
 * @cancellable: (nullable): optional #GCancellable object,
4772
 *   %NULL to ignore
4773
 * @error: a #GError, or %NULL
4774
 *
4775
 * Sets an attribute in the file with attribute name @attribute to @value_p.
4776
 *
4777
 * Some attributes can be unset by setting @type to
4778
 * %G_FILE_ATTRIBUTE_TYPE_INVALID and @value_p to %NULL.
4779
 *
4780
 * If @cancellable is not %NULL, then the operation can be cancelled by
4781
 * triggering the cancellable object from another thread. If the operation
4782
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4783
 *
4784
 * Returns: %TRUE if the attribute was set, %FALSE otherwise.
4785
 */
4786
gboolean
4787
g_file_set_attribute (GFile                *file,
4788
                      const gchar          *attribute,
4789
                      GFileAttributeType    type,
4790
                      gpointer              value_p,
4791
                      GFileQueryInfoFlags   flags,
4792
                      GCancellable         *cancellable,
4793
                      GError              **error)
4794
0
{
4795
0
  GFileIface *iface;
4796
4797
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
4798
0
  g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
4799
4800
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
4801
0
    return FALSE;
4802
4803
0
  iface = G_FILE_GET_IFACE (file);
4804
4805
0
  if (iface->set_attribute == NULL)
4806
0
    {
4807
0
      g_set_error_literal (error, G_IO_ERROR,
4808
0
                           G_IO_ERROR_NOT_SUPPORTED,
4809
0
                           _("Operation not supported"));
4810
0
      return FALSE;
4811
0
    }
4812
4813
0
  return (* iface->set_attribute) (file, attribute, type, value_p, flags, cancellable, error);
4814
0
}
4815
4816
/**
4817
 * g_file_set_attributes_from_info:
4818
 * @file: input #GFile
4819
 * @info: a #GFileInfo
4820
 * @flags: #GFileQueryInfoFlags
4821
 * @cancellable: (nullable): optional #GCancellable object,
4822
 *   %NULL to ignore
4823
 * @error: a #GError, or %NULL
4824
 *
4825
 * Tries to set all attributes in the #GFileInfo on the target
4826
 * values, not stopping on the first error.
4827
 *
4828
 * If there is any error during this operation then @error will
4829
 * be set to the first error. Error on particular fields are flagged
4830
 * by setting the "status" field in the attribute value to
4831
 * %G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING, which means you can
4832
 * also detect further errors.
4833
 *
4834
 * If @cancellable is not %NULL, then the operation can be cancelled by
4835
 * triggering the cancellable object from another thread. If the operation
4836
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4837
 *
4838
 * Returns: %FALSE if there was any error, %TRUE otherwise.
4839
 */
4840
gboolean
4841
g_file_set_attributes_from_info (GFile                *file,
4842
                                 GFileInfo            *info,
4843
                                 GFileQueryInfoFlags   flags,
4844
                                 GCancellable         *cancellable,
4845
                                 GError              **error)
4846
0
{
4847
0
  GFileIface *iface;
4848
4849
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
4850
0
  g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
4851
4852
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
4853
0
    return FALSE;
4854
4855
0
  g_file_info_clear_status (info);
4856
4857
0
  iface = G_FILE_GET_IFACE (file);
4858
4859
0
  return (* iface->set_attributes_from_info) (file,
4860
0
                                              info,
4861
0
                                              flags,
4862
0
                                              cancellable,
4863
0
                                              error);
4864
0
}
4865
4866
static gboolean
4867
g_file_real_set_attributes_from_info (GFile                *file,
4868
                                      GFileInfo            *info,
4869
                                      GFileQueryInfoFlags   flags,
4870
                                      GCancellable         *cancellable,
4871
                                      GError              **error)
4872
0
{
4873
0
  char **attributes;
4874
0
  int i;
4875
0
  gboolean res;
4876
0
  GFileAttributeValue *value;
4877
4878
0
  res = TRUE;
4879
4880
0
  attributes = g_file_info_list_attributes (info, NULL);
4881
4882
0
  for (i = 0; attributes[i] != NULL; i++)
4883
0
    {
4884
0
      value = _g_file_info_get_attribute_value (info, attributes[i]);
4885
4886
0
      if (value->status != G_FILE_ATTRIBUTE_STATUS_UNSET)
4887
0
        continue;
4888
4889
0
      if (!g_file_set_attribute (file, attributes[i],
4890
0
                                 value->type, _g_file_attribute_value_peek_as_pointer (value),
4891
0
                                 flags, cancellable, error))
4892
0
        {
4893
0
          value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING;
4894
0
          res = FALSE;
4895
          /* Don't set error multiple times */
4896
0
          error = NULL;
4897
0
        }
4898
0
      else
4899
0
        value->status = G_FILE_ATTRIBUTE_STATUS_SET;
4900
0
    }
4901
4902
0
  g_strfreev (attributes);
4903
4904
0
  return res;
4905
0
}
4906
4907
/**
4908
 * g_file_set_attributes_async:
4909
 * @file: input #GFile
4910
 * @info: a #GFileInfo
4911
 * @flags: a #GFileQueryInfoFlags
4912
 * @io_priority: the [I/O priority][io-priority] of the request
4913
 * @cancellable: (nullable): optional #GCancellable object,
4914
 *   %NULL to ignore
4915
 * @callback: (scope async): a #GAsyncReadyCallback
4916
 * @user_data: (closure): a #gpointer
4917
 *
4918
 * Asynchronously sets the attributes of @file with @info.
4919
 *
4920
 * For more details, see g_file_set_attributes_from_info(),
4921
 * which is the synchronous version of this call.
4922
 *
4923
 * When the operation is finished, @callback will be called.
4924
 * You can then call g_file_set_attributes_finish() to get
4925
 * the result of the operation.
4926
 */
4927
void
4928
g_file_set_attributes_async (GFile               *file,
4929
                             GFileInfo           *info,
4930
                             GFileQueryInfoFlags  flags,
4931
                             int                  io_priority,
4932
                             GCancellable        *cancellable,
4933
                             GAsyncReadyCallback  callback,
4934
                             gpointer             user_data)
4935
0
{
4936
0
  GFileIface *iface;
4937
4938
0
  g_return_if_fail (G_IS_FILE (file));
4939
0
  g_return_if_fail (G_IS_FILE_INFO (info));
4940
4941
0
  iface = G_FILE_GET_IFACE (file);
4942
0
  (* iface->set_attributes_async) (file,
4943
0
                                   info,
4944
0
                                   flags,
4945
0
                                   io_priority,
4946
0
                                   cancellable,
4947
0
                                   callback,
4948
0
                                   user_data);
4949
0
}
4950
4951
/**
4952
 * g_file_set_attributes_finish:
4953
 * @file: input #GFile
4954
 * @result: a #GAsyncResult
4955
 * @info: (out) (transfer full): a #GFileInfo
4956
 * @error: a #GError, or %NULL
4957
 *
4958
 * Finishes setting an attribute started in g_file_set_attributes_async().
4959
 *
4960
 * Returns: %TRUE if the attributes were set correctly, %FALSE otherwise.
4961
 */
4962
gboolean
4963
g_file_set_attributes_finish (GFile         *file,
4964
                              GAsyncResult  *result,
4965
                              GFileInfo    **info,
4966
                              GError       **error)
4967
0
{
4968
0
  GFileIface *iface;
4969
4970
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
4971
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4972
4973
  /* No standard handling of errors here, as we must set info even
4974
   * on errors
4975
   */
4976
0
  iface = G_FILE_GET_IFACE (file);
4977
0
  return (* iface->set_attributes_finish) (file, result, info, error);
4978
0
}
4979
4980
/**
4981
 * g_file_set_attribute_string:
4982
 * @file: input #GFile
4983
 * @attribute: a string containing the attribute's name
4984
 * @value: a string containing the attribute's value
4985
 * @flags: #GFileQueryInfoFlags
4986
 * @cancellable: (nullable): optional #GCancellable object,
4987
 *   %NULL to ignore
4988
 * @error: a #GError, or %NULL
4989
 *
4990
 * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_STRING to @value.
4991
 * If @attribute is of a different type, this operation will fail.
4992
 *
4993
 * If @cancellable is not %NULL, then the operation can be cancelled by
4994
 * triggering the cancellable object from another thread. If the operation
4995
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4996
 *
4997
 * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
4998
 */
4999
gboolean
5000
g_file_set_attribute_string (GFile                *file,
5001
                             const char           *attribute,
5002
                             const char           *value,
5003
                             GFileQueryInfoFlags   flags,
5004
                             GCancellable         *cancellable,
5005
                             GError              **error)
5006
0
{
5007
0
  return g_file_set_attribute (file, attribute,
5008
0
                               G_FILE_ATTRIBUTE_TYPE_STRING, (gpointer)value,
5009
0
                               flags, cancellable, error);
5010
0
}
5011
5012
/**
5013
 * g_file_set_attribute_byte_string:
5014
 * @file: input #GFile
5015
 * @attribute: a string containing the attribute's name
5016
 * @value: a string containing the attribute's new value
5017
 * @flags: a #GFileQueryInfoFlags
5018
 * @cancellable: (nullable): optional #GCancellable object,
5019
 *   %NULL to ignore
5020
 * @error: a #GError, or %NULL
5021
 *
5022
 * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING to @value.
5023
 * If @attribute is of a different type, this operation will fail,
5024
 * returning %FALSE.
5025
 *
5026
 * If @cancellable is not %NULL, then the operation can be cancelled by
5027
 * triggering the cancellable object from another thread. If the operation
5028
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5029
 *
5030
 * Returns: %TRUE if the @attribute was successfully set to @value
5031
 *   in the @file, %FALSE otherwise.
5032
 */
5033
gboolean
5034
g_file_set_attribute_byte_string  (GFile                *file,
5035
                                   const gchar          *attribute,
5036
                                   const gchar          *value,
5037
                                   GFileQueryInfoFlags   flags,
5038
                                   GCancellable         *cancellable,
5039
                                   GError              **error)
5040
0
{
5041
0
  return g_file_set_attribute (file, attribute,
5042
0
                               G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, (gpointer)value,
5043
0
                               flags, cancellable, error);
5044
0
}
5045
5046
/**
5047
 * g_file_set_attribute_uint32:
5048
 * @file: input #GFile
5049
 * @attribute: a string containing the attribute's name
5050
 * @value: a #guint32 containing the attribute's new value
5051
 * @flags: a #GFileQueryInfoFlags
5052
 * @cancellable: (nullable): optional #GCancellable object,
5053
 *   %NULL to ignore
5054
 * @error: a #GError, or %NULL
5055
 *
5056
 * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT32 to @value.
5057
 * If @attribute is of a different type, this operation will fail.
5058
 *
5059
 * If @cancellable is not %NULL, then the operation can be cancelled by
5060
 * triggering the cancellable object from another thread. If the operation
5061
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5062
 *
5063
 * Returns: %TRUE if the @attribute was successfully set to @value
5064
 *   in the @file, %FALSE otherwise.
5065
 */
5066
gboolean
5067
g_file_set_attribute_uint32 (GFile                *file,
5068
                             const gchar          *attribute,
5069
                             guint32               value,
5070
                             GFileQueryInfoFlags   flags,
5071
                             GCancellable         *cancellable,
5072
                             GError              **error)
5073
0
{
5074
0
  return g_file_set_attribute (file, attribute,
5075
0
                               G_FILE_ATTRIBUTE_TYPE_UINT32, &value,
5076
0
                               flags, cancellable, error);
5077
0
}
5078
5079
/**
5080
 * g_file_set_attribute_int32:
5081
 * @file: input #GFile
5082
 * @attribute: a string containing the attribute's name
5083
 * @value: a #gint32 containing the attribute's new value
5084
 * @flags: a #GFileQueryInfoFlags
5085
 * @cancellable: (nullable): optional #GCancellable object,
5086
 *   %NULL to ignore
5087
 * @error: a #GError, or %NULL
5088
 *
5089
 * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT32 to @value.
5090
 * If @attribute is of a different type, this operation will fail.
5091
 *
5092
 * If @cancellable is not %NULL, then the operation can be cancelled by
5093
 * triggering the cancellable object from another thread. If the operation
5094
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5095
 *
5096
 * Returns: %TRUE if the @attribute was successfully set to @value
5097
 *   in the @file, %FALSE otherwise.
5098
 */
5099
gboolean
5100
g_file_set_attribute_int32 (GFile                *file,
5101
                            const gchar          *attribute,
5102
                            gint32                value,
5103
                            GFileQueryInfoFlags   flags,
5104
                            GCancellable         *cancellable,
5105
                            GError              **error)
5106
0
{
5107
0
  return g_file_set_attribute (file, attribute,
5108
0
                               G_FILE_ATTRIBUTE_TYPE_INT32, &value,
5109
0
                               flags, cancellable, error);
5110
0
}
5111
5112
/**
5113
 * g_file_set_attribute_uint64:
5114
 * @file: input #GFile
5115
 * @attribute: a string containing the attribute's name
5116
 * @value: a #guint64 containing the attribute's new value
5117
 * @flags: a #GFileQueryInfoFlags
5118
 * @cancellable: (nullable): optional #GCancellable object,
5119
 *   %NULL to ignore
5120
 * @error: a #GError, or %NULL
5121
 *
5122
 * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT64 to @value.
5123
 * If @attribute is of a different type, this operation will fail.
5124
 *
5125
 * If @cancellable is not %NULL, then the operation can be cancelled by
5126
 * triggering the cancellable object from another thread. If the operation
5127
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5128
 *
5129
 * Returns: %TRUE if the @attribute was successfully set to @value
5130
 *   in the @file, %FALSE otherwise.
5131
 */
5132
gboolean
5133
g_file_set_attribute_uint64 (GFile                *file,
5134
                             const gchar          *attribute,
5135
                             guint64               value,
5136
                             GFileQueryInfoFlags   flags,
5137
                             GCancellable         *cancellable,
5138
                             GError              **error)
5139
0
 {
5140
0
  return g_file_set_attribute (file, attribute,
5141
0
                               G_FILE_ATTRIBUTE_TYPE_UINT64, &value,
5142
0
                               flags, cancellable, error);
5143
0
}
5144
5145
/**
5146
 * g_file_set_attribute_int64:
5147
 * @file: input #GFile
5148
 * @attribute: a string containing the attribute's name
5149
 * @value: a #guint64 containing the attribute's new value
5150
 * @flags: a #GFileQueryInfoFlags
5151
 * @cancellable: (nullable): optional #GCancellable object,
5152
 *   %NULL to ignore
5153
 * @error: a #GError, or %NULL
5154
 *
5155
 * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT64 to @value.
5156
 * If @attribute is of a different type, this operation will fail.
5157
 *
5158
 * If @cancellable is not %NULL, then the operation can be cancelled by
5159
 * triggering the cancellable object from another thread. If the operation
5160
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5161
 *
5162
 * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
5163
 */
5164
gboolean
5165
g_file_set_attribute_int64 (GFile                *file,
5166
                            const gchar          *attribute,
5167
                            gint64                value,
5168
                            GFileQueryInfoFlags   flags,
5169
                            GCancellable         *cancellable,
5170
                            GError              **error)
5171
0
{
5172
0
  return g_file_set_attribute (file, attribute,
5173
0
                               G_FILE_ATTRIBUTE_TYPE_INT64, &value,
5174
0
                               flags, cancellable, error);
5175
0
}
5176
5177
/**
5178
 * g_file_mount_mountable:
5179
 * @file: input #GFile
5180
 * @flags: flags affecting the operation
5181
 * @mount_operation: (nullable): a #GMountOperation,
5182
 *   or %NULL to avoid user interaction
5183
 * @cancellable: (nullable): optional #GCancellable object,
5184
 *   %NULL to ignore
5185
 * @callback: (scope async) (nullable): a #GAsyncReadyCallback to call
5186
 *   when the request is satisfied, or %NULL
5187
 * @user_data: (closure): the data to pass to callback function
5188
 *
5189
 * Mounts a file of type G_FILE_TYPE_MOUNTABLE.
5190
 * Using @mount_operation, you can request callbacks when, for instance,
5191
 * passwords are needed during authentication.
5192
 *
5193
 * If @cancellable is not %NULL, then the operation can be cancelled by
5194
 * triggering the cancellable object from another thread. If the operation
5195
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5196
 *
5197
 * When the operation is finished, @callback will be called.
5198
 * You can then call g_file_mount_mountable_finish() to get
5199
 * the result of the operation.
5200
 */
5201
void
5202
g_file_mount_mountable (GFile               *file,
5203
                        GMountMountFlags     flags,
5204
                        GMountOperation     *mount_operation,
5205
                        GCancellable        *cancellable,
5206
                        GAsyncReadyCallback  callback,
5207
                        gpointer             user_data)
5208
0
{
5209
0
  GFileIface *iface;
5210
5211
0
  g_return_if_fail (G_IS_FILE (file));
5212
5213
0
  iface = G_FILE_GET_IFACE (file);
5214
5215
0
  if (iface->mount_mountable == NULL)
5216
0
    {
5217
0
      g_task_report_new_error (file, callback, user_data,
5218
0
                               g_file_mount_mountable,
5219
0
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
5220
0
                               _("Operation not supported"));
5221
0
      return;
5222
0
    }
5223
5224
0
  (* iface->mount_mountable) (file,
5225
0
                              flags,
5226
0
                              mount_operation,
5227
0
                              cancellable,
5228
0
                              callback,
5229
0
                              user_data);
5230
0
}
5231
5232
/**
5233
 * g_file_mount_mountable_finish:
5234
 * @file: input #GFile
5235
 * @result: a #GAsyncResult
5236
 * @error: a #GError, or %NULL
5237
 *
5238
 * Finishes a mount operation. See g_file_mount_mountable() for details.
5239
 *
5240
 * Finish an asynchronous mount operation that was started
5241
 * with g_file_mount_mountable().
5242
 *
5243
 * Returns: (transfer full): a #GFile or %NULL on error.
5244
 *   Free the returned object with g_object_unref().
5245
 */
5246
GFile *
5247
g_file_mount_mountable_finish (GFile         *file,
5248
                               GAsyncResult  *result,
5249
                               GError       **error)
5250
0
{
5251
0
  GFileIface *iface;
5252
5253
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
5254
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
5255
5256
0
  if (g_async_result_legacy_propagate_error (result, error))
5257
0
    return NULL;
5258
0
  else if (g_async_result_is_tagged (result, g_file_mount_mountable))
5259
0
    return g_task_propagate_pointer (G_TASK (result), error);
5260
5261
0
  iface = G_FILE_GET_IFACE (file);
5262
0
  return (* iface->mount_mountable_finish) (file, result, error);
5263
0
}
5264
5265
/**
5266
 * g_file_unmount_mountable:
5267
 * @file: input #GFile
5268
 * @flags: flags affecting the operation
5269
 * @cancellable: (nullable): optional #GCancellable object,
5270
 *   %NULL to ignore
5271
 * @callback: (scope async) (nullable): a #GAsyncReadyCallback to call
5272
 *   when the request is satisfied, or %NULL
5273
 * @user_data: (closure): the data to pass to callback function
5274
 *
5275
 * Unmounts a file of type G_FILE_TYPE_MOUNTABLE.
5276
 *
5277
 * If @cancellable is not %NULL, then the operation can be cancelled by
5278
 * triggering the cancellable object from another thread. If the operation
5279
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5280
 *
5281
 * When the operation is finished, @callback will be called.
5282
 * You can then call g_file_unmount_mountable_finish() to get
5283
 * the result of the operation.
5284
 *
5285
 * Deprecated: 2.22: Use g_file_unmount_mountable_with_operation() instead.
5286
 */
5287
void
5288
g_file_unmount_mountable (GFile               *file,
5289
                          GMountUnmountFlags   flags,
5290
                          GCancellable        *cancellable,
5291
                          GAsyncReadyCallback  callback,
5292
                          gpointer             user_data)
5293
0
{
5294
0
  GFileIface *iface;
5295
5296
0
  g_return_if_fail (G_IS_FILE (file));
5297
5298
0
  iface = G_FILE_GET_IFACE (file);
5299
5300
0
  if (iface->unmount_mountable == NULL)
5301
0
    {
5302
0
      g_task_report_new_error (file, callback, user_data,
5303
0
                               g_file_unmount_mountable_with_operation,
5304
0
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
5305
0
                               _("Operation not supported"));
5306
0
      return;
5307
0
    }
5308
5309
0
  (* iface->unmount_mountable) (file,
5310
0
                                flags,
5311
0
                                cancellable,
5312
0
                                callback,
5313
0
                                user_data);
5314
0
}
5315
5316
/**
5317
 * g_file_unmount_mountable_finish:
5318
 * @file: input #GFile
5319
 * @result: a #GAsyncResult
5320
 * @error: a #GError, or %NULL
5321
 *
5322
 * Finishes an unmount operation, see g_file_unmount_mountable() for details.
5323
 *
5324
 * Finish an asynchronous unmount operation that was started
5325
 * with g_file_unmount_mountable().
5326
 *
5327
 * Returns: %TRUE if the operation finished successfully.
5328
 *   %FALSE otherwise.
5329
 *
5330
 * Deprecated: 2.22: Use g_file_unmount_mountable_with_operation_finish()
5331
 *   instead.
5332
 */
5333
gboolean
5334
g_file_unmount_mountable_finish (GFile         *file,
5335
                                 GAsyncResult  *result,
5336
                                 GError       **error)
5337
0
{
5338
0
  GFileIface *iface;
5339
5340
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
5341
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
5342
5343
0
  if (g_async_result_legacy_propagate_error (result, error))
5344
0
    return FALSE;
5345
0
  else if (g_async_result_is_tagged (result, g_file_unmount_mountable_with_operation))
5346
0
    return g_task_propagate_boolean (G_TASK (result), error);
5347
5348
0
  iface = G_FILE_GET_IFACE (file);
5349
0
  return (* iface->unmount_mountable_finish) (file, result, error);
5350
0
}
5351
5352
/**
5353
 * g_file_unmount_mountable_with_operation:
5354
 * @file: input #GFile
5355
 * @flags: flags affecting the operation
5356
 * @mount_operation: (nullable): a #GMountOperation,
5357
 *   or %NULL to avoid user interaction
5358
 * @cancellable: (nullable): optional #GCancellable object,
5359
 *   %NULL to ignore
5360
 * @callback: (scope async) (nullable): a #GAsyncReadyCallback to call
5361
 *   when the request is satisfied, or %NULL
5362
 * @user_data: (closure): the data to pass to callback function
5363
 *
5364
 * Unmounts a file of type %G_FILE_TYPE_MOUNTABLE.
5365
 *
5366
 * If @cancellable is not %NULL, then the operation can be cancelled by
5367
 * triggering the cancellable object from another thread. If the operation
5368
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5369
 *
5370
 * When the operation is finished, @callback will be called.
5371
 * You can then call g_file_unmount_mountable_finish() to get
5372
 * the result of the operation.
5373
 *
5374
 * Since: 2.22
5375
 */
5376
void
5377
g_file_unmount_mountable_with_operation (GFile               *file,
5378
                                         GMountUnmountFlags   flags,
5379
                                         GMountOperation     *mount_operation,
5380
                                         GCancellable        *cancellable,
5381
                                         GAsyncReadyCallback  callback,
5382
                                         gpointer             user_data)
5383
0
{
5384
0
  GFileIface *iface;
5385
5386
0
  g_return_if_fail (G_IS_FILE (file));
5387
5388
0
  iface = G_FILE_GET_IFACE (file);
5389
5390
0
  if (iface->unmount_mountable == NULL && iface->unmount_mountable_with_operation == NULL)
5391
0
    {
5392
0
      g_task_report_new_error (file, callback, user_data,
5393
0
                               g_file_unmount_mountable_with_operation,
5394
0
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
5395
0
                               _("Operation not supported"));
5396
0
      return;
5397
0
    }
5398
5399
0
  if (iface->unmount_mountable_with_operation != NULL)
5400
0
    (* iface->unmount_mountable_with_operation) (file,
5401
0
                                                 flags,
5402
0
                                                 mount_operation,
5403
0
                                                 cancellable,
5404
0
                                                 callback,
5405
0
                                                 user_data);
5406
0
  else
5407
0
    (* iface->unmount_mountable) (file,
5408
0
                                  flags,
5409
0
                                  cancellable,
5410
0
                                  callback,
5411
0
                                  user_data);
5412
0
}
5413
5414
/**
5415
 * g_file_unmount_mountable_with_operation_finish:
5416
 * @file: input #GFile
5417
 * @result: a #GAsyncResult
5418
 * @error: a #GError, or %NULL
5419
 *
5420
 * Finishes an unmount operation,
5421
 * see g_file_unmount_mountable_with_operation() for details.
5422
 *
5423
 * Finish an asynchronous unmount operation that was started
5424
 * with g_file_unmount_mountable_with_operation().
5425
 *
5426
 * Returns: %TRUE if the operation finished successfully.
5427
 *   %FALSE otherwise.
5428
 *
5429
 * Since: 2.22
5430
 */
5431
gboolean
5432
g_file_unmount_mountable_with_operation_finish (GFile         *file,
5433
                                                GAsyncResult  *result,
5434
                                                GError       **error)
5435
0
{
5436
0
  GFileIface *iface;
5437
5438
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
5439
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
5440
5441
0
  if (g_async_result_legacy_propagate_error (result, error))
5442
0
    return FALSE;
5443
0
  else if (g_async_result_is_tagged (result, g_file_unmount_mountable_with_operation))
5444
0
    return g_task_propagate_boolean (G_TASK (result), error);
5445
5446
0
  iface = G_FILE_GET_IFACE (file);
5447
0
  if (iface->unmount_mountable_with_operation_finish != NULL)
5448
0
    return (* iface->unmount_mountable_with_operation_finish) (file, result, error);
5449
0
  else
5450
0
    return (* iface->unmount_mountable_finish) (file, result, error);
5451
0
}
5452
5453
/**
5454
 * g_file_eject_mountable:
5455
 * @file: input #GFile
5456
 * @flags: flags affecting the operation
5457
 * @cancellable: (nullable): optional #GCancellable object,
5458
 *   %NULL to ignore
5459
 * @callback: (scope async) (nullable): a #GAsyncReadyCallback to call
5460
 *   when the request is satisfied, or %NULL
5461
 * @user_data: (closure): the data to pass to callback function
5462
 *
5463
 * Starts an asynchronous eject on a mountable.
5464
 * When this operation has completed, @callback will be called with
5465
 * @user_user data, and the operation can be finalized with
5466
 * g_file_eject_mountable_finish().
5467
 *
5468
 * If @cancellable is not %NULL, then the operation can be cancelled by
5469
 * triggering the cancellable object from another thread. If the operation
5470
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5471
 *
5472
 * Deprecated: 2.22: Use g_file_eject_mountable_with_operation() instead.
5473
 */
5474
void
5475
g_file_eject_mountable (GFile               *file,
5476
                        GMountUnmountFlags   flags,
5477
                        GCancellable        *cancellable,
5478
                        GAsyncReadyCallback  callback,
5479
                        gpointer             user_data)
5480
0
{
5481
0
  GFileIface *iface;
5482
5483
0
  g_return_if_fail (G_IS_FILE (file));
5484
5485
0
  iface = G_FILE_GET_IFACE (file);
5486
5487
0
  if (iface->eject_mountable == NULL)
5488
0
    {
5489
0
      g_task_report_new_error (file, callback, user_data,
5490
0
                               g_file_eject_mountable_with_operation,
5491
0
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
5492
0
                               _("Operation not supported"));
5493
0
      return;
5494
0
    }
5495
5496
0
  (* iface->eject_mountable) (file,
5497
0
                              flags,
5498
0
                              cancellable,
5499
0
                              callback,
5500
0
                              user_data);
5501
0
}
5502
5503
/**
5504
 * g_file_eject_mountable_finish:
5505
 * @file: input #GFile
5506
 * @result: a #GAsyncResult
5507
 * @error: a #GError, or %NULL
5508
 *
5509
 * Finishes an asynchronous eject operation started by
5510
 * g_file_eject_mountable().
5511
 *
5512
 * Returns: %TRUE if the @file was ejected successfully.
5513
 *   %FALSE otherwise.
5514
 *
5515
 * Deprecated: 2.22: Use g_file_eject_mountable_with_operation_finish()
5516
 *   instead.
5517
 */
5518
gboolean
5519
g_file_eject_mountable_finish (GFile         *file,
5520
                               GAsyncResult  *result,
5521
                               GError       **error)
5522
0
{
5523
0
  GFileIface *iface;
5524
5525
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
5526
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
5527
5528
0
  if (g_async_result_legacy_propagate_error (result, error))
5529
0
    return FALSE;
5530
0
  else if (g_async_result_is_tagged (result, g_file_eject_mountable_with_operation))
5531
0
    return g_task_propagate_boolean (G_TASK (result), error);
5532
5533
0
  iface = G_FILE_GET_IFACE (file);
5534
0
  return (* iface->eject_mountable_finish) (file, result, error);
5535
0
}
5536
5537
/**
5538
 * g_file_eject_mountable_with_operation:
5539
 * @file: input #GFile
5540
 * @flags: flags affecting the operation
5541
 * @mount_operation: (nullable): a #GMountOperation,
5542
 *   or %NULL to avoid user interaction
5543
 * @cancellable: (nullable): optional #GCancellable object,
5544
 *   %NULL to ignore
5545
 * @callback: (scope async) (nullable): a #GAsyncReadyCallback to call
5546
 *   when the request is satisfied, or %NULL
5547
 * @user_data: (closure): the data to pass to callback function
5548
 *
5549
 * Starts an asynchronous eject on a mountable.
5550
 * When this operation has completed, @callback will be called with
5551
 * @user_user data, and the operation can be finalized with
5552
 * g_file_eject_mountable_with_operation_finish().
5553
 *
5554
 * If @cancellable is not %NULL, then the operation can be cancelled by
5555
 * triggering the cancellable object from another thread. If the operation
5556
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5557
 *
5558
 * Since: 2.22
5559
 */
5560
void
5561
g_file_eject_mountable_with_operation (GFile               *file,
5562
                                       GMountUnmountFlags   flags,
5563
                                       GMountOperation     *mount_operation,
5564
                                       GCancellable        *cancellable,
5565
                                       GAsyncReadyCallback  callback,
5566
                                       gpointer             user_data)
5567
0
{
5568
0
  GFileIface *iface;
5569
5570
0
  g_return_if_fail (G_IS_FILE (file));
5571
5572
0
  iface = G_FILE_GET_IFACE (file);
5573
5574
0
  if (iface->eject_mountable == NULL && iface->eject_mountable_with_operation == NULL)
5575
0
    {
5576
0
      g_task_report_new_error (file, callback, user_data,
5577
0
                               g_file_eject_mountable_with_operation,
5578
0
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
5579
0
                               _("Operation not supported"));
5580
0
      return;
5581
0
    }
5582
5583
0
  if (iface->eject_mountable_with_operation != NULL)
5584
0
    (* iface->eject_mountable_with_operation) (file,
5585
0
                                               flags,
5586
0
                                               mount_operation,
5587
0
                                               cancellable,
5588
0
                                               callback,
5589
0
                                               user_data);
5590
0
  else
5591
0
    (* iface->eject_mountable) (file,
5592
0
                                flags,
5593
0
                                cancellable,
5594
0
                                callback,
5595
0
                                user_data);
5596
0
}
5597
5598
/**
5599
 * g_file_eject_mountable_with_operation_finish:
5600
 * @file: input #GFile
5601
 * @result: a #GAsyncResult
5602
 * @error: a #GError, or %NULL
5603
 *
5604
 * Finishes an asynchronous eject operation started by
5605
 * g_file_eject_mountable_with_operation().
5606
 *
5607
 * Returns: %TRUE if the @file was ejected successfully.
5608
 *   %FALSE otherwise.
5609
 *
5610
 * Since: 2.22
5611
 */
5612
gboolean
5613
g_file_eject_mountable_with_operation_finish (GFile         *file,
5614
                                              GAsyncResult  *result,
5615
                                              GError       **error)
5616
0
{
5617
0
  GFileIface *iface;
5618
5619
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
5620
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
5621
5622
0
  if (g_async_result_legacy_propagate_error (result, error))
5623
0
    return FALSE;
5624
0
  else if (g_async_result_is_tagged (result, g_file_eject_mountable_with_operation))
5625
0
    return g_task_propagate_boolean (G_TASK (result), error);
5626
5627
0
  iface = G_FILE_GET_IFACE (file);
5628
0
  if (iface->eject_mountable_with_operation_finish != NULL)
5629
0
    return (* iface->eject_mountable_with_operation_finish) (file, result, error);
5630
0
  else
5631
0
    return (* iface->eject_mountable_finish) (file, result, error);
5632
0
}
5633
5634
/**
5635
 * g_file_monitor_directory:
5636
 * @file: input #GFile
5637
 * @flags: a set of #GFileMonitorFlags
5638
 * @cancellable: (nullable): optional #GCancellable object,
5639
 *   %NULL to ignore
5640
 * @error: a #GError, or %NULL
5641
 *
5642
 * Obtains a directory monitor for the given file.
5643
 * This may fail if directory monitoring is not supported.
5644
 *
5645
 * If @cancellable is not %NULL, then the operation can be cancelled by
5646
 * triggering the cancellable object from another thread. If the operation
5647
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5648
 *
5649
 * It does not make sense for @flags to contain
5650
 * %G_FILE_MONITOR_WATCH_HARD_LINKS, since hard links can not be made to
5651
 * directories.  It is not possible to monitor all the files in a
5652
 * directory for changes made via hard links; if you want to do this then
5653
 * you must register individual watches with g_file_monitor().
5654
 *
5655
 * Virtual: monitor_dir
5656
 * Returns: (transfer full): a #GFileMonitor for the given @file,
5657
 *   or %NULL on error.
5658
 *   Free the returned object with g_object_unref().
5659
 */
5660
GFileMonitor *
5661
g_file_monitor_directory (GFile              *file,
5662
                          GFileMonitorFlags   flags,
5663
                          GCancellable       *cancellable,
5664
                          GError            **error)
5665
0
{
5666
0
  GFileIface *iface;
5667
5668
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
5669
0
  g_return_val_if_fail (~flags & G_FILE_MONITOR_WATCH_HARD_LINKS, NULL);
5670
5671
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
5672
0
    return NULL;
5673
5674
0
  iface = G_FILE_GET_IFACE (file);
5675
5676
0
  if (iface->monitor_dir == NULL)
5677
0
    {
5678
0
      g_set_error_literal (error, G_IO_ERROR,
5679
0
                           G_IO_ERROR_NOT_SUPPORTED,
5680
0
                           _("Operation not supported"));
5681
0
      return NULL;
5682
0
    }
5683
5684
0
  return (* iface->monitor_dir) (file, flags, cancellable, error);
5685
0
}
5686
5687
/**
5688
 * g_file_monitor_file:
5689
 * @file: input #GFile
5690
 * @flags: a set of #GFileMonitorFlags
5691
 * @cancellable: (nullable): optional #GCancellable object,
5692
 *   %NULL to ignore
5693
 * @error: a #GError, or %NULL
5694
 *
5695
 * Obtains a file monitor for the given file. If no file notification
5696
 * mechanism exists, then regular polling of the file is used.
5697
 *
5698
 * If @cancellable is not %NULL, then the operation can be cancelled by
5699
 * triggering the cancellable object from another thread. If the operation
5700
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5701
 *
5702
 * If @flags contains %G_FILE_MONITOR_WATCH_HARD_LINKS then the monitor
5703
 * will also attempt to report changes made to the file via another
5704
 * filename (ie, a hard link). Without this flag, you can only rely on
5705
 * changes made through the filename contained in @file to be
5706
 * reported. Using this flag may result in an increase in resource
5707
 * usage, and may not have any effect depending on the #GFileMonitor
5708
 * backend and/or filesystem type.
5709
 * 
5710
 * Returns: (transfer full): a #GFileMonitor for the given @file,
5711
 *   or %NULL on error.
5712
 *   Free the returned object with g_object_unref().
5713
 */
5714
GFileMonitor *
5715
g_file_monitor_file (GFile              *file,
5716
                     GFileMonitorFlags   flags,
5717
                     GCancellable       *cancellable,
5718
                     GError            **error)
5719
0
{
5720
0
  GFileIface *iface;
5721
0
  GFileMonitor *monitor;
5722
5723
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
5724
5725
0
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
5726
0
    return NULL;
5727
5728
0
  iface = G_FILE_GET_IFACE (file);
5729
5730
0
  monitor = NULL;
5731
5732
0
  if (iface->monitor_file)
5733
0
    monitor = (* iface->monitor_file) (file, flags, cancellable, NULL);
5734
5735
  /* Fallback to polling */
5736
0
  if (monitor == NULL)
5737
0
    monitor = _g_poll_file_monitor_new (file);
5738
5739
0
  return monitor;
5740
0
}
5741
5742
/**
5743
 * g_file_monitor:
5744
 * @file: input #GFile
5745
 * @flags: a set of #GFileMonitorFlags
5746
 * @cancellable: (nullable): optional #GCancellable object,
5747
 *   %NULL to ignore
5748
 * @error: a #GError, or %NULL
5749
 *
5750
 * Obtains a file or directory monitor for the given file,
5751
 * depending on the type of the file.
5752
 *
5753
 * If @cancellable is not %NULL, then the operation can be cancelled by
5754
 * triggering the cancellable object from another thread. If the operation
5755
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5756
 *
5757
 * Returns: (transfer full): a #GFileMonitor for the given @file,
5758
 *   or %NULL on error.
5759
 *   Free the returned object with g_object_unref().
5760
 *
5761
 * Since: 2.18
5762
 */
5763
GFileMonitor *
5764
g_file_monitor (GFile              *file,
5765
                GFileMonitorFlags   flags,
5766
                GCancellable       *cancellable,
5767
                GError            **error)
5768
0
{
5769
0
  if (g_file_query_file_type (file, 0, cancellable) == G_FILE_TYPE_DIRECTORY)
5770
0
    return g_file_monitor_directory (file,
5771
0
                                     flags & ~G_FILE_MONITOR_WATCH_HARD_LINKS,
5772
0
                                     cancellable, error);
5773
0
  else
5774
0
    return g_file_monitor_file (file, flags, cancellable, error);
5775
0
}
5776
5777
/********************************************
5778
 *   Default implementation of async ops    *
5779
 ********************************************/
5780
5781
typedef struct {
5782
  char *attributes;
5783
  GFileQueryInfoFlags flags;
5784
} QueryInfoAsyncData;
5785
5786
static void
5787
query_info_data_free (QueryInfoAsyncData *data)
5788
0
{
5789
0
  g_free (data->attributes);
5790
0
  g_free (data);
5791
0
}
5792
5793
static void
5794
query_info_async_thread (GTask         *task,
5795
                         gpointer       object,
5796
                         gpointer       task_data,
5797
                         GCancellable  *cancellable)
5798
0
{
5799
0
  QueryInfoAsyncData *data = task_data;
5800
0
  GFileInfo *info;
5801
0
  GError *error = NULL;
5802
5803
0
  info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error);
5804
0
  if (info)
5805
0
    g_task_return_pointer (task, info, g_object_unref);
5806
0
  else
5807
0
    g_task_return_error (task, error);
5808
0
}
5809
5810
static void
5811
g_file_real_query_info_async (GFile               *file,
5812
                              const char          *attributes,
5813
                              GFileQueryInfoFlags  flags,
5814
                              int                  io_priority,
5815
                              GCancellable        *cancellable,
5816
                              GAsyncReadyCallback  callback,
5817
                              gpointer             user_data)
5818
0
{
5819
0
  GTask *task;
5820
0
  QueryInfoAsyncData *data;
5821
5822
0
  data = g_new0 (QueryInfoAsyncData, 1);
5823
0
  data->attributes = g_strdup (attributes);
5824
0
  data->flags = flags;
5825
5826
0
  task = g_task_new (file, cancellable, callback, user_data);
5827
0
  g_task_set_source_tag (task, g_file_real_query_info_async);
5828
0
  g_task_set_task_data (task, data, (GDestroyNotify)query_info_data_free);
5829
0
  g_task_set_priority (task, io_priority);
5830
0
  g_task_run_in_thread (task, query_info_async_thread);
5831
0
  g_object_unref (task);
5832
0
}
5833
5834
static GFileInfo *
5835
g_file_real_query_info_finish (GFile         *file,
5836
                               GAsyncResult  *res,
5837
                               GError       **error)
5838
0
{
5839
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5840
5841
0
  return g_task_propagate_pointer (G_TASK (res), error);
5842
0
}
5843
5844
static void
5845
query_filesystem_info_async_thread (GTask         *task,
5846
                                    gpointer       object,
5847
                                    gpointer       task_data,
5848
                                    GCancellable  *cancellable)
5849
0
{
5850
0
  const char *attributes = task_data;
5851
0
  GFileInfo *info;
5852
0
  GError *error = NULL;
5853
5854
0
  info = g_file_query_filesystem_info (G_FILE (object), attributes, cancellable, &error);
5855
0
  if (info)
5856
0
    g_task_return_pointer (task, info, g_object_unref);
5857
0
  else
5858
0
    g_task_return_error (task, error);
5859
0
}
5860
5861
static void
5862
g_file_real_query_filesystem_info_async (GFile               *file,
5863
                                         const char          *attributes,
5864
                                         int                  io_priority,
5865
                                         GCancellable        *cancellable,
5866
                                         GAsyncReadyCallback  callback,
5867
                                         gpointer             user_data)
5868
0
{
5869
0
  GTask *task;
5870
5871
0
  task = g_task_new (file, cancellable, callback, user_data);
5872
0
  g_task_set_source_tag (task, g_file_real_query_filesystem_info_async);
5873
0
  g_task_set_task_data (task, g_strdup (attributes), g_free);
5874
0
  g_task_set_priority (task, io_priority);
5875
0
  g_task_run_in_thread (task, query_filesystem_info_async_thread);
5876
0
  g_object_unref (task);
5877
0
}
5878
5879
static GFileInfo *
5880
g_file_real_query_filesystem_info_finish (GFile         *file,
5881
                                          GAsyncResult  *res,
5882
                                          GError       **error)
5883
0
{
5884
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5885
5886
0
  return g_task_propagate_pointer (G_TASK (res), error);
5887
0
}
5888
5889
static void
5890
enumerate_children_async_thread (GTask         *task,
5891
                                 gpointer       object,
5892
                                 gpointer       task_data,
5893
                                 GCancellable  *cancellable)
5894
0
{
5895
0
  QueryInfoAsyncData *data = task_data;
5896
0
  GFileEnumerator *enumerator;
5897
0
  GError *error = NULL;
5898
5899
0
  enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error);
5900
0
  if (error)
5901
0
    g_task_return_error (task, error);
5902
0
  else
5903
0
    g_task_return_pointer (task, enumerator, g_object_unref);
5904
0
}
5905
5906
static void
5907
g_file_real_enumerate_children_async (GFile               *file,
5908
                                      const char          *attributes,
5909
                                      GFileQueryInfoFlags  flags,
5910
                                      int                  io_priority,
5911
                                      GCancellable        *cancellable,
5912
                                      GAsyncReadyCallback  callback,
5913
                                      gpointer             user_data)
5914
0
{
5915
0
  GTask *task;
5916
0
  QueryInfoAsyncData *data;
5917
5918
0
  data = g_new0 (QueryInfoAsyncData, 1);
5919
0
  data->attributes = g_strdup (attributes);
5920
0
  data->flags = flags;
5921
5922
0
  task = g_task_new (file, cancellable, callback, user_data);
5923
0
  g_task_set_source_tag (task, g_file_real_enumerate_children_async);
5924
0
  g_task_set_task_data (task, data, (GDestroyNotify)query_info_data_free);
5925
0
  g_task_set_priority (task, io_priority);
5926
0
  g_task_run_in_thread (task, enumerate_children_async_thread);
5927
0
  g_object_unref (task);
5928
0
}
5929
5930
static GFileEnumerator *
5931
g_file_real_enumerate_children_finish (GFile         *file,
5932
                                       GAsyncResult  *res,
5933
                                       GError       **error)
5934
0
{
5935
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5936
5937
0
  return g_task_propagate_pointer (G_TASK (res), error);
5938
0
}
5939
5940
static void
5941
open_read_async_thread (GTask         *task,
5942
                        gpointer       object,
5943
                        gpointer       task_data,
5944
                        GCancellable  *cancellable)
5945
0
{
5946
0
  GFileInputStream *stream;
5947
0
  GError *error = NULL;
5948
5949
0
  stream = g_file_read (G_FILE (object), cancellable, &error);
5950
0
  if (stream)
5951
0
    g_task_return_pointer (task, stream, g_object_unref);
5952
0
  else
5953
0
    g_task_return_error (task, error);
5954
0
}
5955
5956
static void
5957
g_file_real_read_async (GFile               *file,
5958
                        int                  io_priority,
5959
                        GCancellable        *cancellable,
5960
                        GAsyncReadyCallback  callback,
5961
                        gpointer             user_data)
5962
0
{
5963
0
  GTask *task;
5964
5965
0
  task = g_task_new (file, cancellable, callback, user_data);
5966
0
  g_task_set_source_tag (task, g_file_real_read_async);
5967
0
  g_task_set_priority (task, io_priority);
5968
0
  g_task_run_in_thread (task, open_read_async_thread);
5969
0
  g_object_unref (task);
5970
0
}
5971
5972
static GFileInputStream *
5973
g_file_real_read_finish (GFile         *file,
5974
                         GAsyncResult  *res,
5975
                         GError       **error)
5976
0
{
5977
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5978
5979
0
  return g_task_propagate_pointer (G_TASK (res), error);
5980
0
}
5981
5982
static void
5983
append_to_async_thread (GTask         *task,
5984
                        gpointer       source_object,
5985
                        gpointer       task_data,
5986
                        GCancellable  *cancellable)
5987
0
{
5988
0
  GFileCreateFlags *data = task_data;
5989
0
  GFileOutputStream *stream;
5990
0
  GError *error = NULL;
5991
5992
0
  stream = g_file_append_to (G_FILE (source_object), *data, cancellable, &error);
5993
0
  if (stream)
5994
0
    g_task_return_pointer (task, stream, g_object_unref);
5995
0
  else
5996
0
    g_task_return_error (task, error);
5997
0
}
5998
5999
static void
6000
g_file_real_append_to_async (GFile               *file,
6001
                             GFileCreateFlags     flags,
6002
                             int                  io_priority,
6003
                             GCancellable        *cancellable,
6004
                             GAsyncReadyCallback  callback,
6005
                             gpointer             user_data)
6006
0
{
6007
0
  GFileCreateFlags *data;
6008
0
  GTask *task;
6009
6010
0
  data = g_new0 (GFileCreateFlags, 1);
6011
0
  *data = flags;
6012
6013
0
  task = g_task_new (file, cancellable, callback, user_data);
6014
0
  g_task_set_source_tag (task, g_file_real_append_to_async);
6015
0
  g_task_set_task_data (task, data, g_free);
6016
0
  g_task_set_priority (task, io_priority);
6017
6018
0
  g_task_run_in_thread (task, append_to_async_thread);
6019
0
  g_object_unref (task);
6020
0
}
6021
6022
static GFileOutputStream *
6023
g_file_real_append_to_finish (GFile         *file,
6024
                              GAsyncResult  *res,
6025
                              GError       **error)
6026
0
{
6027
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
6028
6029
0
  return g_task_propagate_pointer (G_TASK (res), error);
6030
0
}
6031
6032
static void
6033
create_async_thread (GTask         *task,
6034
                     gpointer       source_object,
6035
                     gpointer       task_data,
6036
                     GCancellable  *cancellable)
6037
0
{
6038
0
  GFileCreateFlags *data = task_data;
6039
0
  GFileOutputStream *stream;
6040
0
  GError *error = NULL;
6041
6042
0
  stream = g_file_create (G_FILE (source_object), *data, cancellable, &error);
6043
0
  if (stream)
6044
0
    g_task_return_pointer (task, stream, g_object_unref);
6045
0
  else
6046
0
    g_task_return_error (task, error);
6047
0
}
6048
6049
static void
6050
g_file_real_create_async (GFile               *file,
6051
                          GFileCreateFlags     flags,
6052
                          int                  io_priority,
6053
                          GCancellable        *cancellable,
6054
                          GAsyncReadyCallback  callback,
6055
                          gpointer             user_data)
6056
0
{
6057
0
  GFileCreateFlags *data;
6058
0
  GTask *task;
6059
6060
0
  data = g_new0 (GFileCreateFlags, 1);
6061
0
  *data = flags;
6062
6063
0
  task = g_task_new (file, cancellable, callback, user_data);
6064
0
  g_task_set_source_tag (task, g_file_real_create_async);
6065
0
  g_task_set_task_data (task, data, g_free);
6066
0
  g_task_set_priority (task, io_priority);
6067
6068
0
  g_task_run_in_thread (task, create_async_thread);
6069
0
  g_object_unref (task);
6070
0
}
6071
6072
static GFileOutputStream *
6073
g_file_real_create_finish (GFile         *file,
6074
                           GAsyncResult  *res,
6075
                           GError       **error)
6076
0
{
6077
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
6078
6079
0
  return g_task_propagate_pointer (G_TASK (res), error);
6080
0
}
6081
6082
typedef struct {
6083
  GFileOutputStream *stream;
6084
  char *etag;
6085
  gboolean make_backup;
6086
  GFileCreateFlags flags;
6087
} ReplaceAsyncData;
6088
6089
static void
6090
replace_async_data_free (ReplaceAsyncData *data)
6091
0
{
6092
0
  if (data->stream)
6093
0
    g_object_unref (data->stream);
6094
0
  g_free (data->etag);
6095
0
  g_free (data);
6096
0
}
6097
6098
static void
6099
replace_async_thread (GTask         *task,
6100
                      gpointer       source_object,
6101
                      gpointer       task_data,
6102
                      GCancellable  *cancellable)
6103
0
{
6104
0
  GFileOutputStream *stream;
6105
0
  ReplaceAsyncData *data = task_data;
6106
0
  GError *error = NULL;
6107
6108
0
  stream = g_file_replace (G_FILE (source_object),
6109
0
                           data->etag,
6110
0
                           data->make_backup,
6111
0
                           data->flags,
6112
0
                           cancellable,
6113
0
                           &error);
6114
6115
0
  if (stream)
6116
0
    g_task_return_pointer (task, stream, g_object_unref);
6117
0
  else
6118
0
    g_task_return_error (task, error);
6119
0
}
6120
6121
static void
6122
g_file_real_replace_async (GFile               *file,
6123
                           const char          *etag,
6124
                           gboolean             make_backup,
6125
                           GFileCreateFlags     flags,
6126
                           int                  io_priority,
6127
                           GCancellable        *cancellable,
6128
                           GAsyncReadyCallback  callback,
6129
                           gpointer             user_data)
6130
0
{
6131
0
  GTask *task;
6132
0
  ReplaceAsyncData *data;
6133
6134
0
  data = g_new0 (ReplaceAsyncData, 1);
6135
0
  data->etag = g_strdup (etag);
6136
0
  data->make_backup = make_backup;
6137
0
  data->flags = flags;
6138
6139
0
  task = g_task_new (file, cancellable, callback, user_data);
6140
0
  g_task_set_source_tag (task, g_file_real_replace_async);
6141
0
  g_task_set_task_data (task, data, (GDestroyNotify)replace_async_data_free);
6142
0
  g_task_set_priority (task, io_priority);
6143
6144
0
  g_task_run_in_thread (task, replace_async_thread);
6145
0
  g_object_unref (task);
6146
0
}
6147
6148
static GFileOutputStream *
6149
g_file_real_replace_finish (GFile         *file,
6150
                            GAsyncResult  *res,
6151
                            GError       **error)
6152
0
{
6153
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
6154
6155
0
  return g_task_propagate_pointer (G_TASK (res), error);
6156
0
}
6157
6158
static void
6159
delete_async_thread (GTask        *task,
6160
                     gpointer      object,
6161
                     gpointer      task_data,
6162
                     GCancellable *cancellable)
6163
0
{
6164
0
  GError *error = NULL;
6165
6166
0
  if (g_file_delete (G_FILE (object), cancellable, &error))
6167
0
    g_task_return_boolean (task, TRUE);
6168
0
  else
6169
0
    g_task_return_error (task, error);
6170
0
}
6171
6172
static void
6173
g_file_real_delete_async (GFile               *file,
6174
                          int                  io_priority,
6175
                          GCancellable        *cancellable,
6176
                          GAsyncReadyCallback  callback,
6177
                          gpointer             user_data)
6178
0
{
6179
0
  GTask *task;
6180
6181
0
  task = g_task_new (file, cancellable, callback, user_data);
6182
0
  g_task_set_source_tag (task, g_file_real_delete_async);
6183
0
  g_task_set_priority (task, io_priority);
6184
0
  g_task_run_in_thread (task, delete_async_thread);
6185
0
  g_object_unref (task);
6186
0
}
6187
6188
static gboolean
6189
g_file_real_delete_finish (GFile         *file,
6190
                           GAsyncResult  *res,
6191
                           GError       **error)
6192
0
{
6193
0
  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
6194
6195
0
  return g_task_propagate_boolean (G_TASK (res), error);
6196
0
}
6197
6198
static void
6199
trash_async_thread (GTask        *task,
6200
                    gpointer      object,
6201
                    gpointer      task_data,
6202
                    GCancellable *cancellable)
6203
0
{
6204
0
  GError *error = NULL;
6205
6206
0
  if (g_file_trash (G_FILE (object), cancellable, &error))
6207
0
    g_task_return_boolean (task, TRUE);
6208
0
  else
6209
0
    g_task_return_error (task, error);
6210
0
}
6211
6212
static void
6213
g_file_real_trash_async (GFile               *file,
6214
                         int                  io_priority,
6215
                         GCancellable        *cancellable,
6216
                         GAsyncReadyCallback  callback,
6217
                         gpointer             user_data)
6218
0
{
6219
0
  GTask *task;
6220
6221
0
  task = g_task_new (file, cancellable, callback, user_data);
6222
0
  g_task_set_source_tag (task, g_file_real_trash_async);
6223
0
  g_task_set_priority (task, io_priority);
6224
0
  g_task_run_in_thread (task, trash_async_thread);
6225
0
  g_object_unref (task);
6226
0
}
6227
6228
static gboolean
6229
g_file_real_trash_finish (GFile         *file,
6230
                          GAsyncResult  *res,
6231
                          GError       **error)
6232
0
{
6233
0
  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
6234
6235
0
  return g_task_propagate_boolean (G_TASK (res), error);
6236
0
}
6237
6238
6239
typedef struct {
6240
  GFile *source;  /* (owned) */
6241
  GFile *destination;  /* (owned) */
6242
  GFileCopyFlags flags;
6243
  GFileProgressCallback progress_cb;
6244
  gpointer progress_cb_data;
6245
} MoveAsyncData;
6246
6247
static void
6248
move_async_data_free (MoveAsyncData *data)
6249
0
{
6250
0
  g_object_unref (data->source);
6251
0
  g_object_unref (data->destination);
6252
0
  g_slice_free (MoveAsyncData, data);
6253
0
}
6254
6255
typedef struct {
6256
  MoveAsyncData *data;  /* (unowned) */
6257
  goffset current_num_bytes;
6258
  goffset total_num_bytes;
6259
} MoveProgressData;
6260
6261
static gboolean
6262
move_async_progress_in_main (gpointer user_data)
6263
0
{
6264
0
  MoveProgressData *progress = user_data;
6265
0
  MoveAsyncData *data = progress->data;
6266
6267
0
  data->progress_cb (progress->current_num_bytes,
6268
0
                     progress->total_num_bytes,
6269
0
                     data->progress_cb_data);
6270
6271
0
  return G_SOURCE_REMOVE;
6272
0
}
6273
6274
static void
6275
move_async_progress_callback (goffset  current_num_bytes,
6276
                              goffset  total_num_bytes,
6277
                              gpointer user_data)
6278
0
{
6279
0
  GTask *task = user_data;
6280
0
  MoveAsyncData *data = g_task_get_task_data (task);
6281
0
  MoveProgressData *progress;
6282
6283
0
  progress = g_new0 (MoveProgressData, 1);
6284
0
  progress->data = data;
6285
0
  progress->current_num_bytes = current_num_bytes;
6286
0
  progress->total_num_bytes = total_num_bytes;
6287
6288
0
  g_main_context_invoke_full (g_task_get_context (task),
6289
0
                              g_task_get_priority (task),
6290
0
                              move_async_progress_in_main,
6291
0
                              g_steal_pointer (&progress),
6292
0
                              g_free);
6293
0
}
6294
6295
static void
6296
move_async_thread (GTask        *task,
6297
                   gpointer      source,
6298
                   gpointer      task_data,
6299
                   GCancellable *cancellable)
6300
0
{
6301
0
  MoveAsyncData *data = task_data;
6302
0
  gboolean result;
6303
0
  GError *error = NULL;
6304
6305
0
  result = g_file_move (data->source,
6306
0
                        data->destination,
6307
0
                        data->flags,
6308
0
                        cancellable,
6309
0
                        (data->progress_cb != NULL) ? move_async_progress_callback : NULL,
6310
0
                        task,
6311
0
                        &error);
6312
0
  if (result)
6313
0
    g_task_return_boolean (task, TRUE);
6314
0
  else
6315
0
    g_task_return_error (task, g_steal_pointer (&error));
6316
0
}
6317
6318
static void
6319
g_file_real_move_async (GFile                  *source,
6320
                        GFile                  *destination,
6321
                        GFileCopyFlags          flags,
6322
                        int                     io_priority,
6323
                        GCancellable           *cancellable,
6324
                        GFileProgressCallback   progress_callback,
6325
                        gpointer                progress_callback_data,
6326
                        GAsyncReadyCallback     callback,
6327
                        gpointer                user_data)
6328
0
{
6329
0
  GTask *task;
6330
0
  MoveAsyncData *data;
6331
6332
0
  data = g_slice_new0 (MoveAsyncData);
6333
0
  data->source = g_object_ref (source);
6334
0
  data->destination = g_object_ref (destination);
6335
0
  data->flags = flags;
6336
0
  data->progress_cb = progress_callback;
6337
0
  data->progress_cb_data = progress_callback_data;
6338
6339
0
  task = g_task_new (source, cancellable, callback, user_data);
6340
0
  g_task_set_source_tag (task, g_file_real_move_async);
6341
0
  g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) move_async_data_free);
6342
0
  g_task_set_priority (task, io_priority);
6343
0
  g_task_run_in_thread (task, move_async_thread);
6344
0
  g_object_unref (task);
6345
0
}
6346
6347
static gboolean
6348
g_file_real_move_finish (GFile        *file,
6349
                         GAsyncResult *result,
6350
                         GError      **error)
6351
0
{
6352
0
  g_return_val_if_fail (g_task_is_valid (result, file), FALSE);
6353
6354
0
  return g_task_propagate_boolean (G_TASK (result), error);
6355
0
}
6356
6357
static void
6358
make_directory_async_thread (GTask        *task,
6359
                             gpointer      object,
6360
                             gpointer      task_data,
6361
                             GCancellable *cancellable)
6362
0
{
6363
0
  GError *error = NULL;
6364
6365
0
  if (g_file_make_directory (G_FILE (object), cancellable, &error))
6366
0
    g_task_return_boolean (task, TRUE);
6367
0
  else
6368
0
    g_task_return_error (task, error);
6369
0
}
6370
6371
static void
6372
g_file_real_make_directory_async (GFile               *file,
6373
                                  int                  io_priority,
6374
                                  GCancellable        *cancellable,
6375
                                  GAsyncReadyCallback  callback,
6376
                                  gpointer             user_data)
6377
0
{
6378
0
  GTask *task;
6379
6380
0
  task = g_task_new (file, cancellable, callback, user_data);
6381
0
  g_task_set_source_tag (task, g_file_real_make_directory_async);
6382
0
  g_task_set_priority (task, io_priority);
6383
0
  g_task_run_in_thread (task, make_directory_async_thread);
6384
0
  g_object_unref (task);
6385
0
}
6386
6387
static gboolean
6388
g_file_real_make_directory_finish (GFile         *file,
6389
                                   GAsyncResult  *res,
6390
                                   GError       **error)
6391
0
{
6392
0
  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
6393
6394
0
  return g_task_propagate_boolean (G_TASK (res), error);
6395
0
}
6396
6397
static void
6398
open_readwrite_async_thread (GTask        *task,
6399
                             gpointer      object,
6400
                             gpointer      task_data,
6401
                             GCancellable *cancellable)
6402
0
{
6403
0
  GFileIOStream *stream;
6404
0
  GError *error = NULL;
6405
6406
0
  stream = g_file_open_readwrite (G_FILE (object), cancellable, &error);
6407
6408
0
  if (stream == NULL)
6409
0
    g_task_return_error (task, error);
6410
0
  else
6411
0
    g_task_return_pointer (task, stream, g_object_unref);
6412
0
}
6413
6414
static void
6415
g_file_real_open_readwrite_async (GFile               *file,
6416
                                  int                  io_priority,
6417
                                  GCancellable        *cancellable,
6418
                                  GAsyncReadyCallback  callback,
6419
                                  gpointer             user_data)
6420
0
{
6421
0
  GTask *task;
6422
6423
0
  task = g_task_new (file, cancellable, callback, user_data);
6424
0
  g_task_set_source_tag (task, g_file_real_open_readwrite_async);
6425
0
  g_task_set_priority (task, io_priority);
6426
6427
0
  g_task_run_in_thread (task, open_readwrite_async_thread);
6428
0
  g_object_unref (task);
6429
0
}
6430
6431
static GFileIOStream *
6432
g_file_real_open_readwrite_finish (GFile         *file,
6433
                                   GAsyncResult  *res,
6434
                                   GError       **error)
6435
0
{
6436
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
6437
6438
0
  return g_task_propagate_pointer (G_TASK (res), error);
6439
0
}
6440
6441
static void
6442
create_readwrite_async_thread (GTask        *task,
6443
                               gpointer      object,
6444
                               gpointer      task_data,
6445
                               GCancellable *cancellable)
6446
0
{
6447
0
  GFileCreateFlags *data = task_data;
6448
0
  GFileIOStream *stream;
6449
0
  GError *error = NULL;
6450
6451
0
  stream = g_file_create_readwrite (G_FILE (object), *data, cancellable, &error);
6452
6453
0
  if (stream == NULL)
6454
0
    g_task_return_error (task, error);
6455
0
  else
6456
0
    g_task_return_pointer (task, stream, g_object_unref);
6457
0
}
6458
6459
static void
6460
g_file_real_create_readwrite_async (GFile               *file,
6461
                                    GFileCreateFlags     flags,
6462
                                    int                  io_priority,
6463
                                    GCancellable        *cancellable,
6464
                                    GAsyncReadyCallback  callback,
6465
                                    gpointer             user_data)
6466
0
{
6467
0
  GFileCreateFlags *data;
6468
0
  GTask *task;
6469
6470
0
  data = g_new0 (GFileCreateFlags, 1);
6471
0
  *data = flags;
6472
6473
0
  task = g_task_new (file, cancellable, callback, user_data);
6474
0
  g_task_set_source_tag (task, g_file_real_create_readwrite_async);
6475
0
  g_task_set_task_data (task, data, g_free);
6476
0
  g_task_set_priority (task, io_priority);
6477
6478
0
  g_task_run_in_thread (task, create_readwrite_async_thread);
6479
0
  g_object_unref (task);
6480
0
}
6481
6482
static GFileIOStream *
6483
g_file_real_create_readwrite_finish (GFile         *file,
6484
                                     GAsyncResult  *res,
6485
                                     GError       **error)
6486
0
{
6487
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
6488
6489
0
  return g_task_propagate_pointer (G_TASK (res), error);
6490
0
}
6491
6492
typedef struct {
6493
  char *etag;
6494
  gboolean make_backup;
6495
  GFileCreateFlags flags;
6496
} ReplaceRWAsyncData;
6497
6498
static void
6499
replace_rw_async_data_free (ReplaceRWAsyncData *data)
6500
0
{
6501
0
  g_free (data->etag);
6502
0
  g_free (data);
6503
0
}
6504
6505
static void
6506
replace_readwrite_async_thread (GTask        *task,
6507
                                gpointer      object,
6508
                                gpointer      task_data,
6509
                                GCancellable *cancellable)
6510
0
{
6511
0
  GFileIOStream *stream;
6512
0
  GError *error = NULL;
6513
0
  ReplaceRWAsyncData *data = task_data;
6514
6515
0
  stream = g_file_replace_readwrite (G_FILE (object),
6516
0
                                     data->etag,
6517
0
                                     data->make_backup,
6518
0
                                     data->flags,
6519
0
                                     cancellable,
6520
0
                                     &error);
6521
6522
0
  if (stream == NULL)
6523
0
    g_task_return_error (task, error);
6524
0
  else
6525
0
    g_task_return_pointer (task, stream, g_object_unref);
6526
0
}
6527
6528
static void
6529
g_file_real_replace_readwrite_async (GFile               *file,
6530
                                     const char          *etag,
6531
                                     gboolean             make_backup,
6532
                                     GFileCreateFlags     flags,
6533
                                     int                  io_priority,
6534
                                     GCancellable        *cancellable,
6535
                                     GAsyncReadyCallback  callback,
6536
                                     gpointer             user_data)
6537
0
{
6538
0
  GTask *task;
6539
0
  ReplaceRWAsyncData *data;
6540
6541
0
  data = g_new0 (ReplaceRWAsyncData, 1);
6542
0
  data->etag = g_strdup (etag);
6543
0
  data->make_backup = make_backup;
6544
0
  data->flags = flags;
6545
6546
0
  task = g_task_new (file, cancellable, callback, user_data);
6547
0
  g_task_set_source_tag (task, g_file_real_replace_readwrite_async);
6548
0
  g_task_set_task_data (task, data, (GDestroyNotify)replace_rw_async_data_free);
6549
0
  g_task_set_priority (task, io_priority);
6550
6551
0
  g_task_run_in_thread (task, replace_readwrite_async_thread);
6552
0
  g_object_unref (task);
6553
0
}
6554
6555
static GFileIOStream *
6556
g_file_real_replace_readwrite_finish (GFile         *file,
6557
                                      GAsyncResult  *res,
6558
                                      GError       **error)
6559
0
{
6560
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
6561
6562
0
  return g_task_propagate_pointer (G_TASK (res), error);
6563
0
}
6564
6565
static void
6566
set_display_name_async_thread (GTask        *task,
6567
                               gpointer      object,
6568
                               gpointer      task_data,
6569
                               GCancellable *cancellable)
6570
0
{
6571
0
  GError *error = NULL;
6572
0
  char *name = task_data;
6573
0
  GFile *file;
6574
6575
0
  file = g_file_set_display_name (G_FILE (object), name, cancellable, &error);
6576
6577
0
  if (file == NULL)
6578
0
    g_task_return_error (task, error);
6579
0
  else
6580
0
    g_task_return_pointer (task, file, g_object_unref);
6581
0
}
6582
6583
static void
6584
g_file_real_set_display_name_async (GFile               *file,
6585
                                    const char          *display_name,
6586
                                    int                  io_priority,
6587
                                    GCancellable        *cancellable,
6588
                                    GAsyncReadyCallback  callback,
6589
                                    gpointer             user_data)
6590
0
{
6591
0
  GTask *task;
6592
6593
0
  task = g_task_new (file, cancellable, callback, user_data);
6594
0
  g_task_set_source_tag (task, g_file_real_set_display_name_async);
6595
0
  g_task_set_task_data (task, g_strdup (display_name), g_free);
6596
0
  g_task_set_priority (task, io_priority);
6597
6598
0
  g_task_run_in_thread (task, set_display_name_async_thread);
6599
0
  g_object_unref (task);
6600
0
}
6601
6602
static GFile *
6603
g_file_real_set_display_name_finish (GFile         *file,
6604
                                     GAsyncResult  *res,
6605
                                     GError       **error)
6606
0
{
6607
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
6608
6609
0
  return g_task_propagate_pointer (G_TASK (res), error);
6610
0
}
6611
6612
typedef struct {
6613
  GFileQueryInfoFlags flags;
6614
  GFileInfo *info;
6615
  gboolean res;
6616
  GError *error;
6617
} SetInfoAsyncData;
6618
6619
static void
6620
set_info_data_free (SetInfoAsyncData *data)
6621
0
{
6622
0
  if (data->info)
6623
0
    g_object_unref (data->info);
6624
0
  if (data->error)
6625
0
    g_error_free (data->error);
6626
0
  g_free (data);
6627
0
}
6628
6629
static void
6630
set_info_async_thread (GTask        *task,
6631
                       gpointer      object,
6632
                       gpointer      task_data,
6633
                       GCancellable *cancellable)
6634
0
{
6635
0
  SetInfoAsyncData *data = task_data;
6636
6637
0
  data->error = NULL;
6638
0
  data->res = g_file_set_attributes_from_info (G_FILE (object),
6639
0
                                               data->info,
6640
0
                                               data->flags,
6641
0
                                               cancellable,
6642
0
                                               &data->error);
6643
0
}
6644
6645
static void
6646
g_file_real_set_attributes_async (GFile               *file,
6647
                                  GFileInfo           *info,
6648
                                  GFileQueryInfoFlags  flags,
6649
                                  int                  io_priority,
6650
                                  GCancellable        *cancellable,
6651
                                  GAsyncReadyCallback  callback,
6652
                                  gpointer             user_data)
6653
0
{
6654
0
  GTask *task;
6655
0
  SetInfoAsyncData *data;
6656
6657
0
  data = g_new0 (SetInfoAsyncData, 1);
6658
0
  data->info = g_file_info_dup (info);
6659
0
  data->flags = flags;
6660
6661
0
  task = g_task_new (file, cancellable, callback, user_data);
6662
0
  g_task_set_source_tag (task, g_file_real_set_attributes_async);
6663
0
  g_task_set_task_data (task, data, (GDestroyNotify)set_info_data_free);
6664
0
  g_task_set_priority (task, io_priority);
6665
6666
0
  g_task_run_in_thread (task, set_info_async_thread);
6667
0
  g_object_unref (task);
6668
0
}
6669
6670
static gboolean
6671
g_file_real_set_attributes_finish (GFile         *file,
6672
                                   GAsyncResult  *res,
6673
                                   GFileInfo    **info,
6674
                                   GError       **error)
6675
0
{
6676
0
  SetInfoAsyncData *data;
6677
6678
0
  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
6679
6680
0
  data = g_task_get_task_data (G_TASK (res));
6681
6682
0
  if (info)
6683
0
    *info = g_object_ref (data->info);
6684
6685
0
  if (error != NULL && data->error)
6686
0
    *error = g_error_copy (data->error);
6687
6688
0
  return data->res;
6689
0
}
6690
6691
static void
6692
find_enclosing_mount_async_thread (GTask        *task,
6693
                                   gpointer      object,
6694
                                   gpointer      task_data,
6695
                                   GCancellable *cancellable)
6696
0
{
6697
0
  GError *error = NULL;
6698
0
  GMount *mount;
6699
6700
0
  mount = g_file_find_enclosing_mount (G_FILE (object), cancellable, &error);
6701
6702
0
  if (mount == NULL)
6703
0
    g_task_return_error (task, error);
6704
0
  else
6705
0
    g_task_return_pointer (task, mount, g_object_unref);
6706
0
}
6707
6708
static void
6709
g_file_real_find_enclosing_mount_async (GFile               *file,
6710
                                        int                  io_priority,
6711
                                        GCancellable        *cancellable,
6712
                                        GAsyncReadyCallback  callback,
6713
                                        gpointer             user_data)
6714
0
{
6715
0
  GTask *task;
6716
6717
0
  task = g_task_new (file, cancellable, callback, user_data);
6718
0
  g_task_set_source_tag (task, g_file_real_find_enclosing_mount_async);
6719
0
  g_task_set_priority (task, io_priority);
6720
6721
0
  g_task_run_in_thread (task, find_enclosing_mount_async_thread);
6722
0
  g_object_unref (task);
6723
0
}
6724
6725
static GMount *
6726
g_file_real_find_enclosing_mount_finish (GFile         *file,
6727
                                         GAsyncResult  *res,
6728
                                         GError       **error)
6729
0
{
6730
0
  g_return_val_if_fail (g_task_is_valid (res, file), NULL);
6731
6732
0
  return g_task_propagate_pointer (G_TASK (res), error);
6733
0
}
6734
6735
6736
typedef struct {
6737
  GFile *source;
6738
  GFile *destination;
6739
  GFileCopyFlags flags;
6740
  GFileProgressCallback progress_cb;
6741
  gpointer progress_cb_data;
6742
} CopyAsyncData;
6743
6744
static void
6745
copy_async_data_free (CopyAsyncData *data)
6746
0
{
6747
0
  g_object_unref (data->source);
6748
0
  g_object_unref (data->destination);
6749
0
  g_slice_free (CopyAsyncData, data);
6750
0
}
6751
6752
typedef struct {
6753
  CopyAsyncData *data;
6754
  goffset current_num_bytes;
6755
  goffset total_num_bytes;
6756
} CopyProgressData;
6757
6758
static gboolean
6759
copy_async_progress_in_main (gpointer user_data)
6760
0
{
6761
0
  CopyProgressData *progress = user_data;
6762
0
  CopyAsyncData *data = progress->data;
6763
6764
0
  data->progress_cb (progress->current_num_bytes,
6765
0
                     progress->total_num_bytes,
6766
0
                     data->progress_cb_data);
6767
6768
0
  return FALSE;
6769
0
}
6770
6771
static void
6772
copy_async_progress_callback (goffset  current_num_bytes,
6773
                              goffset  total_num_bytes,
6774
                              gpointer user_data)
6775
0
{
6776
0
  GTask *task = user_data;
6777
0
  CopyAsyncData *data = g_task_get_task_data (task);
6778
0
  CopyProgressData *progress;
6779
6780
0
  progress = g_new (CopyProgressData, 1);
6781
0
  progress->data = data;
6782
0
  progress->current_num_bytes = current_num_bytes;
6783
0
  progress->total_num_bytes = total_num_bytes;
6784
6785
0
  g_main_context_invoke_full (g_task_get_context (task),
6786
0
                              g_task_get_priority (task),
6787
0
                              copy_async_progress_in_main,
6788
0
                              progress,
6789
0
                              g_free);
6790
0
}
6791
6792
static void
6793
copy_async_thread (GTask        *task,
6794
                   gpointer      source,
6795
                   gpointer      task_data,
6796
                   GCancellable *cancellable)
6797
0
{
6798
0
  CopyAsyncData *data = task_data;
6799
0
  gboolean result;
6800
0
  GError *error = NULL;
6801
6802
0
  result = g_file_copy (data->source,
6803
0
                        data->destination,
6804
0
                        data->flags,
6805
0
                        cancellable,
6806
0
                        (data->progress_cb != NULL) ? copy_async_progress_callback : NULL,
6807
0
                        task,
6808
0
                        &error);
6809
0
  if (result)
6810
0
    g_task_return_boolean (task, TRUE);
6811
0
  else
6812
0
    g_task_return_error (task, error);
6813
0
}
6814
6815
static void
6816
g_file_real_copy_async (GFile                  *source,
6817
                        GFile                  *destination,
6818
                        GFileCopyFlags          flags,
6819
                        int                     io_priority,
6820
                        GCancellable           *cancellable,
6821
                        GFileProgressCallback   progress_callback,
6822
                        gpointer                progress_callback_data,
6823
                        GAsyncReadyCallback     callback,
6824
                        gpointer                user_data)
6825
0
{
6826
0
  GTask *task;
6827
0
  CopyAsyncData *data;
6828
6829
0
  data = g_slice_new (CopyAsyncData);
6830
0
  data->source = g_object_ref (source);
6831
0
  data->destination = g_object_ref (destination);
6832
0
  data->flags = flags;
6833
0
  data->progress_cb = progress_callback;
6834
0
  data->progress_cb_data = progress_callback_data;
6835
6836
0
  task = g_task_new (source, cancellable, callback, user_data);
6837
0
  g_task_set_source_tag (task, g_file_real_copy_async);
6838
0
  g_task_set_task_data (task, data, (GDestroyNotify)copy_async_data_free);
6839
0
  g_task_set_priority (task, io_priority);
6840
0
  g_task_run_in_thread (task, copy_async_thread);
6841
0
  g_object_unref (task);
6842
0
}
6843
6844
static gboolean
6845
g_file_real_copy_finish (GFile        *file,
6846
                         GAsyncResult *res,
6847
                         GError      **error)
6848
0
{
6849
0
  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
6850
6851
0
  return g_task_propagate_boolean (G_TASK (res), error);
6852
0
}
6853
6854
6855
/********************************************
6856
 *   Default VFS operations                 *
6857
 ********************************************/
6858
6859
/**
6860
 * g_file_new_for_path:
6861
 * @path: (type filename): a string containing a relative or absolute path.
6862
 *   The string must be encoded in the glib filename encoding.
6863
 *
6864
 * Constructs a #GFile for a given path. This operation never
6865
 * fails, but the returned object might not support any I/O
6866
 * operation if @path is malformed.
6867
 *
6868
 * Returns: (transfer full): a new #GFile for the given @path.
6869
 *   Free the returned object with g_object_unref().
6870
 */
6871
GFile *
6872
g_file_new_for_path (const char *path)
6873
0
{
6874
0
  g_return_val_if_fail (path != NULL, NULL);
6875
6876
0
  return g_vfs_get_file_for_path (g_vfs_get_default (), path);
6877
0
}
6878
6879
/**
6880
 * g_file_new_for_uri:
6881
 * @uri: a UTF-8 string containing a URI
6882
 *
6883
 * Constructs a #GFile for a given URI. This operation never
6884
 * fails, but the returned object might not support any I/O
6885
 * operation if @uri is malformed or if the uri type is
6886
 * not supported.
6887
 *
6888
 * Returns: (transfer full): a new #GFile for the given @uri.
6889
 *   Free the returned object with g_object_unref().
6890
 */
6891
GFile *
6892
g_file_new_for_uri (const char *uri)
6893
0
{
6894
0
  g_return_val_if_fail (uri != NULL, NULL);
6895
6896
0
  return g_vfs_get_file_for_uri (g_vfs_get_default (), uri);
6897
0
}
6898
6899
/**
6900
 * g_file_new_tmp:
6901
 * @tmpl: (type filename) (nullable): Template for the file
6902
 *   name, as in g_file_open_tmp(), or %NULL for a default template
6903
 * @iostream: (out): on return, a #GFileIOStream for the created file
6904
 * @error: a #GError, or %NULL
6905
 *
6906
 * Opens a file in the preferred directory for temporary files (as
6907
 * returned by g_get_tmp_dir()) and returns a #GFile and
6908
 * #GFileIOStream pointing to it.
6909
 *
6910
 * @tmpl should be a string in the GLib file name encoding
6911
 * containing a sequence of six 'X' characters, and containing no
6912
 * directory components. If it is %NULL, a default template is used.
6913
 *
6914
 * Unlike the other #GFile constructors, this will return %NULL if
6915
 * a temporary file could not be created.
6916
 *
6917
 * Returns: (transfer full): a new #GFile.
6918
 *   Free the returned object with g_object_unref().
6919
 *
6920
 * Since: 2.32
6921
 */
6922
GFile *
6923
g_file_new_tmp (const char     *tmpl,
6924
                GFileIOStream **iostream,
6925
                GError        **error)
6926
0
{
6927
0
  gint fd;
6928
0
  gchar *path;
6929
0
  GFile *file;
6930
0
  GFileOutputStream *output;
6931
6932
0
  g_return_val_if_fail (iostream != NULL, NULL);
6933
6934
0
  fd = g_file_open_tmp (tmpl, &path, error);
6935
0
  if (fd == -1)
6936
0
    return NULL;
6937
6938
0
  file = g_file_new_for_path (path);
6939
6940
0
  output = _g_local_file_output_stream_new (fd);
6941
0
  *iostream = _g_local_file_io_stream_new (G_LOCAL_FILE_OUTPUT_STREAM (output));
6942
6943
0
  g_object_unref (output);
6944
0
  g_free (path);
6945
6946
0
  return file;
6947
0
}
6948
6949
typedef struct {
6950
  GFile *file;
6951
  GFileIOStream *iostream;
6952
} NewTmpAsyncData;
6953
6954
static void
6955
new_tmp_data_free (NewTmpAsyncData *data)
6956
0
{
6957
0
  g_clear_object (&data->file);
6958
0
  g_clear_object (&data->iostream);
6959
0
  g_free (data);
6960
0
}
6961
6962
static void
6963
new_tmp_async_thread (GTask         *task,
6964
                      gpointer       object,
6965
                      gpointer       task_data,
6966
                      GCancellable  *cancellable)
6967
0
{
6968
0
  GFile *file;
6969
0
  const char *tmpl = task_data;
6970
0
  GFileIOStream *iostream = NULL;
6971
0
  GError *error = NULL;
6972
0
  NewTmpAsyncData *return_data;
6973
6974
0
  if (g_task_return_error_if_cancelled (task))
6975
0
    return;
6976
6977
0
  file = g_file_new_tmp (tmpl, &iostream, &error);
6978
6979
0
  if (!file)
6980
0
    {
6981
0
      int error_code = G_IO_ERROR_FAILED;
6982
6983
0
      if (error->domain == G_IO_ERROR)
6984
0
        {
6985
0
          g_task_return_error (task, g_steal_pointer (&error));
6986
0
          return;
6987
0
        }
6988
6989
0
      if (error->domain == G_FILE_ERROR)
6990
0
        error_code = g_io_error_from_file_error (error->code);
6991
6992
0
      g_task_return_new_error (task, G_IO_ERROR, error_code,
6993
0
                               _("Failed to create a temporary directory for "
6994
0
                                 "template “%s”: %s"),
6995
0
                               tmpl, error->message);
6996
6997
0
      g_clear_error (&error);
6998
0
      return;
6999
0
    }
7000
7001
0
  return_data = g_new0 (NewTmpAsyncData, 1);
7002
0
  return_data->file = g_steal_pointer (&file);
7003
0
  return_data->iostream = g_steal_pointer (&iostream);
7004
7005
0
  g_task_return_pointer (task, g_steal_pointer (&return_data),
7006
0
                         (GDestroyNotify) new_tmp_data_free);
7007
0
}
7008
7009
/**
7010
 * g_file_new_tmp_async:
7011
 * @tmpl: (type filename) (nullable): Template for the file
7012
 *   name, as in g_file_open_tmp(), or %NULL for a default template
7013
 * @io_priority: the [I/O priority][io-priority] of the request
7014
 * @cancellable: optional #GCancellable object, %NULL to ignore
7015
 * @callback: (nullable): a #GAsyncReadyCallback to call when the request is done
7016
 * @user_data: (nullable): data to pass to @callback
7017
 *
7018
 * Asynchronously opens a file in the preferred directory for temporary files
7019
 *  (as returned by g_get_tmp_dir()) as g_file_new_tmp().
7020
 *
7021
 * @tmpl should be a string in the GLib file name encoding
7022
 * containing a sequence of six 'X' characters, and containing no
7023
 * directory components. If it is %NULL, a default template is used.
7024
 *
7025
 * Since: 2.74
7026
 */
7027
void
7028
g_file_new_tmp_async (const char          *tmpl,
7029
                      int                  io_priority,
7030
                      GCancellable        *cancellable,
7031
                      GAsyncReadyCallback  callback,
7032
                      gpointer             user_data)
7033
0
{
7034
0
  GTask *task;
7035
7036
0
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
7037
7038
0
  task = g_task_new (NULL, cancellable, callback, user_data);
7039
0
  g_task_set_source_tag (task, g_file_new_tmp_async);
7040
0
  g_task_set_task_data (task, g_strdup (tmpl), g_free);
7041
0
  g_task_set_priority (task, io_priority);
7042
0
  g_task_set_check_cancellable (task, TRUE);
7043
0
  g_task_run_in_thread (task, new_tmp_async_thread);
7044
0
  g_object_unref (task);
7045
0
}
7046
7047
/**
7048
 * g_file_new_tmp_finish:
7049
 * @result: a #GAsyncResult
7050
 * @iostream: (out) (not optional) (not nullable) (transfer full): on return, a #GFileIOStream for the created file
7051
 * @error: a #GError, or %NULL
7052
 *
7053
 * Finishes a temporary file creation started by g_file_new_tmp_async().
7054
 *
7055
 * Returns: (transfer full): a new #GFile.
7056
 *   Free the returned object with g_object_unref().
7057
 *
7058
 * Since: 2.74
7059
 */
7060
GFile *
7061
g_file_new_tmp_finish (GAsyncResult   *result,
7062
                       GFileIOStream **iostream,
7063
                       GError        **error)
7064
0
{
7065
0
  GFile *file;
7066
0
  NewTmpAsyncData *data;
7067
7068
0
  g_return_val_if_fail (g_task_is_valid (result, NULL), NULL);
7069
0
  g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
7070
0
                        g_file_new_tmp_async, NULL);
7071
0
  g_return_val_if_fail (iostream != NULL, NULL);
7072
0
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
7073
7074
0
  data = g_task_propagate_pointer (G_TASK (result), error);
7075
7076
0
  if (!data)
7077
0
    {
7078
0
      *iostream = NULL;
7079
0
      return NULL;
7080
0
    }
7081
7082
0
  file = g_steal_pointer (&data->file);
7083
0
  *iostream = g_steal_pointer (&data->iostream);
7084
7085
0
  new_tmp_data_free (data);
7086
7087
0
  return file;
7088
0
}
7089
7090
static void
7091
new_tmp_dir_async_thread (GTask         *task,
7092
                          gpointer       object,
7093
                          gpointer       task_data,
7094
                          GCancellable  *cancellable)
7095
0
{
7096
0
  gchar *path;
7097
0
  const char *tmpl = task_data;
7098
0
  GError *error = NULL;
7099
7100
0
  if (g_task_return_error_if_cancelled (task))
7101
0
    return;
7102
7103
0
  path = g_dir_make_tmp (tmpl, &error);
7104
7105
0
  if (!path)
7106
0
    {
7107
0
      int error_code = G_IO_ERROR_FAILED;
7108
7109
0
      if (error->domain == G_IO_ERROR)
7110
0
        {
7111
0
          g_task_return_error (task, g_steal_pointer (&error));
7112
0
          return;
7113
0
        }
7114
7115
0
      if (error->domain == G_FILE_ERROR)
7116
0
        error_code = g_io_error_from_file_error (error->code);
7117
7118
0
      g_task_return_new_error (task, G_IO_ERROR, error_code,
7119
0
                               _("Failed to create a temporary directory for "
7120
0
                                 "template “%s”: %s"),
7121
0
                               tmpl, error->message);
7122
7123
0
      g_clear_error (&error);
7124
0
      return;
7125
0
    }
7126
7127
0
  g_task_return_pointer (task, g_file_new_for_path (path), g_object_unref);
7128
7129
0
  g_free (path);
7130
0
}
7131
7132
/**
7133
 * g_file_new_tmp_dir_async:
7134
 * @tmpl: (type filename) (nullable): Template for the file
7135
 *   name, as in g_dir_make_tmp(), or %NULL for a default template
7136
 * @io_priority: the [I/O priority][io-priority] of the request
7137
 * @cancellable: optional #GCancellable object, %NULL to ignore
7138
 * @callback: (nullable): a #GAsyncReadyCallback to call when the request is done
7139
 * @user_data: (nullable): data to pass to @callback
7140
 *
7141
 * Asynchronously creates a directory in the preferred directory for
7142
 * temporary files (as returned by g_get_tmp_dir()) as g_dir_make_tmp().
7143
 *
7144
 * @tmpl should be a string in the GLib file name encoding
7145
 * containing a sequence of six 'X' characters, and containing no
7146
 * directory components. If it is %NULL, a default template is used.
7147
 *
7148
 * Since: 2.74
7149
 */
7150
void
7151
g_file_new_tmp_dir_async (const char          *tmpl,
7152
                          int                  io_priority,
7153
                          GCancellable        *cancellable,
7154
                          GAsyncReadyCallback  callback,
7155
                          gpointer             user_data)
7156
0
{
7157
0
  GTask *task;
7158
7159
0
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
7160
7161
0
  task = g_task_new (NULL, cancellable, callback, user_data);
7162
0
  g_task_set_source_tag (task, g_file_new_tmp_dir_async);
7163
0
  g_task_set_task_data (task, g_strdup (tmpl), g_free);
7164
0
  g_task_set_priority (task, io_priority);
7165
0
  g_task_set_check_cancellable (task, TRUE);
7166
0
  g_task_run_in_thread (task, new_tmp_dir_async_thread);
7167
0
  g_object_unref (task);
7168
0
}
7169
7170
/**
7171
 * g_file_new_tmp_dir_finish:
7172
 * @result: a #GAsyncResult
7173
 * @error: a #GError, or %NULL
7174
 *
7175
 * Finishes a temporary directory creation started by
7176
 * g_file_new_tmp_dir_async().
7177
 *
7178
 * Returns: (transfer full): a new #GFile.
7179
 *   Free the returned object with g_object_unref().
7180
 *
7181
 * Since: 2.74
7182
 */
7183
GFile *
7184
g_file_new_tmp_dir_finish (GAsyncResult  *result,
7185
                           GError       **error)
7186
0
{
7187
0
  g_return_val_if_fail (g_task_is_valid (result, NULL), NULL);
7188
0
  g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
7189
0
                        g_file_new_tmp_dir_async, NULL);
7190
0
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
7191
7192
0
  return g_task_propagate_pointer (G_TASK (result), error);
7193
0
}
7194
7195
/**
7196
 * g_file_parse_name:
7197
 * @parse_name: a file name or path to be parsed
7198
 *
7199
 * Constructs a #GFile with the given @parse_name (i.e. something
7200
 * given by g_file_get_parse_name()). This operation never fails,
7201
 * but the returned object might not support any I/O operation if
7202
 * the @parse_name cannot be parsed.
7203
 *
7204
 * Returns: (transfer full): a new #GFile.
7205
 */
7206
GFile *
7207
g_file_parse_name (const char *parse_name)
7208
0
{
7209
0
  g_return_val_if_fail (parse_name != NULL, NULL);
7210
7211
0
  return g_vfs_parse_name (g_vfs_get_default (), parse_name);
7212
0
}
7213
7214
/**
7215
 * g_file_new_build_filename:
7216
 * @first_element: (type filename): the first element in the path
7217
 * @...: remaining elements in path, terminated by %NULL
7218
 *
7219
 * Constructs a #GFile from a series of elements using the correct
7220
 * separator for filenames.
7221
 *
7222
 * Using this function is equivalent to calling g_build_filename(),
7223
 * followed by g_file_new_for_path() on the result.
7224
 *
7225
 * Returns: (transfer full): a new #GFile
7226
 *
7227
 * Since: 2.56
7228
 */
7229
GFile *
7230
g_file_new_build_filename (const gchar *first_element,
7231
                           ...)
7232
0
{
7233
0
  gchar *str;
7234
0
  GFile *file;
7235
0
  va_list args;
7236
7237
0
  g_return_val_if_fail (first_element != NULL, NULL);
7238
7239
0
  va_start (args, first_element);
7240
0
  str = g_build_filename_valist (first_element, &args);
7241
0
  va_end (args);
7242
7243
0
  file = g_file_new_for_path (str);
7244
0
  g_free (str);
7245
7246
0
  return file;
7247
0
}
7248
7249
static gboolean
7250
is_valid_scheme_character (char c)
7251
0
{
7252
0
  return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.';
7253
0
}
7254
7255
/* Following RFC 2396, valid schemes are built like:
7256
 *       scheme        = alpha *( alpha | digit | "+" | "-" | "." )
7257
 */
7258
static gboolean
7259
has_valid_scheme (const char *uri)
7260
0
{
7261
0
  const char *p;
7262
7263
0
  p = uri;
7264
7265
0
  if (!g_ascii_isalpha (*p))
7266
0
    return FALSE;
7267
7268
0
  do {
7269
0
    p++;
7270
0
  } while (is_valid_scheme_character (*p));
7271
7272
0
  return *p == ':';
7273
0
}
7274
7275
static GFile *
7276
new_for_cmdline_arg (const gchar *arg,
7277
                     const gchar *cwd)
7278
0
{
7279
0
  GFile *file;
7280
0
  char *filename;
7281
7282
0
  if (g_path_is_absolute (arg))
7283
0
    return g_file_new_for_path (arg);
7284
7285
0
  if (has_valid_scheme (arg))
7286
0
    return g_file_new_for_uri (arg);
7287
7288
0
  if (cwd == NULL)
7289
0
    {
7290
0
      char *current_dir;
7291
7292
0
      current_dir = g_get_current_dir ();
7293
0
      filename = g_build_filename (current_dir, arg, NULL);
7294
0
      g_free (current_dir);
7295
0
    }
7296
0
  else
7297
0
    filename = g_build_filename (cwd, arg, NULL);
7298
7299
0
  file = g_file_new_for_path (filename);
7300
0
  g_free (filename);
7301
7302
0
  return file;
7303
0
}
7304
7305
/**
7306
 * g_file_new_for_commandline_arg:
7307
 * @arg: (type filename): a command line string
7308
 *
7309
 * Creates a #GFile with the given argument from the command line.
7310
 * The value of @arg can be either a URI, an absolute path or a
7311
 * relative path resolved relative to the current working directory.
7312
 * This operation never fails, but the returned object might not
7313
 * support any I/O operation if @arg points to a malformed path.
7314
 *
7315
 * Note that on Windows, this function expects its argument to be in
7316
 * UTF-8 -- not the system code page.  This means that you
7317
 * should not use this function with string from argv as it is passed
7318
 * to main().  g_win32_get_command_line() will return a UTF-8 version of
7319
 * the commandline.  #GApplication also uses UTF-8 but
7320
 * g_application_command_line_create_file_for_arg() may be more useful
7321
 * for you there.  It is also always possible to use this function with
7322
 * #GOptionContext arguments of type %G_OPTION_ARG_FILENAME.
7323
 *
7324
 * Returns: (transfer full): a new #GFile.
7325
 *   Free the returned object with g_object_unref().
7326
 */
7327
GFile *
7328
g_file_new_for_commandline_arg (const char *arg)
7329
0
{
7330
0
  g_return_val_if_fail (arg != NULL, NULL);
7331
7332
0
  return new_for_cmdline_arg (arg, NULL);
7333
0
}
7334
7335
/**
7336
 * g_file_new_for_commandline_arg_and_cwd:
7337
 * @arg: (type filename): a command line string
7338
 * @cwd: (type filename): the current working directory of the commandline
7339
 *
7340
 * Creates a #GFile with the given argument from the command line.
7341
 *
7342
 * This function is similar to g_file_new_for_commandline_arg() except
7343
 * that it allows for passing the current working directory as an
7344
 * argument instead of using the current working directory of the
7345
 * process.
7346
 *
7347
 * This is useful if the commandline argument was given in a context
7348
 * other than the invocation of the current process.
7349
 *
7350
 * See also g_application_command_line_create_file_for_arg().
7351
 *
7352
 * Returns: (transfer full): a new #GFile
7353
 *
7354
 * Since: 2.36
7355
 **/
7356
GFile *
7357
g_file_new_for_commandline_arg_and_cwd (const gchar *arg,
7358
                                        const gchar *cwd)
7359
0
{
7360
0
  g_return_val_if_fail (arg != NULL, NULL);
7361
0
  g_return_val_if_fail (cwd != NULL, NULL);
7362
7363
0
  return new_for_cmdline_arg (arg, cwd);
7364
0
}
7365
7366
/**
7367
 * g_file_mount_enclosing_volume:
7368
 * @location: input #GFile
7369
 * @flags: flags affecting the operation
7370
 * @mount_operation: (nullable): a #GMountOperation
7371
 *   or %NULL to avoid user interaction
7372
 * @cancellable: (nullable): optional #GCancellable object,
7373
 *   %NULL to ignore
7374
 * @callback: (nullable): a #GAsyncReadyCallback to call
7375
 *   when the request is satisfied, or %NULL
7376
 * @user_data: the data to pass to callback function
7377
 *
7378
 * Starts a @mount_operation, mounting the volume that contains
7379
 * the file @location.
7380
 *
7381
 * When this operation has completed, @callback will be called with
7382
 * @user_user data, and the operation can be finalized with
7383
 * g_file_mount_enclosing_volume_finish().
7384
 *
7385
 * If @cancellable is not %NULL, then the operation can be cancelled by
7386
 * triggering the cancellable object from another thread. If the operation
7387
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7388
 */
7389
void
7390
g_file_mount_enclosing_volume (GFile               *location,
7391
                               GMountMountFlags     flags,
7392
                               GMountOperation     *mount_operation,
7393
                               GCancellable        *cancellable,
7394
                               GAsyncReadyCallback  callback,
7395
                               gpointer             user_data)
7396
0
{
7397
0
  GFileIface *iface;
7398
7399
0
  g_return_if_fail (G_IS_FILE (location));
7400
7401
0
  iface = G_FILE_GET_IFACE (location);
7402
7403
0
  if (iface->mount_enclosing_volume == NULL)
7404
0
    {
7405
0
      g_task_report_new_error (location, callback, user_data,
7406
0
                               g_file_mount_enclosing_volume,
7407
0
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
7408
0
                               _("volume doesn’t implement mount"));
7409
0
      return;
7410
0
    }
7411
7412
0
  (* iface->mount_enclosing_volume) (location, flags, mount_operation, cancellable, callback, user_data);
7413
7414
0
}
7415
7416
/**
7417
 * g_file_mount_enclosing_volume_finish:
7418
 * @location: input #GFile
7419
 * @result: a #GAsyncResult
7420
 * @error: a #GError, or %NULL
7421
 *
7422
 * Finishes a mount operation started by g_file_mount_enclosing_volume().
7423
 *
7424
 * Returns: %TRUE if successful. If an error has occurred,
7425
 *   this function will return %FALSE and set @error
7426
 *   appropriately if present.
7427
 */
7428
gboolean
7429
g_file_mount_enclosing_volume_finish (GFile         *location,
7430
                                      GAsyncResult  *result,
7431
                                      GError       **error)
7432
0
{
7433
0
  GFileIface *iface;
7434
7435
0
  g_return_val_if_fail (G_IS_FILE (location), FALSE);
7436
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
7437
7438
0
  if (g_async_result_legacy_propagate_error (result, error))
7439
0
    return FALSE;
7440
0
  else if (g_async_result_is_tagged (result, g_file_mount_enclosing_volume))
7441
0
    return g_task_propagate_boolean (G_TASK (result), error);
7442
7443
0
  iface = G_FILE_GET_IFACE (location);
7444
7445
0
  return (* iface->mount_enclosing_volume_finish) (location, result, error);
7446
0
}
7447
7448
/********************************************
7449
 *   Utility functions                      *
7450
 ********************************************/
7451
7452
/**
7453
 * g_file_query_default_handler:
7454
 * @file: a #GFile to open
7455
 * @cancellable: optional #GCancellable object, %NULL to ignore
7456
 * @error: a #GError, or %NULL
7457
 *
7458
 * Returns the #GAppInfo that is registered as the default
7459
 * application to handle the file specified by @file.
7460
 *
7461
 * If @cancellable is not %NULL, then the operation can be cancelled by
7462
 * triggering the cancellable object from another thread. If the operation
7463
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7464
 *
7465
 * Returns: (transfer full): a #GAppInfo if the handle was found,
7466
 *   %NULL if there were errors.
7467
 *   When you are done with it, release it with g_object_unref()
7468
 */
7469
GAppInfo *
7470
g_file_query_default_handler (GFile         *file,
7471
                              GCancellable  *cancellable,
7472
                              GError       **error)
7473
0
{
7474
0
  char *uri_scheme;
7475
0
  const char *content_type;
7476
0
  GAppInfo *appinfo;
7477
0
  GFileInfo *info;
7478
0
  char *path;
7479
7480
0
  uri_scheme = g_file_get_uri_scheme (file);
7481
0
  if (uri_scheme && uri_scheme[0] != '\0')
7482
0
    {
7483
0
      appinfo = g_app_info_get_default_for_uri_scheme (uri_scheme);
7484
0
      g_free (uri_scheme);
7485
7486
0
      if (appinfo != NULL)
7487
0
        return appinfo;
7488
0
    }
7489
0
  else
7490
0
    g_free (uri_scheme);
7491
7492
0
  info = g_file_query_info (file,
7493
0
                            G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
7494
0
                            G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE,
7495
0
                            0,
7496
0
                            cancellable,
7497
0
                            error);
7498
0
  if (info == NULL)
7499
0
    return NULL;
7500
7501
0
  appinfo = NULL;
7502
7503
0
  content_type = g_file_info_get_content_type (info);
7504
0
  if (content_type == NULL)
7505
0
    content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
7506
0
  if (content_type)
7507
0
    {
7508
      /* Don't use is_native(), as we want to support fuse paths if available */
7509
0
      path = g_file_get_path (file);
7510
0
      appinfo = g_app_info_get_default_for_type (content_type,
7511
0
                                                 path == NULL);
7512
0
      g_free (path);
7513
0
    }
7514
7515
0
  g_object_unref (info);
7516
7517
0
  if (appinfo != NULL)
7518
0
    return appinfo;
7519
7520
0
  g_set_error_literal (error, G_IO_ERROR,
7521
0
                       G_IO_ERROR_NOT_SUPPORTED,
7522
0
                       _("No application is registered as handling this file"));
7523
0
  return NULL;
7524
0
}
7525
7526
static void
7527
query_default_handler_query_app_info_for_type_cb (GObject      *object,
7528
                                                  GAsyncResult *result,
7529
                                                  gpointer      user_data)
7530
0
{
7531
0
  GTask *task = G_TASK (user_data);
7532
0
  GAppInfo *appinfo;
7533
0
  GError *error = NULL;
7534
7535
0
  appinfo = g_app_info_get_default_for_type_finish (result, &error);
7536
7537
0
  if (appinfo != NULL)
7538
0
    {
7539
0
      g_task_return_pointer (task, g_steal_pointer (&appinfo), g_object_unref);
7540
0
    }
7541
0
  else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
7542
0
    {
7543
0
      g_task_return_new_error (task,
7544
0
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
7545
0
                               "%s", error->message);
7546
0
    }
7547
0
  else
7548
0
    {
7549
0
      g_task_return_error (task, g_steal_pointer (&error));
7550
0
    }
7551
7552
0
  g_clear_error (&error);
7553
0
  g_object_unref (task);
7554
0
}
7555
7556
static void
7557
query_default_handler_query_info_cb (GObject      *object,
7558
                                     GAsyncResult *result,
7559
                                     gpointer      user_data)
7560
0
{
7561
0
  GFile *file = G_FILE (object);
7562
0
  GTask *task = G_TASK (user_data);
7563
0
  GError *error = NULL;
7564
0
  GFileInfo *info;
7565
0
  const char *content_type;
7566
7567
0
  info = g_file_query_info_finish (file, result, &error);
7568
0
  if (info == NULL)
7569
0
    {
7570
0
      g_task_return_error (task, g_steal_pointer (&error));
7571
0
      g_object_unref (task);
7572
0
      return;
7573
0
    }
7574
7575
0
  content_type = g_file_info_get_content_type (info);
7576
0
  if (content_type == NULL)
7577
0
    content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
7578
0
  if (content_type)
7579
0
    {
7580
0
      GCancellable *cancellable = g_task_get_cancellable (task);
7581
0
      char *path;
7582
7583
      /* Don't use is_native(), as we want to support fuse paths if available */
7584
0
      path = g_file_get_path (file);
7585
7586
0
      g_app_info_get_default_for_type_async (content_type,
7587
0
                                             path == NULL,
7588
0
                                             cancellable,
7589
0
                                             query_default_handler_query_app_info_for_type_cb,
7590
0
                                             g_steal_pointer (&task));
7591
7592
0
      g_free (path);
7593
0
    }
7594
0
  else
7595
0
    {
7596
0
      g_task_return_new_error (task,
7597
0
                               G_IO_ERROR,
7598
0
                               G_IO_ERROR_NOT_SUPPORTED,
7599
0
                               _("No application is registered as handling this file"));
7600
0
    }
7601
7602
0
  g_object_unref (info);
7603
0
  g_clear_object (&task);
7604
0
}
7605
7606
static void
7607
on_query_default_handler_for_uri_cb (GObject      *object,
7608
                                     GAsyncResult *result,
7609
                                     gpointer      user_data)
7610
0
{
7611
0
  GTask *task = user_data;
7612
0
  GAppInfo *app_info;
7613
7614
0
  app_info = g_app_info_get_default_for_uri_scheme_finish (result, NULL);
7615
7616
0
  if (app_info)
7617
0
    {
7618
0
      g_task_return_pointer (task, g_steal_pointer (&app_info), g_object_unref);
7619
0
      g_object_unref (task);
7620
0
    }
7621
0
  else
7622
0
    {
7623
0
      g_file_query_info_async (g_task_get_source_object (task),
7624
0
                               G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
7625
0
                               G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE,
7626
0
                               0,
7627
0
                               g_task_get_priority (task),
7628
0
                               g_task_get_cancellable (task),
7629
0
                               query_default_handler_query_info_cb,
7630
0
                               task);
7631
0
    }
7632
0
}
7633
7634
/**
7635
 * g_file_query_default_handler_async:
7636
 * @file: a #GFile to open
7637
 * @io_priority: the [I/O priority][io-priority] of the request
7638
 * @cancellable: optional #GCancellable object, %NULL to ignore
7639
 * @callback: (nullable): a #GAsyncReadyCallback to call when the request is done
7640
 * @user_data: (nullable): data to pass to @callback
7641
 *
7642
 * Async version of g_file_query_default_handler().
7643
 *
7644
 * Since: 2.60
7645
 */
7646
void
7647
g_file_query_default_handler_async (GFile              *file,
7648
                                    int                 io_priority,
7649
                                    GCancellable       *cancellable,
7650
                                    GAsyncReadyCallback callback,
7651
                                    gpointer            user_data)
7652
0
{
7653
0
  GTask *task;
7654
0
  char *uri_scheme;
7655
7656
0
  task = g_task_new (file, cancellable, callback, user_data);
7657
0
  g_task_set_source_tag (task, g_file_query_default_handler_async);
7658
7659
0
  uri_scheme = g_file_get_uri_scheme (file);
7660
0
  if (uri_scheme && uri_scheme[0] != '\0')
7661
0
    {
7662
0
      g_app_info_get_default_for_uri_scheme_async (uri_scheme,
7663
0
                                                   cancellable,
7664
0
                                                   on_query_default_handler_for_uri_cb,
7665
0
                                                   g_steal_pointer (&task));
7666
0
      g_free (uri_scheme);
7667
0
      return;
7668
0
    }
7669
7670
0
  g_file_query_info_async (file,
7671
0
                           G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
7672
0
                           G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE,
7673
0
                           0,
7674
0
                           io_priority,
7675
0
                           cancellable,
7676
0
                           query_default_handler_query_info_cb,
7677
0
                           g_steal_pointer (&task));
7678
7679
0
  g_free (uri_scheme);
7680
0
}
7681
7682
/**
7683
 * g_file_query_default_handler_finish:
7684
 * @file: a #GFile to open
7685
 * @result: a #GAsyncResult
7686
 * @error: (nullable): a #GError
7687
 *
7688
 * Finishes a g_file_query_default_handler_async() operation.
7689
 *
7690
 * Returns: (transfer full): a #GAppInfo if the handle was found,
7691
 *   %NULL if there were errors.
7692
 *   When you are done with it, release it with g_object_unref()
7693
 *
7694
 * Since: 2.60
7695
 */
7696
GAppInfo *
7697
g_file_query_default_handler_finish (GFile        *file,
7698
                                     GAsyncResult *result,
7699
                                     GError      **error)
7700
0
{
7701
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
7702
0
  g_return_val_if_fail (g_task_is_valid (result, file), NULL);
7703
7704
0
  return g_task_propagate_pointer (G_TASK (result), error);
7705
0
}
7706
7707
0
#define GET_CONTENT_BLOCK_SIZE 8192
7708
7709
/**
7710
 * g_file_load_contents:
7711
 * @file: input #GFile
7712
 * @cancellable: optional #GCancellable object, %NULL to ignore
7713
 * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
7714
 * @length: (out) (optional): a location to place the length of the contents of the file,
7715
 *   or %NULL if the length is not needed
7716
 * @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file,
7717
 *   or %NULL if the entity tag is not needed
7718
 * @error: a #GError, or %NULL
7719
 *
7720
 * Loads the content of the file into memory. The data is always
7721
 * zero-terminated, but this is not included in the resultant @length.
7722
 * The returned @contents should be freed with g_free() when no longer
7723
 * needed.
7724
 *
7725
 * If @cancellable is not %NULL, then the operation can be cancelled by
7726
 * triggering the cancellable object from another thread. If the operation
7727
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7728
 *
7729
 * Returns: %TRUE if the @file's contents were successfully loaded.
7730
 *   %FALSE if there were errors.
7731
 */
7732
gboolean
7733
g_file_load_contents (GFile         *file,
7734
                      GCancellable  *cancellable,
7735
                      char         **contents,
7736
                      gsize         *length,
7737
                      char         **etag_out,
7738
                      GError       **error)
7739
0
{
7740
0
  GFileInputStream *in;
7741
0
  GByteArray *content;
7742
0
  gsize pos;
7743
0
  gssize res;
7744
0
  GFileInfo *info;
7745
7746
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
7747
0
  g_return_val_if_fail (contents != NULL, FALSE);
7748
7749
0
  in = g_file_read (file, cancellable, error);
7750
0
  if (in == NULL)
7751
0
    return FALSE;
7752
7753
0
  content = g_byte_array_new ();
7754
0
  pos = 0;
7755
7756
0
  g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
7757
0
  while ((res = g_input_stream_read (G_INPUT_STREAM (in),
7758
0
                                     content->data + pos,
7759
0
                                     GET_CONTENT_BLOCK_SIZE,
7760
0
                                     cancellable, error)) > 0)
7761
0
    {
7762
0
      pos += res;
7763
0
      g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
7764
0
    }
7765
7766
0
  if (etag_out)
7767
0
    {
7768
0
      *etag_out = NULL;
7769
7770
0
      info = g_file_input_stream_query_info (in,
7771
0
                                             G_FILE_ATTRIBUTE_ETAG_VALUE,
7772
0
                                             cancellable,
7773
0
                                             NULL);
7774
0
      if (info)
7775
0
        {
7776
0
          *etag_out = g_strdup (g_file_info_get_etag (info));
7777
0
          g_object_unref (info);
7778
0
        }
7779
0
    }
7780
7781
  /* Ignore errors on close */
7782
0
  g_input_stream_close (G_INPUT_STREAM (in), cancellable, NULL);
7783
0
  g_object_unref (in);
7784
7785
0
  if (res < 0)
7786
0
    {
7787
      /* error is set already */
7788
0
      g_byte_array_free (content, TRUE);
7789
0
      return FALSE;
7790
0
    }
7791
7792
0
  if (length)
7793
0
    *length = pos;
7794
7795
  /* Zero terminate (we got an extra byte allocated for this */
7796
0
  content->data[pos] = 0;
7797
7798
0
  *contents = (char *)g_byte_array_free (content, FALSE);
7799
7800
0
  return TRUE;
7801
0
}
7802
7803
typedef struct {
7804
  GTask *task;
7805
  GFileReadMoreCallback read_more_callback;
7806
  GByteArray *content;
7807
  gsize pos;
7808
  char *etag;
7809
} LoadContentsData;
7810
7811
7812
static void
7813
load_contents_data_free (LoadContentsData *data)
7814
0
{
7815
0
  if (data->content)
7816
0
    g_byte_array_free (data->content, TRUE);
7817
0
  g_free (data->etag);
7818
0
  g_free (data);
7819
0
}
7820
7821
static void
7822
load_contents_close_callback (GObject      *obj,
7823
                              GAsyncResult *close_res,
7824
                              gpointer      user_data)
7825
0
{
7826
0
  GInputStream *stream = G_INPUT_STREAM (obj);
7827
0
  LoadContentsData *data = user_data;
7828
7829
  /* Ignore errors here, we're only reading anyway */
7830
0
  g_input_stream_close_finish (stream, close_res, NULL);
7831
0
  g_object_unref (stream);
7832
7833
0
  g_task_return_boolean (data->task, TRUE);
7834
0
  g_object_unref (data->task);
7835
0
}
7836
7837
static void
7838
load_contents_fstat_callback (GObject      *obj,
7839
                              GAsyncResult *stat_res,
7840
                              gpointer      user_data)
7841
0
{
7842
0
  GInputStream *stream = G_INPUT_STREAM (obj);
7843
0
  LoadContentsData *data = user_data;
7844
0
  GFileInfo *info;
7845
7846
0
  info = g_file_input_stream_query_info_finish (G_FILE_INPUT_STREAM (stream),
7847
0
                                                stat_res, NULL);
7848
0
  if (info)
7849
0
    {
7850
0
      data->etag = g_strdup (g_file_info_get_etag (info));
7851
0
      g_object_unref (info);
7852
0
    }
7853
7854
0
  g_input_stream_close_async (stream, 0,
7855
0
                              g_task_get_cancellable (data->task),
7856
0
                              load_contents_close_callback, data);
7857
0
}
7858
7859
static void
7860
load_contents_read_callback (GObject      *obj,
7861
                             GAsyncResult *read_res,
7862
                             gpointer      user_data)
7863
0
{
7864
0
  GInputStream *stream = G_INPUT_STREAM (obj);
7865
0
  LoadContentsData *data = user_data;
7866
0
  GError *error = NULL;
7867
0
  gssize read_size;
7868
7869
0
  read_size = g_input_stream_read_finish (stream, read_res, &error);
7870
7871
0
  if (read_size < 0)
7872
0
    {
7873
0
      g_task_return_error (data->task, error);
7874
0
      g_object_unref (data->task);
7875
7876
      /* Close the file ignoring any error */
7877
0
      g_input_stream_close_async (stream, 0, NULL, NULL, NULL);
7878
0
      g_object_unref (stream);
7879
0
    }
7880
0
  else if (read_size == 0)
7881
0
    {
7882
0
      g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
7883
0
                                            G_FILE_ATTRIBUTE_ETAG_VALUE,
7884
0
                                            0,
7885
0
                                            g_task_get_cancellable (data->task),
7886
0
                                            load_contents_fstat_callback,
7887
0
                                            data);
7888
0
    }
7889
0
  else if (read_size > 0)
7890
0
    {
7891
0
      data->pos += read_size;
7892
7893
0
      g_byte_array_set_size (data->content,
7894
0
                             data->pos + GET_CONTENT_BLOCK_SIZE);
7895
7896
7897
0
      if (data->read_more_callback &&
7898
0
          !data->read_more_callback ((char *)data->content->data, data->pos,
7899
0
                                     g_async_result_get_user_data (G_ASYNC_RESULT (data->task))))
7900
0
        g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
7901
0
                                              G_FILE_ATTRIBUTE_ETAG_VALUE,
7902
0
                                              0,
7903
0
                                              g_task_get_cancellable (data->task),
7904
0
                                              load_contents_fstat_callback,
7905
0
                                              data);
7906
0
      else
7907
0
        g_input_stream_read_async (stream,
7908
0
                                   data->content->data + data->pos,
7909
0
                                   GET_CONTENT_BLOCK_SIZE,
7910
0
                                   0,
7911
0
                                   g_task_get_cancellable (data->task),
7912
0
                                   load_contents_read_callback,
7913
0
                                   data);
7914
0
    }
7915
0
}
7916
7917
static void
7918
load_contents_open_callback (GObject      *obj,
7919
                             GAsyncResult *open_res,
7920
                             gpointer      user_data)
7921
0
{
7922
0
  GFile *file = G_FILE (obj);
7923
0
  GFileInputStream *stream;
7924
0
  LoadContentsData *data = user_data;
7925
0
  GError *error = NULL;
7926
7927
0
  stream = g_file_read_finish (file, open_res, &error);
7928
7929
0
  if (stream)
7930
0
    {
7931
0
      g_byte_array_set_size (data->content,
7932
0
                             data->pos + GET_CONTENT_BLOCK_SIZE);
7933
0
      g_input_stream_read_async (G_INPUT_STREAM (stream),
7934
0
                                 data->content->data + data->pos,
7935
0
                                 GET_CONTENT_BLOCK_SIZE,
7936
0
                                 0,
7937
0
                                 g_task_get_cancellable (data->task),
7938
0
                                 load_contents_read_callback,
7939
0
                                 data);
7940
0
    }
7941
0
  else
7942
0
    {
7943
0
      g_task_return_error (data->task, error);
7944
0
      g_object_unref (data->task);
7945
0
    }
7946
0
}
7947
7948
/**
7949
 * g_file_load_partial_contents_async: (skip)
7950
 * @file: input #GFile
7951
 * @cancellable: optional #GCancellable object, %NULL to ignore
7952
 * @read_more_callback: (scope call) (closure user_data): a
7953
 *   #GFileReadMoreCallback to receive partial data
7954
 *   and to specify whether further data should be read
7955
 * @callback: (scope async) (closure user_data): a #GAsyncReadyCallback to call
7956
 *   when the request is satisfied
7957
 * @user_data: the data to pass to the callback functions
7958
 *
7959
 * Reads the partial contents of a file. A #GFileReadMoreCallback should
7960
 * be used to stop reading from the file when appropriate, else this
7961
 * function will behave exactly as g_file_load_contents_async(). This
7962
 * operation can be finished by g_file_load_partial_contents_finish().
7963
 *
7964
 * Users of this function should be aware that @user_data is passed to
7965
 * both the @read_more_callback and the @callback.
7966
 *
7967
 * If @cancellable is not %NULL, then the operation can be cancelled by
7968
 * triggering the cancellable object from another thread. If the operation
7969
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7970
 */
7971
void
7972
g_file_load_partial_contents_async (GFile                 *file,
7973
                                    GCancellable          *cancellable,
7974
                                    GFileReadMoreCallback  read_more_callback,
7975
                                    GAsyncReadyCallback    callback,
7976
                                    gpointer               user_data)
7977
0
{
7978
0
  LoadContentsData *data;
7979
7980
0
  g_return_if_fail (G_IS_FILE (file));
7981
7982
0
  data = g_new0 (LoadContentsData, 1);
7983
0
  data->read_more_callback = read_more_callback;
7984
0
  data->content = g_byte_array_new ();
7985
7986
0
  data->task = g_task_new (file, cancellable, callback, user_data);
7987
0
  g_task_set_source_tag (data->task, g_file_load_partial_contents_async);
7988
0
  g_task_set_task_data (data->task, data, (GDestroyNotify)load_contents_data_free);
7989
7990
0
  g_file_read_async (file,
7991
0
                     0,
7992
0
                     g_task_get_cancellable (data->task),
7993
0
                     load_contents_open_callback,
7994
0
                     data);
7995
0
}
7996
7997
/**
7998
 * g_file_load_partial_contents_finish:
7999
 * @file: input #GFile
8000
 * @res: a #GAsyncResult
8001
 * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
8002
 * @length: (out) (optional): a location to place the length of the contents of the file,
8003
 *   or %NULL if the length is not needed
8004
 * @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file,
8005
 *   or %NULL if the entity tag is not needed
8006
 * @error: a #GError, or %NULL
8007
 *
8008
 * Finishes an asynchronous partial load operation that was started
8009
 * with g_file_load_partial_contents_async(). The data is always
8010
 * zero-terminated, but this is not included in the resultant @length.
8011
 * The returned @contents should be freed with g_free() when no longer
8012
 * needed.
8013
 *
8014
 * Returns: %TRUE if the load was successful. If %FALSE and @error is
8015
 *   present, it will be set appropriately.
8016
 */
8017
gboolean
8018
g_file_load_partial_contents_finish (GFile         *file,
8019
                                     GAsyncResult  *res,
8020
                                     char         **contents,
8021
                                     gsize         *length,
8022
                                     char         **etag_out,
8023
                                     GError       **error)
8024
0
{
8025
0
  GTask *task;
8026
0
  LoadContentsData *data;
8027
8028
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
8029
0
  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
8030
0
  g_return_val_if_fail (contents != NULL, FALSE);
8031
8032
0
  task = G_TASK (res);
8033
8034
0
  if (!g_task_propagate_boolean (task, error))
8035
0
    {
8036
0
      if (length)
8037
0
        *length = 0;
8038
0
      return FALSE;
8039
0
    }
8040
8041
0
  data = g_task_get_task_data (task);
8042
8043
0
  if (length)
8044
0
    *length = data->pos;
8045
8046
0
  if (etag_out)
8047
0
    {
8048
0
      *etag_out = data->etag;
8049
0
      data->etag = NULL;
8050
0
    }
8051
8052
  /* Zero terminate */
8053
0
  g_byte_array_set_size (data->content, data->pos + 1);
8054
0
  data->content->data[data->pos] = 0;
8055
8056
0
  *contents = (char *)g_byte_array_free (data->content, FALSE);
8057
0
  data->content = NULL;
8058
8059
0
  return TRUE;
8060
0
}
8061
8062
/**
8063
 * g_file_load_contents_async:
8064
 * @file: input #GFile
8065
 * @cancellable: optional #GCancellable object, %NULL to ignore
8066
 * @callback: a #GAsyncReadyCallback to call when the request is satisfied
8067
 * @user_data: the data to pass to callback function
8068
 *
8069
 * Starts an asynchronous load of the @file's contents.
8070
 *
8071
 * For more details, see g_file_load_contents() which is
8072
 * the synchronous version of this call.
8073
 *
8074
 * When the load operation has completed, @callback will be called
8075
 * with @user data. To finish the operation, call
8076
 * g_file_load_contents_finish() with the #GAsyncResult returned by
8077
 * the @callback.
8078
 *
8079
 * If @cancellable is not %NULL, then the operation can be cancelled by
8080
 * triggering the cancellable object from another thread. If the operation
8081
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
8082
 */
8083
void
8084
g_file_load_contents_async (GFile               *file,
8085
                           GCancellable        *cancellable,
8086
                           GAsyncReadyCallback  callback,
8087
                           gpointer             user_data)
8088
0
{
8089
0
  g_file_load_partial_contents_async (file,
8090
0
                                      cancellable,
8091
0
                                      NULL,
8092
0
                                      callback, user_data);
8093
0
}
8094
8095
/**
8096
 * g_file_load_contents_finish:
8097
 * @file: input #GFile
8098
 * @res: a #GAsyncResult
8099
 * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
8100
 * @length: (out) (optional): a location to place the length of the contents of the file,
8101
 *   or %NULL if the length is not needed
8102
 * @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file,
8103
 *   or %NULL if the entity tag is not needed
8104
 * @error: a #GError, or %NULL
8105
 *
8106
 * Finishes an asynchronous load of the @file's contents.
8107
 * The contents are placed in @contents, and @length is set to the
8108
 * size of the @contents string. The @contents should be freed with
8109
 * g_free() when no longer needed. If @etag_out is present, it will be
8110
 * set to the new entity tag for the @file.
8111
 *
8112
 * Returns: %TRUE if the load was successful. If %FALSE and @error is
8113
 *   present, it will be set appropriately.
8114
 */
8115
gboolean
8116
g_file_load_contents_finish (GFile         *file,
8117
                             GAsyncResult  *res,
8118
                             char         **contents,
8119
                             gsize         *length,
8120
                             char         **etag_out,
8121
                             GError       **error)
8122
0
{
8123
0
  return g_file_load_partial_contents_finish (file,
8124
0
                                              res,
8125
0
                                              contents,
8126
0
                                              length,
8127
0
                                              etag_out,
8128
0
                                              error);
8129
0
}
8130
8131
/**
8132
 * g_file_replace_contents:
8133
 * @file: input #GFile
8134
 * @contents: (element-type guint8) (array length=length): a string containing the new contents for @file
8135
 * @length: the length of @contents in bytes
8136
 * @etag: (nullable): the old [entity-tag][gfile-etag] for the document,
8137
 *   or %NULL
8138
 * @make_backup: %TRUE if a backup should be created
8139
 * @flags: a set of #GFileCreateFlags
8140
 * @new_etag: (out) (optional) (nullable): a location to a new [entity tag][gfile-etag]
8141
 *   for the document. This should be freed with g_free() when no longer
8142
 *   needed, or %NULL
8143
 * @cancellable: optional #GCancellable object, %NULL to ignore
8144
 * @error: a #GError, or %NULL
8145
 *
8146
 * Replaces the contents of @file with @contents of @length bytes.
8147
 *
8148
 * If @etag is specified (not %NULL), any existing file must have that etag,
8149
 * or the error %G_IO_ERROR_WRONG_ETAG will be returned.
8150
 *
8151
 * If @make_backup is %TRUE, this function will attempt to make a backup
8152
 * of @file. Internally, it uses g_file_replace(), so will try to replace the
8153
 * file contents in the safest way possible. For example, atomic renames are
8154
 * used when replacing local files’ contents.
8155
 *
8156
 * If @cancellable is not %NULL, then the operation can be cancelled by
8157
 * triggering the cancellable object from another thread. If the operation
8158
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
8159
 *
8160
 * The returned @new_etag can be used to verify that the file hasn't
8161
 * changed the next time it is saved over.
8162
 *
8163
 * Returns: %TRUE if successful. If an error has occurred, this function
8164
 *   will return %FALSE and set @error appropriately if present.
8165
 */
8166
gboolean
8167
g_file_replace_contents (GFile             *file,
8168
                         const char        *contents,
8169
                         gsize              length,
8170
                         const char        *etag,
8171
                         gboolean           make_backup,
8172
                         GFileCreateFlags   flags,
8173
                         char             **new_etag,
8174
                         GCancellable      *cancellable,
8175
                         GError           **error)
8176
0
{
8177
0
  GFileOutputStream *out;
8178
0
  gsize pos, remainder;
8179
0
  gssize res = -1;
8180
0
  gboolean ret;
8181
8182
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
8183
0
  g_return_val_if_fail (contents != NULL, FALSE);
8184
8185
0
  out = g_file_replace (file, etag, make_backup, flags, cancellable, error);
8186
0
  if (out == NULL)
8187
0
    return FALSE;
8188
8189
0
  pos = 0;
8190
0
  remainder = length;
8191
0
  while (remainder > 0 &&
8192
0
         (res = g_output_stream_write (G_OUTPUT_STREAM (out),
8193
0
                                       contents + pos,
8194
0
                                       MIN (remainder, GET_CONTENT_BLOCK_SIZE),
8195
0
                                       cancellable,
8196
0
                                       error)) > 0)
8197
0
    {
8198
0
      pos += res;
8199
0
      remainder -= res;
8200
0
    }
8201
8202
0
  if (remainder > 0 && res < 0)
8203
0
    {
8204
      /* Ignore errors on close */
8205
0
      g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, NULL);
8206
0
      g_object_unref (out);
8207
8208
      /* error is set already */
8209
0
      return FALSE;
8210
0
    }
8211
8212
0
  ret = g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, error);
8213
8214
0
  if (new_etag)
8215
0
    *new_etag = g_file_output_stream_get_etag (out);
8216
8217
0
  g_object_unref (out);
8218
8219
0
  return ret;
8220
0
}
8221
8222
typedef struct {
8223
  GTask *task;
8224
  GBytes *content;
8225
  gsize pos;
8226
  char *etag;
8227
  gboolean failed;
8228
} ReplaceContentsData;
8229
8230
static void
8231
replace_contents_data_free (ReplaceContentsData *data)
8232
0
{
8233
0
  g_bytes_unref (data->content);
8234
0
  g_free (data->etag);
8235
0
  g_free (data);
8236
0
}
8237
8238
static void
8239
replace_contents_close_callback (GObject      *obj,
8240
                                 GAsyncResult *close_res,
8241
                                 gpointer      user_data)
8242
0
{
8243
0
  GOutputStream *stream = G_OUTPUT_STREAM (obj);
8244
0
  ReplaceContentsData *data = user_data;
8245
8246
  /* Ignore errors here, we're only reading anyway */
8247
0
  g_output_stream_close_finish (stream, close_res, NULL);
8248
8249
0
  if (!data->failed)
8250
0
    {
8251
0
      data->etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (stream));
8252
0
      g_task_return_boolean (data->task, TRUE);
8253
0
    }
8254
0
  g_object_unref (data->task);
8255
0
}
8256
8257
static void
8258
replace_contents_write_callback (GObject      *obj,
8259
                                 GAsyncResult *read_res,
8260
                                 gpointer      user_data)
8261
0
{
8262
0
  GOutputStream *stream = G_OUTPUT_STREAM (obj);
8263
0
  ReplaceContentsData *data = user_data;
8264
0
  GError *error = NULL;
8265
0
  gssize write_size;
8266
8267
0
  write_size = g_output_stream_write_finish (stream, read_res, &error);
8268
8269
0
  if (write_size <= 0)
8270
0
    {
8271
      /* Error or EOF, close the file */
8272
0
      if (write_size < 0)
8273
0
        {
8274
0
          data->failed = TRUE;
8275
0
          g_task_return_error (data->task, error);
8276
0
        }
8277
0
      g_output_stream_close_async (stream, 0,
8278
0
                                   g_task_get_cancellable (data->task),
8279
0
                                   replace_contents_close_callback, data);
8280
0
    }
8281
0
  else if (write_size > 0)
8282
0
    {
8283
0
      const gchar *content;
8284
0
      gsize length;
8285
8286
0
      content = g_bytes_get_data (data->content, &length);
8287
0
      data->pos += write_size;
8288
8289
0
      if (data->pos >= length)
8290
0
        g_output_stream_close_async (stream, 0,
8291
0
                                     g_task_get_cancellable (data->task),
8292
0
                                     replace_contents_close_callback, data);
8293
0
      else
8294
0
        g_output_stream_write_async (stream,
8295
0
                                     content + data->pos,
8296
0
                                     length - data->pos,
8297
0
                                     0,
8298
0
                                     g_task_get_cancellable (data->task),
8299
0
                                     replace_contents_write_callback,
8300
0
                                     data);
8301
0
    }
8302
0
}
8303
8304
static void
8305
replace_contents_open_callback (GObject      *obj,
8306
                                GAsyncResult *open_res,
8307
                                gpointer      user_data)
8308
0
{
8309
0
  GFile *file = G_FILE (obj);
8310
0
  GFileOutputStream *stream;
8311
0
  ReplaceContentsData *data = user_data;
8312
0
  GError *error = NULL;
8313
8314
0
  stream = g_file_replace_finish (file, open_res, &error);
8315
8316
0
  if (stream)
8317
0
    {
8318
0
      const gchar *content;
8319
0
      gsize length;
8320
8321
0
      content = g_bytes_get_data (data->content, &length);
8322
0
      g_output_stream_write_async (G_OUTPUT_STREAM (stream),
8323
0
                                   content + data->pos,
8324
0
                                   length - data->pos,
8325
0
                                   0,
8326
0
                                   g_task_get_cancellable (data->task),
8327
0
                                   replace_contents_write_callback,
8328
0
                                   data);
8329
0
      g_object_unref (stream);  /* ownership is transferred to the write_async() call above */
8330
0
    }
8331
0
  else
8332
0
    {
8333
0
      g_task_return_error (data->task, error);
8334
0
      g_object_unref (data->task);
8335
0
    }
8336
0
}
8337
8338
/**
8339
 * g_file_replace_contents_async:
8340
 * @file: input #GFile
8341
 * @contents: (element-type guint8) (array length=length): string of contents to replace the file with
8342
 * @length: the length of @contents in bytes
8343
 * @etag: (nullable): a new [entity tag][gfile-etag] for the @file, or %NULL
8344
 * @make_backup: %TRUE if a backup should be created
8345
 * @flags: a set of #GFileCreateFlags
8346
 * @cancellable: optional #GCancellable object, %NULL to ignore
8347
 * @callback: a #GAsyncReadyCallback to call when the request is satisfied
8348
 * @user_data: the data to pass to callback function
8349
 *
8350
 * Starts an asynchronous replacement of @file with the given
8351
 * @contents of @length bytes. @etag will replace the document's
8352
 * current entity tag.
8353
 *
8354
 * When this operation has completed, @callback will be called with
8355
 * @user_user data, and the operation can be finalized with
8356
 * g_file_replace_contents_finish().
8357
 *
8358
 * If @cancellable is not %NULL, then the operation can be cancelled by
8359
 * triggering the cancellable object from another thread. If the operation
8360
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
8361
 *
8362
 * If @make_backup is %TRUE, this function will attempt to
8363
 * make a backup of @file.
8364
 *
8365
 * Note that no copy of @contents will be made, so it must stay valid
8366
 * until @callback is called. See g_file_replace_contents_bytes_async()
8367
 * for a #GBytes version that will automatically hold a reference to the
8368
 * contents (without copying) for the duration of the call.
8369
 */
8370
void
8371
g_file_replace_contents_async  (GFile               *file,
8372
                                const char          *contents,
8373
                                gsize                length,
8374
                                const char          *etag,
8375
                                gboolean             make_backup,
8376
                                GFileCreateFlags     flags,
8377
                                GCancellable        *cancellable,
8378
                                GAsyncReadyCallback  callback,
8379
                                gpointer             user_data)
8380
0
{
8381
0
  GBytes *bytes;
8382
8383
0
  bytes = g_bytes_new_static (contents, length);
8384
0
  g_file_replace_contents_bytes_async (file, bytes, etag, make_backup, flags,
8385
0
      cancellable, callback, user_data);
8386
0
  g_bytes_unref (bytes);
8387
0
}
8388
8389
/**
8390
 * g_file_replace_contents_bytes_async:
8391
 * @file: input #GFile
8392
 * @contents: a #GBytes
8393
 * @etag: (nullable): a new [entity tag][gfile-etag] for the @file, or %NULL
8394
 * @make_backup: %TRUE if a backup should be created
8395
 * @flags: a set of #GFileCreateFlags
8396
 * @cancellable: optional #GCancellable object, %NULL to ignore
8397
 * @callback: a #GAsyncReadyCallback to call when the request is satisfied
8398
 * @user_data: the data to pass to callback function
8399
 *
8400
 * Same as g_file_replace_contents_async() but takes a #GBytes input instead.
8401
 * This function will keep a ref on @contents until the operation is done.
8402
 * Unlike g_file_replace_contents_async() this allows forgetting about the
8403
 * content without waiting for the callback.
8404
 *
8405
 * When this operation has completed, @callback will be called with
8406
 * @user_user data, and the operation can be finalized with
8407
 * g_file_replace_contents_finish().
8408
 *
8409
 * Since: 2.40
8410
 */
8411
void
8412
g_file_replace_contents_bytes_async  (GFile               *file,
8413
                                      GBytes              *contents,
8414
                                      const char          *etag,
8415
                                      gboolean             make_backup,
8416
                                      GFileCreateFlags     flags,
8417
                                      GCancellable        *cancellable,
8418
                                      GAsyncReadyCallback  callback,
8419
                                      gpointer             user_data)
8420
0
{
8421
0
  ReplaceContentsData *data;
8422
8423
0
  g_return_if_fail (G_IS_FILE (file));
8424
0
  g_return_if_fail (contents != NULL);
8425
8426
0
  data = g_new0 (ReplaceContentsData, 1);
8427
8428
0
  data->content = g_bytes_ref (contents);
8429
8430
0
  data->task = g_task_new (file, cancellable, callback, user_data);
8431
0
  g_task_set_source_tag (data->task, g_file_replace_contents_bytes_async);
8432
0
  g_task_set_task_data (data->task, data, (GDestroyNotify)replace_contents_data_free);
8433
8434
0
  g_file_replace_async (file,
8435
0
                        etag,
8436
0
                        make_backup,
8437
0
                        flags,
8438
0
                        0,
8439
0
                        g_task_get_cancellable (data->task),
8440
0
                        replace_contents_open_callback,
8441
0
                        data);
8442
0
}
8443
8444
/**
8445
 * g_file_replace_contents_finish:
8446
 * @file: input #GFile
8447
 * @res: a #GAsyncResult
8448
 * @new_etag: (out) (optional) (nullable): a location of a new [entity tag][gfile-etag]
8449
 *   for the document. This should be freed with g_free() when it is no
8450
 *   longer needed, or %NULL
8451
 * @error: a #GError, or %NULL
8452
 *
8453
 * Finishes an asynchronous replace of the given @file. See
8454
 * g_file_replace_contents_async(). Sets @new_etag to the new entity
8455
 * tag for the document, if present.
8456
 *
8457
 * Returns: %TRUE on success, %FALSE on failure.
8458
 */
8459
gboolean
8460
g_file_replace_contents_finish (GFile         *file,
8461
                                GAsyncResult  *res,
8462
                                char         **new_etag,
8463
                                GError       **error)
8464
0
{
8465
0
  GTask *task;
8466
0
  ReplaceContentsData *data;
8467
8468
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
8469
0
  g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
8470
8471
0
  task = G_TASK (res);
8472
8473
0
  if (!g_task_propagate_boolean (task, error))
8474
0
    return FALSE;
8475
8476
0
  data = g_task_get_task_data (task);
8477
8478
0
  if (new_etag)
8479
0
    {
8480
0
      *new_etag = data->etag;
8481
0
      data->etag = NULL; /* Take ownership */
8482
0
    }
8483
8484
0
  return TRUE;
8485
0
}
8486
8487
gboolean
8488
g_file_real_measure_disk_usage (GFile                         *file,
8489
                                GFileMeasureFlags              flags,
8490
                                GCancellable                  *cancellable,
8491
                                GFileMeasureProgressCallback   progress_callback,
8492
                                gpointer                       progress_data,
8493
                                guint64                       *disk_usage,
8494
                                guint64                       *num_dirs,
8495
                                guint64                       *num_files,
8496
                                GError                       **error)
8497
0
{
8498
0
  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
8499
0
                       "Operation not supported for the current backend.");
8500
0
  return FALSE;
8501
0
}
8502
8503
typedef struct
8504
{
8505
  GFileMeasureFlags             flags;
8506
  GFileMeasureProgressCallback  progress_callback;
8507
  gpointer                      progress_data;
8508
} MeasureTaskData;
8509
8510
typedef struct
8511
{
8512
  guint64 disk_usage;
8513
  guint64 num_dirs;
8514
  guint64 num_files;
8515
} MeasureResult;
8516
8517
typedef struct
8518
{
8519
  GFileMeasureProgressCallback callback;
8520
  gpointer                     user_data;
8521
  gboolean                     reporting;
8522
  guint64                      current_size;
8523
  guint64                      num_dirs;
8524
  guint64                      num_files;
8525
} MeasureProgress;
8526
8527
static gboolean
8528
measure_disk_usage_invoke_progress (gpointer user_data)
8529
0
{
8530
0
  MeasureProgress *progress = user_data;
8531
8532
0
  (* progress->callback) (progress->reporting,
8533
0
                          progress->current_size, progress->num_dirs, progress->num_files,
8534
0
                          progress->user_data);
8535
8536
0
  return FALSE;
8537
0
}
8538
8539
static void
8540
measure_disk_usage_progress (gboolean reporting,
8541
                             guint64  current_size,
8542
                             guint64  num_dirs,
8543
                             guint64  num_files,
8544
                             gpointer user_data)
8545
0
{
8546
0
  MeasureProgress progress;
8547
0
  GTask *task = user_data;
8548
0
  MeasureTaskData *data;
8549
8550
0
  data = g_task_get_task_data (task);
8551
8552
0
  progress.callback = data->progress_callback;
8553
0
  progress.user_data = data->progress_data;
8554
0
  progress.reporting = reporting;
8555
0
  progress.current_size = current_size;
8556
0
  progress.num_dirs = num_dirs;
8557
0
  progress.num_files = num_files;
8558
8559
0
  g_main_context_invoke_full (g_task_get_context (task),
8560
0
                              g_task_get_priority (task),
8561
0
                              measure_disk_usage_invoke_progress,
8562
0
                              g_memdup2 (&progress, sizeof progress),
8563
0
                              g_free);
8564
0
}
8565
8566
static void
8567
measure_disk_usage_thread (GTask        *task,
8568
                           gpointer      source_object,
8569
                           gpointer      task_data,
8570
                           GCancellable *cancellable)
8571
0
{
8572
0
  MeasureTaskData *data = task_data;
8573
0
  GError *error = NULL;
8574
0
  MeasureResult result = { 0, };
8575
8576
0
  if (g_file_measure_disk_usage (source_object, data->flags, cancellable,
8577
0
                                 data->progress_callback ? measure_disk_usage_progress : NULL, task,
8578
0
                                 &result.disk_usage, &result.num_dirs, &result.num_files,
8579
0
                                 &error))
8580
0
    g_task_return_pointer (task, g_memdup2 (&result, sizeof result), g_free);
8581
0
  else
8582
0
    g_task_return_error (task, error);
8583
0
}
8584
8585
static void
8586
g_file_real_measure_disk_usage_async (GFile                        *file,
8587
                                      GFileMeasureFlags             flags,
8588
                                      gint                          io_priority,
8589
                                      GCancellable                 *cancellable,
8590
                                      GFileMeasureProgressCallback  progress_callback,
8591
                                      gpointer                      progress_data,
8592
                                      GAsyncReadyCallback           callback,
8593
                                      gpointer                      user_data)
8594
0
{
8595
0
  MeasureTaskData data;
8596
0
  GTask *task;
8597
8598
0
  data.flags = flags;
8599
0
  data.progress_callback = progress_callback;
8600
0
  data.progress_data = progress_data;
8601
8602
0
  task = g_task_new (file, cancellable, callback, user_data);
8603
0
  g_task_set_source_tag (task, g_file_real_measure_disk_usage_async);
8604
0
  g_task_set_task_data (task, g_memdup2 (&data, sizeof data), g_free);
8605
0
  g_task_set_priority (task, io_priority);
8606
8607
0
  g_task_run_in_thread (task, measure_disk_usage_thread);
8608
0
  g_object_unref (task);
8609
0
}
8610
8611
static gboolean
8612
g_file_real_measure_disk_usage_finish (GFile         *file,
8613
                                       GAsyncResult  *result,
8614
                                       guint64       *disk_usage,
8615
                                       guint64       *num_dirs,
8616
                                       guint64       *num_files,
8617
                                       GError       **error)
8618
0
{
8619
0
  MeasureResult *measure_result;
8620
8621
0
  g_return_val_if_fail (g_task_is_valid (result, file), FALSE);
8622
8623
0
  measure_result = g_task_propagate_pointer (G_TASK (result), error);
8624
8625
0
  if (measure_result == NULL)
8626
0
    return FALSE;
8627
8628
0
  if (disk_usage)
8629
0
    *disk_usage = measure_result->disk_usage;
8630
8631
0
  if (num_dirs)
8632
0
    *num_dirs = measure_result->num_dirs;
8633
8634
0
  if (num_files)
8635
0
    *num_files = measure_result->num_files;
8636
8637
0
  g_free (measure_result);
8638
8639
0
  return TRUE;
8640
0
}
8641
8642
/**
8643
 * g_file_measure_disk_usage:
8644
 * @file: a #GFile
8645
 * @flags: #GFileMeasureFlags
8646
 * @cancellable: (nullable): optional #GCancellable
8647
 * @progress_callback: (nullable): a #GFileMeasureProgressCallback
8648
 * @progress_data: user_data for @progress_callback
8649
 * @disk_usage: (out) (optional): the number of bytes of disk space used
8650
 * @num_dirs: (out) (optional): the number of directories encountered
8651
 * @num_files: (out) (optional): the number of non-directories encountered
8652
 * @error: (nullable): %NULL, or a pointer to a %NULL #GError pointer
8653
 *
8654
 * Recursively measures the disk usage of @file.
8655
 *
8656
 * This is essentially an analog of the 'du' command, but it also
8657
 * reports the number of directories and non-directory files encountered
8658
 * (including things like symbolic links).
8659
 *
8660
 * By default, errors are only reported against the toplevel file
8661
 * itself.  Errors found while recursing are silently ignored, unless
8662
 * %G_FILE_MEASURE_REPORT_ANY_ERROR is given in @flags.
8663
 *
8664
 * The returned size, @disk_usage, is in bytes and should be formatted
8665
 * with g_format_size() in order to get something reasonable for showing
8666
 * in a user interface.
8667
 *
8668
 * @progress_callback and @progress_data can be given to request
8669
 * periodic progress updates while scanning.  See the documentation for
8670
 * #GFileMeasureProgressCallback for information about when and how the
8671
 * callback will be invoked.
8672
 *
8673
 * Returns: %TRUE if successful, with the out parameters set.
8674
 *   %FALSE otherwise, with @error set.
8675
 *
8676
 * Since: 2.38
8677
 **/
8678
gboolean
8679
g_file_measure_disk_usage (GFile                         *file,
8680
                           GFileMeasureFlags              flags,
8681
                           GCancellable                  *cancellable,
8682
                           GFileMeasureProgressCallback   progress_callback,
8683
                           gpointer                       progress_data,
8684
                           guint64                       *disk_usage,
8685
                           guint64                       *num_dirs,
8686
                           guint64                       *num_files,
8687
                           GError                       **error)
8688
0
{
8689
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
8690
0
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
8691
0
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
8692
8693
0
  return G_FILE_GET_IFACE (file)->measure_disk_usage (file, flags, cancellable,
8694
0
                                                      progress_callback, progress_data,
8695
0
                                                      disk_usage, num_dirs, num_files,
8696
0
                                                      error);
8697
0
}
8698
8699
/**
8700
 * g_file_measure_disk_usage_async:
8701
 * @file: a #GFile
8702
 * @flags: #GFileMeasureFlags
8703
 * @io_priority: the [I/O priority][io-priority] of the request
8704
 * @cancellable: (nullable): optional #GCancellable
8705
 * @progress_callback: (nullable): a #GFileMeasureProgressCallback
8706
 * @progress_data: user_data for @progress_callback
8707
 * @callback: (nullable): a #GAsyncReadyCallback to call when complete
8708
 * @user_data: the data to pass to callback function
8709
 *
8710
 * Recursively measures the disk usage of @file.
8711
 *
8712
 * This is the asynchronous version of g_file_measure_disk_usage().  See
8713
 * there for more information.
8714
 *
8715
 * Since: 2.38
8716
 **/
8717
void
8718
g_file_measure_disk_usage_async (GFile                        *file,
8719
                                 GFileMeasureFlags             flags,
8720
                                 gint                          io_priority,
8721
                                 GCancellable                 *cancellable,
8722
                                 GFileMeasureProgressCallback  progress_callback,
8723
                                 gpointer                      progress_data,
8724
                                 GAsyncReadyCallback           callback,
8725
                                 gpointer                      user_data)
8726
0
{
8727
0
  g_return_if_fail (G_IS_FILE (file));
8728
0
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
8729
8730
0
  G_FILE_GET_IFACE (file)->measure_disk_usage_async (file, flags, io_priority, cancellable,
8731
0
                                                     progress_callback, progress_data,
8732
0
                                                     callback, user_data);
8733
0
}
8734
8735
/**
8736
 * g_file_measure_disk_usage_finish:
8737
 * @file: a #GFile
8738
 * @result: the #GAsyncResult passed to your #GAsyncReadyCallback
8739
 * @disk_usage: (out) (optional): the number of bytes of disk space used
8740
 * @num_dirs: (out) (optional): the number of directories encountered
8741
 * @num_files: (out) (optional): the number of non-directories encountered
8742
 * @error: (nullable): %NULL, or a pointer to a %NULL #GError pointer
8743
 *
8744
 * Collects the results from an earlier call to
8745
 * g_file_measure_disk_usage_async().  See g_file_measure_disk_usage() for
8746
 * more information.
8747
 *
8748
 * Returns: %TRUE if successful, with the out parameters set.
8749
 *   %FALSE otherwise, with @error set.
8750
 *
8751
 * Since: 2.38
8752
 **/
8753
gboolean
8754
g_file_measure_disk_usage_finish (GFile         *file,
8755
                                  GAsyncResult  *result,
8756
                                  guint64       *disk_usage,
8757
                                  guint64       *num_dirs,
8758
                                  guint64       *num_files,
8759
                                  GError       **error)
8760
0
{
8761
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
8762
0
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
8763
8764
0
  return G_FILE_GET_IFACE (file)->measure_disk_usage_finish (file, result, disk_usage, num_dirs, num_files, error);
8765
0
}
8766
8767
/**
8768
 * g_file_start_mountable:
8769
 * @file: input #GFile
8770
 * @flags: flags affecting the operation
8771
 * @start_operation: (nullable): a #GMountOperation, or %NULL to avoid user interaction
8772
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
8773
 * @callback: (nullable): a #GAsyncReadyCallback to call when the request is satisfied, or %NULL
8774
 * @user_data: the data to pass to callback function
8775
 *
8776
 * Starts a file of type %G_FILE_TYPE_MOUNTABLE.
8777
 * Using @start_operation, you can request callbacks when, for instance,
8778
 * passwords are needed during authentication.
8779
 *
8780
 * If @cancellable is not %NULL, then the operation can be cancelled by
8781
 * triggering the cancellable object from another thread. If the operation
8782
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
8783
 *
8784
 * When the operation is finished, @callback will be called.
8785
 * You can then call g_file_mount_mountable_finish() to get
8786
 * the result of the operation.
8787
 *
8788
 * Since: 2.22
8789
 */
8790
void
8791
g_file_start_mountable (GFile               *file,
8792
                        GDriveStartFlags     flags,
8793
                        GMountOperation     *start_operation,
8794
                        GCancellable        *cancellable,
8795
                        GAsyncReadyCallback  callback,
8796
                        gpointer             user_data)
8797
0
{
8798
0
  GFileIface *iface;
8799
8800
0
  g_return_if_fail (G_IS_FILE (file));
8801
8802
0
  iface = G_FILE_GET_IFACE (file);
8803
8804
0
  if (iface->start_mountable == NULL)
8805
0
    {
8806
0
      g_task_report_new_error (file, callback, user_data,
8807
0
                               g_file_start_mountable,
8808
0
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
8809
0
                               _("Operation not supported"));
8810
0
      return;
8811
0
    }
8812
8813
0
  (* iface->start_mountable) (file,
8814
0
                              flags,
8815
0
                              start_operation,
8816
0
                              cancellable,
8817
0
                              callback,
8818
0
                              user_data);
8819
0
}
8820
8821
/**
8822
 * g_file_start_mountable_finish:
8823
 * @file: input #GFile
8824
 * @result: a #GAsyncResult
8825
 * @error: a #GError, or %NULL
8826
 *
8827
 * Finishes a start operation. See g_file_start_mountable() for details.
8828
 *
8829
 * Finish an asynchronous start operation that was started
8830
 * with g_file_start_mountable().
8831
 *
8832
 * Returns: %TRUE if the operation finished successfully. %FALSE
8833
 * otherwise.
8834
 *
8835
 * Since: 2.22
8836
 */
8837
gboolean
8838
g_file_start_mountable_finish (GFile         *file,
8839
                               GAsyncResult  *result,
8840
                               GError       **error)
8841
0
{
8842
0
  GFileIface *iface;
8843
8844
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
8845
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
8846
8847
0
  if (g_async_result_legacy_propagate_error (result, error))
8848
0
    return FALSE;
8849
0
  else if (g_async_result_is_tagged (result, g_file_start_mountable))
8850
0
    return g_task_propagate_boolean (G_TASK (result), error);
8851
8852
0
  iface = G_FILE_GET_IFACE (file);
8853
0
  return (* iface->start_mountable_finish) (file, result, error);
8854
0
}
8855
8856
/**
8857
 * g_file_stop_mountable:
8858
 * @file: input #GFile
8859
 * @flags: flags affecting the operation
8860
 * @mount_operation: (nullable): a #GMountOperation,
8861
 *   or %NULL to avoid user interaction.
8862
 * @cancellable: (nullable): optional #GCancellable object,
8863
 *   %NULL to ignore
8864
 * @callback: (nullable): a #GAsyncReadyCallback to call
8865
 *   when the request is satisfied, or %NULL
8866
 * @user_data: the data to pass to callback function
8867
 *
8868
 * Stops a file of type %G_FILE_TYPE_MOUNTABLE.
8869
 *
8870
 * If @cancellable is not %NULL, then the operation can be cancelled by
8871
 * triggering the cancellable object from another thread. If the operation
8872
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
8873
 *
8874
 * When the operation is finished, @callback will be called.
8875
 * You can then call g_file_stop_mountable_finish() to get
8876
 * the result of the operation.
8877
 *
8878
 * Since: 2.22
8879
 */
8880
void
8881
g_file_stop_mountable (GFile               *file,
8882
                       GMountUnmountFlags   flags,
8883
                       GMountOperation     *mount_operation,
8884
                       GCancellable        *cancellable,
8885
                       GAsyncReadyCallback  callback,
8886
                       gpointer             user_data)
8887
0
{
8888
0
  GFileIface *iface;
8889
8890
0
  g_return_if_fail (G_IS_FILE (file));
8891
8892
0
  iface = G_FILE_GET_IFACE (file);
8893
8894
0
  if (iface->stop_mountable == NULL)
8895
0
    {
8896
0
      g_task_report_new_error (file, callback, user_data,
8897
0
                               g_file_stop_mountable,
8898
0
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
8899
0
                               _("Operation not supported"));
8900
0
      return;
8901
0
    }
8902
8903
0
  (* iface->stop_mountable) (file,
8904
0
                             flags,
8905
0
                             mount_operation,
8906
0
                             cancellable,
8907
0
                             callback,
8908
0
                             user_data);
8909
0
}
8910
8911
/**
8912
 * g_file_stop_mountable_finish:
8913
 * @file: input #GFile
8914
 * @result: a #GAsyncResult
8915
 * @error: a #GError, or %NULL
8916
 *
8917
 * Finishes a stop operation, see g_file_stop_mountable() for details.
8918
 *
8919
 * Finish an asynchronous stop operation that was started
8920
 * with g_file_stop_mountable().
8921
 *
8922
 * Returns: %TRUE if the operation finished successfully.
8923
 *   %FALSE otherwise.
8924
 *
8925
 * Since: 2.22
8926
 */
8927
gboolean
8928
g_file_stop_mountable_finish (GFile         *file,
8929
                              GAsyncResult  *result,
8930
                              GError       **error)
8931
0
{
8932
0
  GFileIface *iface;
8933
8934
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
8935
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
8936
8937
0
  if (g_async_result_legacy_propagate_error (result, error))
8938
0
    return FALSE;
8939
0
  else if (g_async_result_is_tagged (result, g_file_stop_mountable))
8940
0
    return g_task_propagate_boolean (G_TASK (result), error);
8941
8942
0
  iface = G_FILE_GET_IFACE (file);
8943
0
  return (* iface->stop_mountable_finish) (file, result, error);
8944
0
}
8945
8946
/**
8947
 * g_file_poll_mountable:
8948
 * @file: input #GFile
8949
 * @cancellable: optional #GCancellable object, %NULL to ignore
8950
 * @callback: (nullable): a #GAsyncReadyCallback to call
8951
 *   when the request is satisfied, or %NULL
8952
 * @user_data: the data to pass to callback function
8953
 *
8954
 * Polls a file of type %G_FILE_TYPE_MOUNTABLE.
8955
 *
8956
 * If @cancellable is not %NULL, then the operation can be cancelled by
8957
 * triggering the cancellable object from another thread. If the operation
8958
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
8959
 *
8960
 * When the operation is finished, @callback will be called.
8961
 * You can then call g_file_mount_mountable_finish() to get
8962
 * the result of the operation.
8963
 *
8964
 * Since: 2.22
8965
 */
8966
void
8967
g_file_poll_mountable (GFile               *file,
8968
                       GCancellable        *cancellable,
8969
                       GAsyncReadyCallback  callback,
8970
                       gpointer             user_data)
8971
0
{
8972
0
  GFileIface *iface;
8973
8974
0
  g_return_if_fail (G_IS_FILE (file));
8975
8976
0
  iface = G_FILE_GET_IFACE (file);
8977
8978
0
  if (iface->poll_mountable == NULL)
8979
0
    {
8980
0
      g_task_report_new_error (file, callback, user_data,
8981
0
                               g_file_poll_mountable,
8982
0
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
8983
0
                               _("Operation not supported"));
8984
0
      return;
8985
0
    }
8986
8987
0
  (* iface->poll_mountable) (file,
8988
0
                             cancellable,
8989
0
                             callback,
8990
0
                             user_data);
8991
0
}
8992
8993
/**
8994
 * g_file_poll_mountable_finish:
8995
 * @file: input #GFile
8996
 * @result: a #GAsyncResult
8997
 * @error: a #GError, or %NULL
8998
 *
8999
 * Finishes a poll operation. See g_file_poll_mountable() for details.
9000
 *
9001
 * Finish an asynchronous poll operation that was polled
9002
 * with g_file_poll_mountable().
9003
 *
9004
 * Returns: %TRUE if the operation finished successfully. %FALSE
9005
 * otherwise.
9006
 *
9007
 * Since: 2.22
9008
 */
9009
gboolean
9010
g_file_poll_mountable_finish (GFile         *file,
9011
                              GAsyncResult  *result,
9012
                              GError       **error)
9013
0
{
9014
0
  GFileIface *iface;
9015
9016
0
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
9017
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
9018
9019
0
  if (g_async_result_legacy_propagate_error (result, error))
9020
0
    return FALSE;
9021
0
  else if (g_async_result_is_tagged (result, g_file_poll_mountable))
9022
0
    return g_task_propagate_boolean (G_TASK (result), error);
9023
9024
0
  iface = G_FILE_GET_IFACE (file);
9025
0
  return (* iface->poll_mountable_finish) (file, result, error);
9026
0
}
9027
9028
/**
9029
 * g_file_supports_thread_contexts:
9030
 * @file: a #GFile
9031
 *
9032
 * Checks if @file supports
9033
 * [thread-default contexts][g-main-context-push-thread-default-context].
9034
 * If this returns %FALSE, you cannot perform asynchronous operations on
9035
 * @file in a thread that has a thread-default context.
9036
 *
9037
 * Returns: Whether or not @file supports thread-default contexts.
9038
 *
9039
 * Since: 2.22
9040
 */
9041
gboolean
9042
g_file_supports_thread_contexts (GFile *file)
9043
0
{
9044
0
 GFileIface *iface;
9045
9046
0
 g_return_val_if_fail (G_IS_FILE (file), FALSE);
9047
9048
0
 iface = G_FILE_GET_IFACE (file);
9049
0
 return iface->supports_thread_contexts;
9050
0
}
9051
9052
/**
9053
 * g_file_load_bytes:
9054
 * @file: a #GFile
9055
 * @cancellable: (nullable): a #GCancellable or %NULL
9056
 * @etag_out: (out) (nullable) (optional): a location to place the current
9057
 *   entity tag for the file, or %NULL if the entity tag is not needed
9058
 * @error: a location for a #GError or %NULL
9059
 *
9060
 * Loads the contents of @file and returns it as #GBytes.
9061
 *
9062
 * If @file is a resource:// based URI, the resulting bytes will reference the
9063
 * embedded resource instead of a copy. Otherwise, this is equivalent to calling
9064
 * g_file_load_contents() and g_bytes_new_take().
9065
 *
9066
 * For resources, @etag_out will be set to %NULL.
9067
 *
9068
 * The data contained in the resulting #GBytes is always zero-terminated, but
9069
 * this is not included in the #GBytes length. The resulting #GBytes should be
9070
 * freed with g_bytes_unref() when no longer in use.
9071
 *
9072
 * Returns: (transfer full): a #GBytes or %NULL and @error is set
9073
 *
9074
 * Since: 2.56
9075
 */
9076
GBytes *
9077
g_file_load_bytes (GFile         *file,
9078
                   GCancellable  *cancellable,
9079
                   gchar        **etag_out,
9080
                   GError       **error)
9081
0
{
9082
0
  gchar *contents;
9083
0
  gsize len;
9084
9085
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
9086
0
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
9087
0
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
9088
9089
0
  if (etag_out != NULL)
9090
0
    *etag_out = NULL;
9091
9092
0
  if (g_file_has_uri_scheme (file, "resource"))
9093
0
    {
9094
0
      GBytes *bytes;
9095
0
      gchar *uri, *unescaped;
9096
9097
0
      uri = g_file_get_uri (file);
9098
0
      unescaped = g_uri_unescape_string (uri + strlen ("resource://"), NULL);
9099
0
      g_free (uri);
9100
9101
0
      bytes = g_resources_lookup_data (unescaped, G_RESOURCE_LOOKUP_FLAGS_NONE, error);
9102
0
      g_free (unescaped);
9103
9104
0
      return bytes;
9105
0
    }
9106
9107
  /* contents is guaranteed to be \0 terminated */
9108
0
  if (g_file_load_contents (file, cancellable, &contents, &len, etag_out, error))
9109
0
    return g_bytes_new_take (g_steal_pointer (&contents), len);
9110
9111
0
  return NULL;
9112
0
}
9113
9114
static void
9115
g_file_load_bytes_cb (GObject      *object,
9116
                      GAsyncResult *result,
9117
                      gpointer      user_data)
9118
0
{
9119
0
  GFile *file = G_FILE (object);
9120
0
  GTask *task = user_data;
9121
0
  GError *error = NULL;
9122
0
  gchar *etag = NULL;
9123
0
  gchar *contents = NULL;
9124
0
  gsize len = 0;
9125
9126
0
  g_file_load_contents_finish (file, result, &contents, &len, &etag, &error);
9127
0
  g_task_set_task_data (task, g_steal_pointer (&etag), g_free);
9128
9129
0
  if (error != NULL)
9130
0
    g_task_return_error (task, g_steal_pointer (&error));
9131
0
  else
9132
0
    g_task_return_pointer (task,
9133
0
                           g_bytes_new_take (g_steal_pointer (&contents), len),
9134
0
                           (GDestroyNotify)g_bytes_unref);
9135
9136
0
  g_object_unref (task);
9137
0
}
9138
9139
/**
9140
 * g_file_load_bytes_async:
9141
 * @file: a #GFile
9142
 * @cancellable: (nullable): a #GCancellable or %NULL
9143
 * @callback: (scope async): a #GAsyncReadyCallback to call when the
9144
 *   request is satisfied
9145
 * @user_data: (closure): the data to pass to callback function
9146
 *
9147
 * Asynchronously loads the contents of @file as #GBytes.
9148
 *
9149
 * If @file is a resource:// based URI, the resulting bytes will reference the
9150
 * embedded resource instead of a copy. Otherwise, this is equivalent to calling
9151
 * g_file_load_contents_async() and g_bytes_new_take().
9152
 *
9153
 * @callback should call g_file_load_bytes_finish() to get the result of this
9154
 * asynchronous operation.
9155
 *
9156
 * See g_file_load_bytes() for more information.
9157
 *
9158
 * Since: 2.56
9159
 */
9160
void
9161
g_file_load_bytes_async (GFile               *file,
9162
                         GCancellable        *cancellable,
9163
                         GAsyncReadyCallback  callback,
9164
                         gpointer             user_data)
9165
0
{
9166
0
  GError *error = NULL;
9167
0
  GBytes *bytes;
9168
0
  GTask *task;
9169
9170
0
  g_return_if_fail (G_IS_FILE (file));
9171
0
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
9172
9173
0
  task = g_task_new (file, cancellable, callback, user_data);
9174
0
  g_task_set_source_tag (task, g_file_load_bytes_async);
9175
9176
0
  if (!g_file_has_uri_scheme (file, "resource"))
9177
0
    {
9178
0
      g_file_load_contents_async (file,
9179
0
                                  cancellable,
9180
0
                                  g_file_load_bytes_cb,
9181
0
                                  g_steal_pointer (&task));
9182
0
      return;
9183
0
    }
9184
9185
0
  bytes = g_file_load_bytes (file, cancellable, NULL, &error);
9186
9187
0
  if (bytes == NULL)
9188
0
    g_task_return_error (task, g_steal_pointer (&error));
9189
0
  else
9190
0
    g_task_return_pointer (task,
9191
0
                           g_steal_pointer (&bytes),
9192
0
                           (GDestroyNotify)g_bytes_unref);
9193
9194
0
  g_object_unref (task);
9195
0
}
9196
9197
/**
9198
 * g_file_load_bytes_finish:
9199
 * @file: a #GFile
9200
 * @result: a #GAsyncResult provided to the callback
9201
 * @etag_out: (out) (nullable) (optional): a location to place the current
9202
 *   entity tag for the file, or %NULL if the entity tag is not needed
9203
 * @error: a location for a #GError, or %NULL
9204
 *
9205
 * Completes an asynchronous request to g_file_load_bytes_async().
9206
 *
9207
 * For resources, @etag_out will be set to %NULL.
9208
 *
9209
 * The data contained in the resulting #GBytes is always zero-terminated, but
9210
 * this is not included in the #GBytes length. The resulting #GBytes should be
9211
 * freed with g_bytes_unref() when no longer in use.
9212
 *
9213
 * See g_file_load_bytes() for more information.
9214
 *
9215
 * Returns: (transfer full): a #GBytes or %NULL and @error is set
9216
 *
9217
 * Since: 2.56
9218
 */
9219
GBytes *
9220
g_file_load_bytes_finish (GFile         *file,
9221
                          GAsyncResult  *result,
9222
                          gchar        **etag_out,
9223
                          GError       **error)
9224
0
{
9225
0
  GBytes *bytes;
9226
9227
0
  g_return_val_if_fail (G_IS_FILE (file), NULL);
9228
0
  g_return_val_if_fail (G_IS_TASK (result), NULL);
9229
0
  g_return_val_if_fail (g_task_is_valid (G_TASK (result), file), NULL);
9230
0
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
9231
9232
0
  bytes = g_task_propagate_pointer (G_TASK (result), error);
9233
9234
0
  if (etag_out != NULL)
9235
0
    *etag_out = g_strdup (g_task_get_task_data (G_TASK (result)));
9236
9237
0
  return bytes;
9238
0
}