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