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