gsocket: Set SO_NOSIGPIPE on sockets on Darwin
[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     }
3556
3557   /* If the types are different, and the destination method failed
3558    * also try the source method
3559    */
3560   if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination))
3561     {
3562       iface = G_FILE_GET_IFACE (source);
3563
3564       if (iface->move)
3565         {
3566           my_error = NULL;
3567           res = (* iface->move) (source, destination,
3568                                  flags, cancellable,
3569                                  progress_callback, progress_callback_data,
3570                                  &my_error);
3571
3572           if (res)
3573             return TRUE;
3574
3575           if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
3576             {
3577               g_propagate_error (error, my_error);
3578               return FALSE;
3579             }
3580         }
3581     }
3582
3583   if (flags & G_FILE_COPY_NO_FALLBACK_FOR_MOVE)
3584     {
3585       g_set_error_literal (error, G_IO_ERROR,
3586                            G_IO_ERROR_NOT_SUPPORTED,
3587                            _("Operation not supported"));
3588       return FALSE;
3589     }
3590
3591   flags |= G_FILE_COPY_ALL_METADATA;
3592   if (!g_file_copy (source, destination, flags, cancellable,
3593                     progress_callback, progress_callback_data,
3594                     error))
3595     return FALSE;
3596
3597   return g_file_delete (source, cancellable, error);
3598 }
3599
3600 /**
3601  * g_file_make_directory:
3602  * @file: input #GFile
3603  * @cancellable: (allow-none): optional #GCancellable object,
3604  *     %NULL to ignore
3605  * @error: a #GError, or %NULL
3606  *
3607  * Creates a directory. Note that this will only create a child directory
3608  * of the immediate parent directory of the path or URI given by the #GFile.
3609  * To recursively create directories, see g_file_make_directory_with_parents().
3610  * This function will fail if the parent directory does not exist, setting
3611  * @error to %G_IO_ERROR_NOT_FOUND. If the file system doesn't support
3612  * creating directories, this function will fail, setting @error to
3613  * %G_IO_ERROR_NOT_SUPPORTED.
3614  *
3615  * For a local #GFile the newly created directory will have the default
3616  * (current) ownership and permissions of the current process.
3617  *
3618  * If @cancellable is not %NULL, then the operation can be cancelled by
3619  * triggering the cancellable object from another thread. If the operation
3620  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3621  *
3622  * Returns: %TRUE on successful creation, %FALSE otherwise.
3623  */
3624 gboolean
3625 g_file_make_directory (GFile         *file,
3626                        GCancellable  *cancellable,
3627                        GError       **error)
3628 {
3629   GFileIface *iface;
3630
3631   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3632
3633   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3634     return FALSE;
3635
3636   iface = G_FILE_GET_IFACE (file);
3637
3638   if (iface->make_directory == NULL)
3639     {
3640       g_set_error_literal (error, G_IO_ERROR,
3641                            G_IO_ERROR_NOT_SUPPORTED,
3642                            _("Operation not supported"));
3643       return FALSE;
3644     }
3645
3646   return (* iface->make_directory) (file, cancellable, error);
3647 }
3648
3649 /**
3650  * g_file_make_directory_async:
3651  * @file: input #GFile
3652  * @io_priority: the [I/O priority][io-priority] of the request
3653  * @cancellable: (allow-none): optional #GCancellable object,
3654  *     %NULL to ignore
3655  * @callback: a #GAsyncReadyCallback to call
3656  *     when the request is satisfied
3657  * @user_data: the data to pass to callback function
3658  *
3659  * Asynchronously creates a directory.
3660  *
3661  * Virtual: make_directory_async
3662  * Since: 2.38
3663  */
3664 void
3665 g_file_make_directory_async (GFile               *file,
3666                              int                  io_priority,
3667                              GCancellable        *cancellable,
3668                              GAsyncReadyCallback  callback,
3669                              gpointer             user_data)
3670 {
3671   GFileIface *iface;
3672
3673   g_return_if_fail (G_IS_FILE (file));
3674
3675   iface = G_FILE_GET_IFACE (file);
3676   (* iface->make_directory_async) (file,
3677                                    io_priority,
3678                                    cancellable,
3679                                    callback,
3680                                    user_data);
3681 }
3682
3683 /**
3684  * g_file_make_directory_finish:
3685  * @file: input #GFile
3686  * @result: a #GAsyncResult
3687  * @error: a #GError, or %NULL
3688  *
3689  * Finishes an asynchronous directory creation, started with
3690  * g_file_make_directory_async().
3691  *
3692  * Virtual: make_directory_finish
3693  * Returns: %TRUE on successful directory creation, %FALSE otherwise.
3694  * Since: 2.38
3695  */
3696 gboolean
3697 g_file_make_directory_finish (GFile         *file,
3698                               GAsyncResult  *result,
3699                               GError       **error)
3700 {
3701   GFileIface *iface;
3702
3703   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3704   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3705
3706   iface = G_FILE_GET_IFACE (file);
3707   return (* iface->make_directory_finish) (file, result, error);
3708 }
3709
3710 /**
3711  * g_file_make_directory_with_parents:
3712  * @file: input #GFile
3713  * @cancellable: (allow-none): optional #GCancellable object,
3714  *     %NULL to ignore
3715  * @error: a #GError, or %NULL
3716  *
3717  * Creates a directory and any parent directories that may not
3718  * exist similar to 'mkdir -p'. If the file system does not support
3719  * creating directories, this function will fail, setting @error to
3720  * %G_IO_ERROR_NOT_SUPPORTED. If the directory itself already exists,
3721  * this function will fail setting @error to %G_IO_ERROR_EXISTS, unlike
3722  * the similar g_mkdir_with_parents().
3723  *
3724  * For a local #GFile the newly created directories will have the default
3725  * (current) ownership and permissions of the current process.
3726  *
3727  * If @cancellable is not %NULL, then the operation can be cancelled by
3728  * triggering the cancellable object from another thread. If the operation
3729  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3730  *
3731  * Returns: %TRUE if all directories have been successfully created, %FALSE
3732  * otherwise.
3733  *
3734  * Since: 2.18
3735  */
3736 gboolean
3737 g_file_make_directory_with_parents (GFile         *file,
3738                                     GCancellable  *cancellable,
3739                                     GError       **error)
3740 {
3741   GFile *work_file = NULL;
3742   GList *list = NULL, *l;
3743   GError *my_error = NULL;
3744
3745   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3746
3747   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3748     return FALSE;
3749
3750   g_file_make_directory (file, cancellable, &my_error);
3751   if (my_error == NULL || my_error->code != G_IO_ERROR_NOT_FOUND)
3752     {
3753       if (my_error)
3754         g_propagate_error (error, my_error);
3755       return my_error == NULL;
3756     }
3757
3758   work_file = g_object_ref (file);
3759
3760   while (my_error != NULL && my_error->code == G_IO_ERROR_NOT_FOUND)
3761     {
3762       GFile *parent_file;
3763
3764       parent_file = g_file_get_parent (work_file);
3765       if (parent_file == NULL)
3766         break;
3767
3768       g_clear_error (&my_error);
3769       g_file_make_directory (parent_file, cancellable, &my_error);
3770
3771       g_object_unref (work_file);
3772       work_file = g_object_ref (parent_file);
3773
3774       if (my_error != NULL && my_error->code == G_IO_ERROR_NOT_FOUND)
3775         list = g_list_prepend (list, parent_file);  /* Transfer ownership of ref */
3776       else
3777         g_object_unref (parent_file);
3778     }
3779
3780   for (l = list; my_error == NULL && l; l = l->next)
3781     {
3782       g_file_make_directory ((GFile *) l->data, cancellable, &my_error);
3783     }
3784
3785   if (work_file)
3786     g_object_unref (work_file);
3787
3788   /* Clean up */
3789   while (list != NULL)
3790     {
3791       g_object_unref ((GFile *) list->data);
3792       list = g_list_remove (list, list->data);
3793     }
3794
3795   if (my_error != NULL)
3796     {
3797       g_propagate_error (error, my_error);
3798       return FALSE;
3799     }
3800
3801   return g_file_make_directory (file, cancellable, error);
3802 }
3803
3804 /**
3805  * g_file_make_symbolic_link:
3806  * @file: a #GFile with the name of the symlink to create
3807  * @symlink_value: a string with the path for the target of the new symlink
3808  * @cancellable: (allow-none): optional #GCancellable object,
3809  *     %NULL to ignore
3810  * @error: a #GError
3811  *
3812  * Creates a symbolic link named @file which contains the string
3813  * @symlink_value.
3814  *
3815  * If @cancellable is not %NULL, then the operation can be cancelled by
3816  * triggering the cancellable object from another thread. If the operation
3817  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3818  *
3819  * Returns: %TRUE on the creation of a new symlink, %FALSE otherwise.
3820  */
3821 gboolean
3822 g_file_make_symbolic_link (GFile         *file,
3823                            const char    *symlink_value,
3824                            GCancellable  *cancellable,
3825                            GError       **error)
3826 {
3827   GFileIface *iface;
3828
3829   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3830   g_return_val_if_fail (symlink_value != NULL, FALSE);
3831
3832   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3833     return FALSE;
3834
3835   if (*symlink_value == '\0')
3836     {
3837       g_set_error_literal (error, G_IO_ERROR,
3838                            G_IO_ERROR_INVALID_ARGUMENT,
3839                            _("Invalid symlink value given"));
3840       return FALSE;
3841     }
3842
3843   iface = G_FILE_GET_IFACE (file);
3844
3845   if (iface->make_symbolic_link == NULL)
3846     {
3847       g_set_error_literal (error, G_IO_ERROR,
3848                            G_IO_ERROR_NOT_SUPPORTED,
3849                            _("Operation not supported"));
3850       return FALSE;
3851     }
3852
3853   return (* iface->make_symbolic_link) (file, symlink_value, cancellable, error);
3854 }
3855
3856 /**
3857  * g_file_delete:
3858  * @file: input #GFile
3859  * @cancellable: (allow-none): optional #GCancellable object,
3860  *     %NULL to ignore
3861  * @error: a #GError, or %NULL
3862  *
3863  * Deletes a file. If the @file is a directory, it will only be
3864  * deleted if it is empty. This has the same semantics as g_unlink().
3865  *
3866  * If @cancellable is not %NULL, then the operation can be cancelled by
3867  * triggering the cancellable object from another thread. If the operation
3868  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3869  *
3870  * Virtual: delete_file
3871  * Returns: %TRUE if the file was deleted. %FALSE otherwise.
3872  */
3873 gboolean
3874 g_file_delete (GFile         *file,
3875                GCancellable  *cancellable,
3876                GError       **error)
3877 {
3878   GFileIface *iface;
3879
3880   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3881
3882   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3883     return FALSE;
3884
3885   iface = G_FILE_GET_IFACE (file);
3886
3887   if (iface->delete_file == NULL)
3888     {
3889       g_set_error_literal (error, G_IO_ERROR,
3890                            G_IO_ERROR_NOT_SUPPORTED,
3891                            _("Operation not supported"));
3892       return FALSE;
3893     }
3894
3895   return (* iface->delete_file) (file, cancellable, error);
3896 }
3897
3898 /**
3899  * g_file_delete_async:
3900  * @file: input #GFile
3901  * @io_priority: the [I/O priority][io-priority] of the request
3902  * @cancellable: (allow-none): optional #GCancellable object,
3903  *     %NULL to ignore
3904  * @callback: a #GAsyncReadyCallback to call
3905  *     when the request is satisfied
3906  * @user_data: the data to pass to callback function
3907  *
3908  * Asynchronously delete a file. If the @file is a directory, it will
3909  * only be deleted if it is empty.  This has the same semantics as
3910  * g_unlink().
3911  *
3912  * Virtual: delete_file_async
3913  * Since: 2.34
3914  */
3915 void
3916 g_file_delete_async (GFile               *file,
3917                      int                  io_priority,
3918                      GCancellable        *cancellable,
3919                      GAsyncReadyCallback  callback,
3920                      gpointer             user_data)
3921 {
3922   GFileIface *iface;
3923
3924   g_return_if_fail (G_IS_FILE (file));
3925
3926   iface = G_FILE_GET_IFACE (file);
3927   (* iface->delete_file_async) (file,
3928                                 io_priority,
3929                                 cancellable,
3930                                 callback,
3931                                 user_data);
3932 }
3933
3934 /**
3935  * g_file_delete_finish:
3936  * @file: input #GFile
3937  * @result: a #GAsyncResult
3938  * @error: a #GError, or %NULL
3939  *
3940  * Finishes deleting a file started with g_file_delete_async().
3941  *
3942  * Virtual: delete_file_finish
3943  * Returns: %TRUE if the file was deleted. %FALSE otherwise.
3944  * Since: 2.34
3945  **/
3946 gboolean
3947 g_file_delete_finish (GFile         *file,
3948                       GAsyncResult  *result,
3949                       GError       **error)
3950 {
3951   GFileIface *iface;
3952
3953   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3954   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3955
3956   if (g_async_result_legacy_propagate_error (result, error))
3957     return FALSE;
3958
3959   iface = G_FILE_GET_IFACE (file);
3960   return (* iface->delete_file_finish) (file, result, error);
3961 }
3962
3963 /**
3964  * g_file_trash:
3965  * @file: #GFile to send to trash
3966  * @cancellable: (allow-none): optional #GCancellable object,
3967  *     %NULL to ignore
3968  * @error: a #GError, or %NULL
3969  *
3970  * Sends @file to the "Trashcan", if possible. This is similar to
3971  * deleting it, but the user can recover it before emptying the trashcan.
3972  * Not all file systems support trashing, so this call can return the
3973  * %G_IO_ERROR_NOT_SUPPORTED error.
3974  *
3975  * If @cancellable is not %NULL, then the operation can be cancelled by
3976  * triggering the cancellable object from another thread. If the operation
3977  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3978  *
3979  * Virtual: trash
3980  * Returns: %TRUE on successful trash, %FALSE otherwise.
3981  */
3982 gboolean
3983 g_file_trash (GFile         *file,
3984               GCancellable  *cancellable,
3985               GError       **error)
3986 {
3987   GFileIface *iface;
3988
3989   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3990
3991   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3992     return FALSE;
3993
3994   iface = G_FILE_GET_IFACE (file);
3995
3996   if (iface->trash == NULL)
3997     {
3998       g_set_error_literal (error,
3999                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
4000                            _("Trash not supported"));
4001       return FALSE;
4002     }
4003
4004   return (* iface->trash) (file, cancellable, error);
4005 }
4006
4007 /**
4008  * g_file_trash_async:
4009  * @file: input #GFile
4010  * @io_priority: the [I/O priority][io-priority] of the request
4011  * @cancellable: (allow-none): optional #GCancellable object,
4012  *     %NULL to ignore
4013  * @callback: a #GAsyncReadyCallback to call
4014  *     when the request is satisfied
4015  * @user_data: the data to pass to callback function
4016  *
4017  * Asynchronously sends @file to the Trash location, if possible.
4018  *
4019  * Virtual: trash_async
4020  * Since: 2.38
4021  */
4022 void
4023 g_file_trash_async (GFile               *file,
4024                     int                  io_priority,
4025                     GCancellable        *cancellable,
4026                     GAsyncReadyCallback  callback,
4027                     gpointer             user_data)
4028 {
4029   GFileIface *iface;
4030
4031   g_return_if_fail (G_IS_FILE (file));
4032
4033   iface = G_FILE_GET_IFACE (file);
4034   (* iface->trash_async) (file,
4035                           io_priority,
4036                           cancellable,
4037                           callback,
4038                           user_data);
4039 }
4040
4041 /**
4042  * g_file_trash_finish:
4043  * @file: input #GFile
4044  * @result: a #GAsyncResult
4045  * @error: a #GError, or %NULL
4046  *
4047  * Finishes an asynchronous file trashing operation, started with
4048  * g_file_trash_async().
4049  *
4050  * Virtual: trash_finish
4051  * Returns: %TRUE on successful trash, %FALSE otherwise.
4052  * Since: 2.38
4053  */
4054 gboolean
4055 g_file_trash_finish (GFile         *file,
4056                      GAsyncResult  *result,
4057                      GError       **error)
4058 {
4059   GFileIface *iface;
4060
4061   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4062   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4063
4064   iface = G_FILE_GET_IFACE (file);
4065   return (* iface->trash_finish) (file, result, error);
4066 }
4067
4068 /**
4069  * g_file_set_display_name:
4070  * @file: input #GFile
4071  * @display_name: a string
4072  * @cancellable: (allow-none): optional #GCancellable object,
4073  *     %NULL to ignore
4074  * @error: a #GError, or %NULL
4075  *
4076  * Renames @file to the specified display name.
4077  *
4078  * The display name is converted from UTF-8 to the correct encoding
4079  * for the target filesystem if possible and the @file is renamed to this.
4080  *
4081  * If you want to implement a rename operation in the user interface the
4082  * edit name (#G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME) should be used as the
4083  * initial value in the rename widget, and then the result after editing
4084  * should be passed to g_file_set_display_name().
4085  *
4086  * On success the resulting converted filename is returned.
4087  *
4088  * If @cancellable is not %NULL, then the operation can be cancelled by
4089  * triggering the cancellable object from another thread. If the operation
4090  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4091  *
4092  * Returns: (transfer full): a #GFile specifying what @file was renamed to,
4093  *     or %NULL if there was an error.
4094  *     Free the returned object with g_object_unref().
4095  */
4096 GFile *
4097 g_file_set_display_name (GFile         *file,
4098                          const gchar   *display_name,
4099                          GCancellable  *cancellable,
4100                          GError       **error)
4101 {
4102   GFileIface *iface;
4103
4104   g_return_val_if_fail (G_IS_FILE (file), NULL);
4105   g_return_val_if_fail (display_name != NULL, NULL);
4106
4107   if (strchr (display_name, G_DIR_SEPARATOR) != NULL)
4108     {
4109       g_set_error (error,
4110                    G_IO_ERROR,
4111                    G_IO_ERROR_INVALID_ARGUMENT,
4112                    _("File names cannot contain '%c'"), G_DIR_SEPARATOR);
4113       return NULL;
4114     }
4115
4116   if (g_cancellable_set_error_if_cancelled (cancellable, error))
4117     return NULL;
4118
4119   iface = G_FILE_GET_IFACE (file);
4120
4121   return (* iface->set_display_name) (file, display_name, cancellable, error);
4122 }
4123
4124 /**
4125  * g_file_set_display_name_async:
4126  * @file: input #GFile
4127  * @display_name: a string
4128  * @io_priority: the [I/O priority][io-priority] of the request
4129  * @cancellable: (allow-none): optional #GCancellable object,
4130  *     %NULL to ignore
4131  * @callback: (scope async): a #GAsyncReadyCallback to call
4132  *     when the request is satisfied
4133  * @user_data: (closure): the data to pass to callback function
4134  *
4135  * Asynchronously sets the display name for a given #GFile.
4136  *
4137  * For more details, see g_file_set_display_name() which is
4138  * the synchronous version of this call.
4139  *
4140  * When the operation is finished, @callback will be called.
4141  * You can then call g_file_set_display_name_finish() to get
4142  * the result of the operation.
4143  */
4144 void
4145 g_file_set_display_name_async (GFile               *file,
4146                                const gchar         *display_name,
4147                                gint                 io_priority,
4148                                GCancellable        *cancellable,
4149                                GAsyncReadyCallback  callback,
4150                                gpointer             user_data)
4151 {
4152   GFileIface *iface;
4153
4154   g_return_if_fail (G_IS_FILE (file));
4155   g_return_if_fail (display_name != NULL);
4156
4157   iface = G_FILE_GET_IFACE (file);
4158   (* iface->set_display_name_async) (file,
4159                                      display_name,
4160                                      io_priority,
4161                                      cancellable,
4162                                      callback,
4163                                      user_data);
4164 }
4165
4166 /**
4167  * g_file_set_display_name_finish:
4168  * @file: input #GFile
4169  * @res: a #GAsyncResult
4170  * @error: a #GError, or %NULL
4171  *
4172  * Finishes setting a display name started with
4173  * g_file_set_display_name_async().
4174  *
4175  * Returns: (transfer full): a #GFile or %NULL on error.
4176  *     Free the returned object with g_object_unref().
4177  */
4178 GFile *
4179 g_file_set_display_name_finish (GFile         *file,
4180                                 GAsyncResult  *res,
4181                                 GError       **error)
4182 {
4183   GFileIface *iface;
4184
4185   g_return_val_if_fail (G_IS_FILE (file), NULL);
4186   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
4187
4188   if (g_async_result_legacy_propagate_error (res, error))
4189     return NULL;
4190
4191   iface = G_FILE_GET_IFACE (file);
4192   return (* iface->set_display_name_finish) (file, res, error);
4193 }
4194
4195 /**
4196  * g_file_query_settable_attributes:
4197  * @file: input #GFile
4198  * @cancellable: (allow-none): optional #GCancellable object,
4199  *     %NULL to ignore
4200  * @error: a #GError, or %NULL
4201  *
4202  * Obtain the list of settable attributes for the file.
4203  *
4204  * Returns the type and full attribute name of all the attributes
4205  * that can be set on this file. This doesn't mean setting it will
4206  * always succeed though, you might get an access failure, or some
4207  * specific file may not support a specific attribute.
4208  *
4209  * If @cancellable is not %NULL, then the operation can be cancelled by
4210  * triggering the cancellable object from another thread. If the operation
4211  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4212  *
4213  * Returns: a #GFileAttributeInfoList describing the settable attributes.
4214  *     When you are done with it, release it with
4215  *     g_file_attribute_info_list_unref()
4216  */
4217 GFileAttributeInfoList *
4218 g_file_query_settable_attributes (GFile         *file,
4219                                   GCancellable  *cancellable,
4220                                   GError       **error)
4221 {
4222   GFileIface *iface;
4223   GError *my_error;
4224   GFileAttributeInfoList *list;
4225
4226   g_return_val_if_fail (G_IS_FILE (file), NULL);
4227
4228   if (g_cancellable_set_error_if_cancelled (cancellable, error))
4229     return NULL;
4230
4231   iface = G_FILE_GET_IFACE (file);
4232
4233   if (iface->query_settable_attributes == NULL)
4234     return g_file_attribute_info_list_new ();
4235
4236   my_error = NULL;
4237   list = (* iface->query_settable_attributes) (file, cancellable, &my_error);
4238
4239   if (list == NULL)
4240     {
4241       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
4242         {
4243           list = g_file_attribute_info_list_new ();
4244           g_error_free (my_error);
4245         }
4246       else
4247         g_propagate_error (error, my_error);
4248     }
4249
4250   return list;
4251 }
4252
4253 /**
4254  * g_file_query_writable_namespaces:
4255  * @file: input #GFile
4256  * @cancellable: (allow-none): optional #GCancellable object,
4257  *     %NULL to ignore
4258  * @error: a #GError, or %NULL
4259  *
4260  * Obtain the list of attribute namespaces where new attributes
4261  * can be created by a user. An example of this is extended
4262  * attributes (in the "xattr" namespace).
4263  *
4264  * If @cancellable is not %NULL, then the operation can be cancelled by
4265  * triggering the cancellable object from another thread. If the operation
4266  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4267  *
4268  * Returns: a #GFileAttributeInfoList describing the writable namespaces.
4269  *     When you are done with it, release it with
4270  *     g_file_attribute_info_list_unref()
4271  */
4272 GFileAttributeInfoList *
4273 g_file_query_writable_namespaces (GFile         *file,
4274                                   GCancellable  *cancellable,
4275                                   GError       **error)
4276 {
4277   GFileIface *iface;
4278   GError *my_error;
4279   GFileAttributeInfoList *list;
4280
4281   g_return_val_if_fail (G_IS_FILE (file), NULL);
4282
4283   if (g_cancellable_set_error_if_cancelled (cancellable, error))
4284     return NULL;
4285
4286   iface = G_FILE_GET_IFACE (file);
4287
4288   if (iface->query_writable_namespaces == NULL)
4289     return g_file_attribute_info_list_new ();
4290
4291   my_error = NULL;
4292   list = (* iface->query_writable_namespaces) (file, cancellable, &my_error);
4293
4294   if (list == NULL)
4295     {
4296       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
4297         {
4298           list = g_file_attribute_info_list_new ();
4299           g_error_free (my_error);
4300         }
4301       else
4302         g_propagate_error (error, my_error);
4303     }
4304
4305   return list;
4306 }
4307
4308 /**
4309  * g_file_set_attribute:
4310  * @file: input #GFile
4311  * @attribute: a string containing the attribute's name
4312  * @type: The type of the attribute
4313  * @value_p: (allow-none): a pointer to the value (or the pointer
4314  *     itself if the type is a pointer type)
4315  * @flags: a set of #GFileQueryInfoFlags
4316  * @cancellable: (allow-none): optional #GCancellable object,
4317  *     %NULL to ignore
4318  * @error: a #GError, or %NULL
4319  *
4320  * Sets an attribute in the file with attribute name @attribute to @value.
4321  *
4322  * Some attributes can be unset by setting @attribute to
4323  * %G_FILE_ATTRIBUTE_TYPE_INVALID and @value_p to %NULL.
4324  *
4325  * If @cancellable is not %NULL, then the operation can be cancelled by
4326  * triggering the cancellable object from another thread. If the operation
4327  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4328  *
4329  * Returns: %TRUE if the attribute was set, %FALSE otherwise.
4330  */
4331 gboolean
4332 g_file_set_attribute (GFile                *file,
4333                       const gchar          *attribute,
4334                       GFileAttributeType    type,
4335                       gpointer              value_p,
4336                       GFileQueryInfoFlags   flags,
4337                       GCancellable         *cancellable,
4338                       GError              **error)
4339 {
4340   GFileIface *iface;
4341
4342   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4343   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
4344
4345   if (g_cancellable_set_error_if_cancelled (cancellable, error))
4346     return FALSE;
4347
4348   iface = G_FILE_GET_IFACE (file);
4349
4350   if (iface->set_attribute == NULL)
4351     {
4352       g_set_error_literal (error, G_IO_ERROR,
4353                            G_IO_ERROR_NOT_SUPPORTED,
4354                            _("Operation not supported"));
4355       return FALSE;
4356     }
4357
4358   return (* iface->set_attribute) (file, attribute, type, value_p, flags, cancellable, error);
4359 }
4360
4361 /**
4362  * g_file_set_attributes_from_info:
4363  * @file: input #GFile
4364  * @info: a #GFileInfo
4365  * @flags: #GFileQueryInfoFlags
4366  * @cancellable: (allow-none): optional #GCancellable object,
4367  *     %NULL to ignore
4368  * @error: a #GError, or %NULL
4369  *
4370  * Tries to set all attributes in the #GFileInfo on the target
4371  * values, not stopping on the first error.
4372  *
4373  * If there is any error during this operation then @error will
4374  * be set to the first error. Error on particular fields are flagged
4375  * by setting the "status" field in the attribute value to
4376  * %G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING, which means you can
4377  * also detect further errors.
4378  *
4379  * If @cancellable is not %NULL, then the operation can be cancelled by
4380  * triggering the cancellable object from another thread. If the operation
4381  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4382  *
4383  * Returns: %FALSE if there was any error, %TRUE otherwise.
4384  */
4385 gboolean
4386 g_file_set_attributes_from_info (GFile                *file,
4387                                  GFileInfo            *info,
4388                                  GFileQueryInfoFlags   flags,
4389                                  GCancellable         *cancellable,
4390                                  GError              **error)
4391 {
4392   GFileIface *iface;
4393
4394   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4395   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
4396
4397   if (g_cancellable_set_error_if_cancelled (cancellable, error))
4398     return FALSE;
4399
4400   g_file_info_clear_status (info);
4401
4402   iface = G_FILE_GET_IFACE (file);
4403
4404   return (* iface->set_attributes_from_info) (file,
4405                                               info,
4406                                               flags,
4407                                               cancellable,
4408                                               error);
4409 }
4410
4411 static gboolean
4412 g_file_real_set_attributes_from_info (GFile                *file,
4413                                       GFileInfo            *info,
4414                                       GFileQueryInfoFlags   flags,
4415                                       GCancellable         *cancellable,
4416                                       GError              **error)
4417 {
4418   char **attributes;
4419   int i;
4420   gboolean res;
4421   GFileAttributeValue *value;
4422
4423   res = TRUE;
4424
4425   attributes = g_file_info_list_attributes (info, NULL);
4426
4427   for (i = 0; attributes[i] != NULL; i++)
4428     {
4429       value = _g_file_info_get_attribute_value (info, attributes[i]);
4430
4431       if (value->status != G_FILE_ATTRIBUTE_STATUS_UNSET)
4432         continue;
4433
4434       if (!g_file_set_attribute (file, attributes[i],
4435                                  value->type, _g_file_attribute_value_peek_as_pointer (value),
4436                                  flags, cancellable, error))
4437         {
4438           value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING;
4439           res = FALSE;
4440           /* Don't set error multiple times */
4441           error = NULL;
4442         }
4443       else
4444         value->status = G_FILE_ATTRIBUTE_STATUS_SET;
4445     }
4446
4447   g_strfreev (attributes);
4448
4449   return res;
4450 }
4451
4452 /**
4453  * g_file_set_attributes_async:
4454  * @file: input #GFile
4455  * @info: a #GFileInfo
4456  * @flags: a #GFileQueryInfoFlags
4457  * @io_priority: the [I/O priority][io-priority] of the request
4458  * @cancellable: (allow-none): optional #GCancellable object,
4459  *     %NULL to ignore
4460  * @callback: (scope async): a #GAsyncReadyCallback
4461  * @user_data: (closure): a #gpointer
4462  *
4463  * Asynchronously sets the attributes of @file with @info.
4464  *
4465  * For more details, see g_file_set_attributes_from_info(),
4466  * which is the synchronous version of this call.
4467  *
4468  * When the operation is finished, @callback will be called.
4469  * You can then call g_file_set_attributes_finish() to get
4470  * the result of the operation.
4471  */
4472 void
4473 g_file_set_attributes_async (GFile               *file,
4474                              GFileInfo           *info,
4475                              GFileQueryInfoFlags  flags,
4476                              int                  io_priority,
4477                              GCancellable        *cancellable,
4478                              GAsyncReadyCallback  callback,
4479                              gpointer             user_data)
4480 {
4481   GFileIface *iface;
4482
4483   g_return_if_fail (G_IS_FILE (file));
4484   g_return_if_fail (G_IS_FILE_INFO (info));
4485
4486   iface = G_FILE_GET_IFACE (file);
4487   (* iface->set_attributes_async) (file,
4488                                    info,
4489                                    flags,
4490                                    io_priority,
4491                                    cancellable,
4492                                    callback,
4493                                    user_data);
4494 }
4495
4496 /**
4497  * g_file_set_attributes_finish:
4498  * @file: input #GFile
4499  * @result: a #GAsyncResult
4500  * @info: (out) (transfer full): a #GFileInfo
4501  * @error: a #GError, or %NULL
4502  *
4503  * Finishes setting an attribute started in g_file_set_attributes_async().
4504  *
4505  * Returns: %TRUE if the attributes were set correctly, %FALSE otherwise.
4506  */
4507 gboolean
4508 g_file_set_attributes_finish (GFile         *file,
4509                               GAsyncResult  *result,
4510                               GFileInfo    **info,
4511                               GError       **error)
4512 {
4513   GFileIface *iface;
4514
4515   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4516   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4517
4518   /* No standard handling of errors here, as we must set info even
4519    * on errors
4520    */
4521   iface = G_FILE_GET_IFACE (file);
4522   return (* iface->set_attributes_finish) (file, result, info, error);
4523 }
4524
4525 /**
4526  * g_file_set_attribute_string:
4527  * @file: input #GFile
4528  * @attribute: a string containing the attribute's name
4529  * @value: a string containing the attribute's value
4530  * @flags: #GFileQueryInfoFlags
4531  * @cancellable: (allow-none): optional #GCancellable object,
4532  *     %NULL to ignore
4533  * @error: a #GError, or %NULL
4534  *
4535  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_STRING to @value.
4536  * If @attribute is of a different type, this operation will fail.
4537  *
4538  * If @cancellable is not %NULL, then the operation can be cancelled by
4539  * triggering the cancellable object from another thread. If the operation
4540  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4541  *
4542  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
4543  */
4544 gboolean
4545 g_file_set_attribute_string (GFile                *file,
4546                              const char           *attribute,
4547                              const char           *value,
4548                              GFileQueryInfoFlags   flags,
4549                              GCancellable         *cancellable,
4550                              GError              **error)
4551 {
4552   return g_file_set_attribute (file, attribute,
4553                                G_FILE_ATTRIBUTE_TYPE_STRING, (gpointer)value,
4554                                flags, cancellable, error);
4555 }
4556
4557 /**
4558  * g_file_set_attribute_byte_string:
4559  * @file: input #GFile
4560  * @attribute: a string containing the attribute's name
4561  * @value: a string containing the attribute's new value
4562  * @flags: a #GFileQueryInfoFlags
4563  * @cancellable: (allow-none): optional #GCancellable object,
4564  *     %NULL to ignore
4565  * @error: a #GError, or %NULL
4566  *
4567  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING to @value.
4568  * If @attribute is of a different type, this operation will fail,
4569  * returning %FALSE.
4570  *
4571  * If @cancellable is not %NULL, then the operation can be cancelled by
4572  * triggering the cancellable object from another thread. If the operation
4573  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4574  *
4575  * Returns: %TRUE if the @attribute was successfully set to @value
4576  *     in the @file, %FALSE otherwise.
4577  */
4578 gboolean
4579 g_file_set_attribute_byte_string  (GFile                *file,
4580                                    const gchar          *attribute,
4581                                    const gchar          *value,
4582                                    GFileQueryInfoFlags   flags,
4583                                    GCancellable         *cancellable,
4584                                    GError              **error)
4585 {
4586   return g_file_set_attribute (file, attribute,
4587                                G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, (gpointer)value,
4588                                flags, cancellable, error);
4589 }
4590
4591 /**
4592  * g_file_set_attribute_uint32:
4593  * @file: input #GFile
4594  * @attribute: a string containing the attribute's name
4595  * @value: a #guint32 containing the attribute's new value
4596  * @flags: a #GFileQueryInfoFlags
4597  * @cancellable: (allow-none): optional #GCancellable object,
4598  *     %NULL to ignore
4599  * @error: a #GError, or %NULL
4600  *
4601  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT32 to @value.
4602  * If @attribute is of a different type, this operation will fail.
4603  *
4604  * If @cancellable is not %NULL, then the operation can be cancelled by
4605  * triggering the cancellable object from another thread. If the operation
4606  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4607  *
4608  * Returns: %TRUE if the @attribute was successfully set to @value
4609  *     in the @file, %FALSE otherwise.
4610  */
4611 gboolean
4612 g_file_set_attribute_uint32 (GFile                *file,
4613                              const gchar          *attribute,
4614                              guint32               value,
4615                              GFileQueryInfoFlags   flags,
4616                              GCancellable         *cancellable,
4617                              GError              **error)
4618 {
4619   return g_file_set_attribute (file, attribute,
4620                                G_FILE_ATTRIBUTE_TYPE_UINT32, &value,
4621                                flags, cancellable, error);
4622 }
4623
4624 /**
4625  * g_file_set_attribute_int32:
4626  * @file: input #GFile
4627  * @attribute: a string containing the attribute's name
4628  * @value: a #gint32 containing the attribute's new value
4629  * @flags: a #GFileQueryInfoFlags
4630  * @cancellable: (allow-none): optional #GCancellable object,
4631  *     %NULL to ignore
4632  * @error: a #GError, or %NULL
4633  *
4634  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT32 to @value.
4635  * If @attribute is of a different type, this operation will fail.
4636  *
4637  * If @cancellable is not %NULL, then the operation can be cancelled by
4638  * triggering the cancellable object from another thread. If the operation
4639  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4640  *
4641  * Returns: %TRUE if the @attribute was successfully set to @value
4642  *     in the @file, %FALSE otherwise.
4643  */
4644 gboolean
4645 g_file_set_attribute_int32 (GFile                *file,
4646                             const gchar          *attribute,
4647                             gint32                value,
4648                             GFileQueryInfoFlags   flags,
4649                             GCancellable         *cancellable,
4650                             GError              **error)
4651 {
4652   return g_file_set_attribute (file, attribute,
4653                                G_FILE_ATTRIBUTE_TYPE_INT32, &value,
4654                                flags, cancellable, error);
4655 }
4656
4657 /**
4658  * g_file_set_attribute_uint64:
4659  * @file: input #GFile
4660  * @attribute: a string containing the attribute's name
4661  * @value: a #guint64 containing the attribute's new value
4662  * @flags: a #GFileQueryInfoFlags
4663  * @cancellable: (allow-none): optional #GCancellable object,
4664  *     %NULL to ignore
4665  * @error: a #GError, or %NULL
4666  *
4667  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT64 to @value.
4668  * If @attribute is of a different type, this operation will fail.
4669  *
4670  * If @cancellable is not %NULL, then the operation can be cancelled by
4671  * triggering the cancellable object from another thread. If the operation
4672  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4673  *
4674  * Returns: %TRUE if the @attribute was successfully set to @value
4675  *     in the @file, %FALSE otherwise.
4676  */
4677 gboolean
4678 g_file_set_attribute_uint64 (GFile                *file,
4679                              const gchar          *attribute,
4680                              guint64               value,
4681                              GFileQueryInfoFlags   flags,
4682                              GCancellable         *cancellable,
4683                              GError              **error)
4684  {
4685   return g_file_set_attribute (file, attribute,
4686                                G_FILE_ATTRIBUTE_TYPE_UINT64, &value,
4687                                flags, cancellable, error);
4688 }
4689
4690 /**
4691  * g_file_set_attribute_int64:
4692  * @file: input #GFile
4693  * @attribute: a string containing the attribute's name
4694  * @value: a #guint64 containing the attribute's new value
4695  * @flags: a #GFileQueryInfoFlags
4696  * @cancellable: (allow-none): optional #GCancellable object,
4697  *     %NULL to ignore
4698  * @error: a #GError, or %NULL
4699  *
4700  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT64 to @value.
4701  * If @attribute is of a different type, this operation will fail.
4702  *
4703  * If @cancellable is not %NULL, then the operation can be cancelled by
4704  * triggering the cancellable object from another thread. If the operation
4705  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4706  *
4707  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
4708  */
4709 gboolean
4710 g_file_set_attribute_int64 (GFile                *file,
4711                             const gchar          *attribute,
4712                             gint64                value,
4713                             GFileQueryInfoFlags   flags,
4714                             GCancellable         *cancellable,
4715                             GError              **error)
4716 {
4717   return g_file_set_attribute (file, attribute,
4718                                G_FILE_ATTRIBUTE_TYPE_INT64, &value,
4719                                flags, cancellable, error);
4720 }
4721
4722 /**
4723  * g_file_mount_mountable:
4724  * @file: input #GFile
4725  * @flags: flags affecting the operation
4726  * @mount_operation: (allow-none): a #GMountOperation,
4727  *     or %NULL to avoid user interaction
4728  * @cancellable: (allow-none): optional #GCancellable object,
4729  *     %NULL to ignore
4730  * @callback: (scope async) (allow-none): a #GAsyncReadyCallback to call
4731  *     when the request is satisfied, or %NULL
4732  * @user_data: (closure): the data to pass to callback function
4733  *
4734  * Mounts a file of type G_FILE_TYPE_MOUNTABLE.
4735  * Using @mount_operation, you can request callbacks when, for instance,
4736  * passwords are needed during authentication.
4737  *
4738  * If @cancellable is not %NULL, then the operation can be cancelled by
4739  * triggering the cancellable object from another thread. If the operation
4740  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4741  *
4742  * When the operation is finished, @callback will be called.
4743  * You can then call g_file_mount_mountable_finish() to get
4744  * the result of the operation.
4745  */
4746 void
4747 g_file_mount_mountable (GFile               *file,
4748                         GMountMountFlags     flags,
4749                         GMountOperation     *mount_operation,
4750                         GCancellable        *cancellable,
4751                         GAsyncReadyCallback  callback,
4752                         gpointer             user_data)
4753 {
4754   GFileIface *iface;
4755
4756   g_return_if_fail (G_IS_FILE (file));
4757
4758   iface = G_FILE_GET_IFACE (file);
4759
4760   if (iface->mount_mountable == NULL)
4761     {
4762       g_task_report_new_error (file, callback, user_data,
4763                                g_file_mount_mountable,
4764                                G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
4765                                _("Operation not supported"));
4766       return;
4767     }
4768
4769   (* iface->mount_mountable) (file,
4770                               flags,
4771                               mount_operation,
4772                               cancellable,
4773                               callback,
4774                               user_data);
4775 }
4776
4777 /**
4778  * g_file_mount_mountable_finish:
4779  * @file: input #GFile
4780  * @result: a #GAsyncResult
4781  * @error: a #GError, or %NULL
4782  *
4783  * Finishes a mount operation. See g_file_mount_mountable() for details.
4784  *
4785  * Finish an asynchronous mount operation that was started
4786  * with g_file_mount_mountable().
4787  *
4788  * Returns: (transfer full): a #GFile or %NULL on error.
4789  *     Free the returned object with g_object_unref().
4790  */
4791 GFile *
4792 g_file_mount_mountable_finish (GFile         *file,
4793                                GAsyncResult  *result,
4794                                GError       **error)
4795 {
4796   GFileIface *iface;
4797
4798   g_return_val_if_fail (G_IS_FILE (file), NULL);
4799   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
4800
4801   if (g_async_result_legacy_propagate_error (result, error))
4802     return NULL;
4803   else if (g_async_result_is_tagged (result, g_file_mount_mountable))
4804     return g_task_propagate_pointer (G_TASK (result), error);
4805
4806   iface = G_FILE_GET_IFACE (file);
4807   return (* iface->mount_mountable_finish) (file, result, error);
4808 }
4809
4810 /**
4811  * g_file_unmount_mountable:
4812  * @file: input #GFile
4813  * @flags: flags affecting the operation
4814  * @cancellable: (allow-none): optional #GCancellable object,
4815  *     %NULL to ignore
4816  * @callback: (scope async) (allow-none): a #GAsyncReadyCallback to call
4817  *     when the request is satisfied, or %NULL
4818  * @user_data: (closure): the data to pass to callback function
4819  *
4820  * Unmounts a file of type G_FILE_TYPE_MOUNTABLE.
4821  *
4822  * If @cancellable is not %NULL, then the operation can be cancelled by
4823  * triggering the cancellable object from another thread. If the operation
4824  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4825  *
4826  * When the operation is finished, @callback will be called.
4827  * You can then call g_file_unmount_mountable_finish() to get
4828  * the result of the operation.
4829  *
4830  * Deprecated: 2.22: Use g_file_unmount_mountable_with_operation() instead.
4831  */
4832 void
4833 g_file_unmount_mountable (GFile               *file,
4834                           GMountUnmountFlags   flags,
4835                           GCancellable        *cancellable,
4836                           GAsyncReadyCallback  callback,
4837                           gpointer             user_data)
4838 {
4839   GFileIface *iface;
4840
4841   g_return_if_fail (G_IS_FILE (file));
4842
4843   iface = G_FILE_GET_IFACE (file);
4844
4845   if (iface->unmount_mountable == NULL)
4846     {
4847       g_task_report_new_error (file, callback, user_data,
4848                                g_file_unmount_mountable_with_operation,
4849                                G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
4850                                _("Operation not supported"));
4851       return;
4852     }
4853
4854   (* iface->unmount_mountable) (file,
4855                                 flags,
4856                                 cancellable,
4857                                 callback,
4858                                 user_data);
4859 }
4860
4861 /**
4862  * g_file_unmount_mountable_finish:
4863  * @file: input #GFile
4864  * @result: a #GAsyncResult
4865  * @error: a #GError, or %NULL
4866  *
4867  * Finishes an unmount operation, see g_file_unmount_mountable() for details.
4868  *
4869  * Finish an asynchronous unmount operation that was started
4870  * with g_file_unmount_mountable().
4871  *
4872  * Returns: %TRUE if the operation finished successfully.
4873  *     %FALSE otherwise.
4874  *
4875  * Deprecated: 2.22: Use g_file_unmount_mountable_with_operation_finish()
4876  *     instead.
4877  */
4878 gboolean
4879 g_file_unmount_mountable_finish (GFile         *file,
4880                                  GAsyncResult  *result,
4881                                  GError       **error)
4882 {
4883   GFileIface *iface;
4884
4885   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4886   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4887
4888   if (g_async_result_legacy_propagate_error (result, error))
4889     return FALSE;
4890   else if (g_async_result_is_tagged (result, g_file_unmount_mountable_with_operation))
4891     return g_task_propagate_boolean (G_TASK (result), error);
4892
4893   iface = G_FILE_GET_IFACE (file);
4894   return (* iface->unmount_mountable_finish) (file, result, error);
4895 }
4896
4897 /**
4898  * g_file_unmount_mountable_with_operation:
4899  * @file: input #GFile
4900  * @flags: flags affecting the operation
4901  * @mount_operation: (allow-none): a #GMountOperation,
4902  *     or %NULL to avoid user interaction
4903  * @cancellable: (allow-none): optional #GCancellable object,
4904  *     %NULL to ignore
4905  * @callback: (scope async) (allow-none): a #GAsyncReadyCallback to call
4906  *     when the request is satisfied, or %NULL
4907  * @user_data: (closure): the data to pass to callback function
4908  *
4909  * Unmounts a file of type #G_FILE_TYPE_MOUNTABLE.
4910  *
4911  * If @cancellable is not %NULL, then the operation can be cancelled by
4912  * triggering the cancellable object from another thread. If the operation
4913  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4914  *
4915  * When the operation is finished, @callback will be called.
4916  * You can then call g_file_unmount_mountable_finish() to get
4917  * the result of the operation.
4918  *
4919  * Since: 2.22
4920  */
4921 void
4922 g_file_unmount_mountable_with_operation (GFile               *file,
4923                                          GMountUnmountFlags   flags,
4924                                          GMountOperation     *mount_operation,
4925                                          GCancellable        *cancellable,
4926                                          GAsyncReadyCallback  callback,
4927                                          gpointer             user_data)
4928 {
4929   GFileIface *iface;
4930
4931   g_return_if_fail (G_IS_FILE (file));
4932
4933   iface = G_FILE_GET_IFACE (file);
4934
4935   if (iface->unmount_mountable == NULL && iface->unmount_mountable_with_operation == NULL)
4936     {
4937       g_task_report_new_error (file, callback, user_data,
4938                                g_file_unmount_mountable_with_operation,
4939                                G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
4940                                _("Operation not supported"));
4941       return;
4942     }
4943
4944   if (iface->unmount_mountable_with_operation != NULL)
4945     (* iface->unmount_mountable_with_operation) (file,
4946                                                  flags,
4947                                                  mount_operation,
4948                                                  cancellable,
4949                                                  callback,
4950                                                  user_data);
4951   else
4952     (* iface->unmount_mountable) (file,
4953                                   flags,
4954                                   cancellable,
4955                                   callback,
4956                                   user_data);
4957 }
4958
4959 /**
4960  * g_file_unmount_mountable_with_operation_finish:
4961  * @file: input #GFile
4962  * @result: a #GAsyncResult
4963  * @error: a #GError, or %NULL
4964  *
4965  * Finishes an unmount operation,
4966  * see g_file_unmount_mountable_with_operation() for details.
4967  *
4968  * Finish an asynchronous unmount operation that was started
4969  * with g_file_unmount_mountable_with_operation().
4970  *
4971  * Returns: %TRUE if the operation finished successfully.
4972  *     %FALSE otherwise.
4973  *
4974  * Since: 2.22
4975  */
4976 gboolean
4977 g_file_unmount_mountable_with_operation_finish (GFile         *file,
4978                                                 GAsyncResult  *result,
4979                                                 GError       **error)
4980 {
4981   GFileIface *iface;
4982
4983   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4984   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4985
4986   if (g_async_result_legacy_propagate_error (result, error))
4987     return FALSE;
4988   else if (g_async_result_is_tagged (result, g_file_unmount_mountable_with_operation))
4989     return g_task_propagate_boolean (G_TASK (result), error);
4990
4991   iface = G_FILE_GET_IFACE (file);
4992   if (iface->unmount_mountable_with_operation_finish != NULL)
4993     return (* iface->unmount_mountable_with_operation_finish) (file, result, error);
4994   else
4995     return (* iface->unmount_mountable_finish) (file, result, error);
4996 }
4997
4998 /**
4999  * g_file_eject_mountable:
5000  * @file: input #GFile
5001  * @flags: flags affecting the operation
5002  * @cancellable: (allow-none): optional #GCancellable object,
5003  *     %NULL to ignore
5004  * @callback: (scope async) (allow-none): a #GAsyncReadyCallback to call
5005  *     when the request is satisfied, or %NULL
5006  * @user_data: (closure): the data to pass to callback function
5007  *
5008  * Starts an asynchronous eject on a mountable.
5009  * When this operation has completed, @callback will be called with
5010  * @user_user data, and the operation can be finalized with
5011  * g_file_eject_mountable_finish().
5012  *
5013  * If @cancellable is not %NULL, then the operation can be cancelled by
5014  * triggering the cancellable object from another thread. If the operation
5015  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5016  *
5017  * Deprecated: 2.22: Use g_file_eject_mountable_with_operation() instead.
5018  */
5019 void
5020 g_file_eject_mountable (GFile               *file,
5021                         GMountUnmountFlags   flags,
5022                         GCancellable        *cancellable,
5023                         GAsyncReadyCallback  callback,
5024                         gpointer             user_data)
5025 {
5026   GFileIface *iface;
5027
5028   g_return_if_fail (G_IS_FILE (file));
5029
5030   iface = G_FILE_GET_IFACE (file);
5031
5032   if (iface->eject_mountable == NULL)
5033     {
5034       g_task_report_new_error (file, callback, user_data,
5035                                g_file_eject_mountable_with_operation,
5036                                G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
5037                                _("Operation not supported"));
5038       return;
5039     }
5040
5041   (* iface->eject_mountable) (file,
5042                               flags,
5043                               cancellable,
5044                               callback,
5045                               user_data);
5046 }
5047
5048 /**
5049  * g_file_eject_mountable_finish:
5050  * @file: input #GFile
5051  * @result: a #GAsyncResult
5052  * @error: a #GError, or %NULL
5053  *
5054  * Finishes an asynchronous eject operation started by
5055  * g_file_eject_mountable().
5056  *
5057  * Returns: %TRUE if the @file was ejected successfully.
5058  *     %FALSE otherwise.
5059  *
5060  * Deprecated: 2.22: Use g_file_eject_mountable_with_operation_finish()
5061  *     instead.
5062  */
5063 gboolean
5064 g_file_eject_mountable_finish (GFile         *file,
5065                                GAsyncResult  *result,
5066                                GError       **error)
5067 {
5068   GFileIface *iface;
5069
5070   g_return_val_if_fail (G_IS_FILE (file), FALSE);
5071   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
5072
5073   if (g_async_result_legacy_propagate_error (result, error))
5074     return FALSE;
5075   else if (g_async_result_is_tagged (result, g_file_eject_mountable_with_operation))
5076     return g_task_propagate_boolean (G_TASK (result), error);
5077
5078   iface = G_FILE_GET_IFACE (file);
5079   return (* iface->eject_mountable_finish) (file, result, error);
5080 }
5081
5082 /**
5083  * g_file_eject_mountable_with_operation:
5084  * @file: input #GFile
5085  * @flags: flags affecting the operation
5086  * @mount_operation: (allow-none): a #GMountOperation,
5087  *     or %NULL to avoid user interaction
5088  * @cancellable: (allow-none): optional #GCancellable object,
5089  *     %NULL to ignore
5090  * @callback: (scope async) (allow-none): a #GAsyncReadyCallback to call
5091  *     when the request is satisfied, or %NULL
5092  * @user_data: (closure): the data to pass to callback function
5093  *
5094  * Starts an asynchronous eject on a mountable.
5095  * When this operation has completed, @callback will be called with
5096  * @user_user data, and the operation can be finalized with
5097  * g_file_eject_mountable_with_operation_finish().
5098  *
5099  * If @cancellable is not %NULL, then the operation can be cancelled by
5100  * triggering the cancellable object from another thread. If the operation
5101  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5102  *
5103  * Since: 2.22
5104  */
5105 void
5106 g_file_eject_mountable_with_operation (GFile               *file,
5107                                        GMountUnmountFlags   flags,
5108                                        GMountOperation     *mount_operation,
5109                                        GCancellable        *cancellable,
5110                                        GAsyncReadyCallback  callback,
5111                                        gpointer             user_data)
5112 {
5113   GFileIface *iface;
5114
5115   g_return_if_fail (G_IS_FILE (file));
5116
5117   iface = G_FILE_GET_IFACE (file);
5118
5119   if (iface->eject_mountable == NULL && iface->eject_mountable_with_operation == NULL)
5120     {
5121       g_task_report_new_error (file, callback, user_data,
5122                                g_file_eject_mountable_with_operation,
5123                                G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
5124                                _("Operation not supported"));
5125       return;
5126     }
5127
5128   if (iface->eject_mountable_with_operation != NULL)
5129     (* iface->eject_mountable_with_operation) (file,
5130                                                flags,
5131                                                mount_operation,
5132                                                cancellable,
5133                                                callback,
5134                                                user_data);
5135   else
5136     (* iface->eject_mountable) (file,
5137                                 flags,
5138                                 cancellable,
5139                                 callback,
5140                                 user_data);
5141 }
5142
5143 /**
5144  * g_file_eject_mountable_with_operation_finish:
5145  * @file: input #GFile
5146  * @result: a #GAsyncResult
5147  * @error: a #GError, or %NULL
5148  *
5149  * Finishes an asynchronous eject operation started by
5150  * g_file_eject_mountable_with_operation().
5151  *
5152  * Returns: %TRUE if the @file was ejected successfully.
5153  *     %FALSE otherwise.
5154  *
5155  * Since: 2.22
5156  */
5157 gboolean
5158 g_file_eject_mountable_with_operation_finish (GFile         *file,
5159                                               GAsyncResult  *result,
5160                                               GError       **error)
5161 {
5162   GFileIface *iface;
5163
5164   g_return_val_if_fail (G_IS_FILE (file), FALSE);
5165   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
5166
5167   if (g_async_result_legacy_propagate_error (result, error))
5168     return FALSE;
5169   else if (g_async_result_is_tagged (result, g_file_eject_mountable_with_operation))
5170     return g_task_propagate_boolean (G_TASK (result), error);
5171
5172   iface = G_FILE_GET_IFACE (file);
5173   if (iface->eject_mountable_with_operation_finish != NULL)
5174     return (* iface->eject_mountable_with_operation_finish) (file, result, error);
5175   else
5176     return (* iface->eject_mountable_finish) (file, result, error);
5177 }
5178
5179 /**
5180  * g_file_monitor_directory:
5181  * @file: input #GFile
5182  * @flags: a set of #GFileMonitorFlags
5183  * @cancellable: (allow-none): optional #GCancellable object,
5184  *     %NULL to ignore
5185  * @error: a #GError, or %NULL
5186  *
5187  * Obtains a directory monitor for the given file.
5188  * This may fail if directory monitoring is not supported.
5189  *
5190  * If @cancellable is not %NULL, then the operation can be cancelled by
5191  * triggering the cancellable object from another thread. If the operation
5192  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5193  *
5194  * It does not make sense for @flags to contain
5195  * %G_FILE_MONITOR_WATCH_HARD_LINKS, since hard links can not be made to
5196  * directories.  It is not possible to monitor all the files in a
5197  * directory for changes made via hard links; if you want to do this then
5198  * you must register individual watches with g_file_monitor().
5199  *
5200  * Virtual: monitor_dir
5201  * Returns: (transfer full): a #GFileMonitor for the given @file,
5202  *     or %NULL on error.
5203  *     Free the returned object with g_object_unref().
5204  */
5205 GFileMonitor *
5206 g_file_monitor_directory (GFile              *file,
5207                           GFileMonitorFlags   flags,
5208                           GCancellable       *cancellable,
5209                           GError            **error)
5210 {
5211   GFileIface *iface;
5212
5213   g_return_val_if_fail (G_IS_FILE (file), NULL);
5214   g_return_val_if_fail (~flags & G_FILE_MONITOR_WATCH_HARD_LINKS, NULL);
5215
5216   if (g_cancellable_set_error_if_cancelled (cancellable, error))
5217     return NULL;
5218
5219   iface = G_FILE_GET_IFACE (file);
5220
5221   if (iface->monitor_dir == NULL)
5222     {
5223       g_set_error_literal (error, G_IO_ERROR,
5224                            G_IO_ERROR_NOT_SUPPORTED,
5225                            _("Operation not supported"));
5226       return NULL;
5227     }
5228
5229   return (* iface->monitor_dir) (file, flags, cancellable, error);
5230 }
5231
5232 /**
5233  * g_file_monitor_file:
5234  * @file: input #GFile
5235  * @flags: a set of #GFileMonitorFlags
5236  * @cancellable: (allow-none): optional #GCancellable object,
5237  *     %NULL to ignore
5238  * @error: a #GError, or %NULL
5239  *
5240  * Obtains a file monitor for the given file. If no file notification
5241  * mechanism exists, then regular polling of the file is used.
5242  *
5243  * If @cancellable is not %NULL, then the operation can be cancelled by
5244  * triggering the cancellable object from another thread. If the operation
5245  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5246  *
5247  * If @flags contains %G_FILE_MONITOR_WATCH_HARD_LINKS then the monitor
5248  * will also attempt to report changes made to the file via another
5249  * filename (ie, a hard link). Without this flag, you can only rely on
5250  * changes made through the filename contained in @file to be
5251  * reported. Using this flag may result in an increase in resource
5252  * usage, and may not have any effect depending on the #GFileMonitor
5253  * backend and/or filesystem type.
5254  * 
5255  * Returns: (transfer full): a #GFileMonitor for the given @file,
5256  *     or %NULL on error.
5257  *     Free the returned object with g_object_unref().
5258  */
5259 GFileMonitor *
5260 g_file_monitor_file (GFile              *file,
5261                      GFileMonitorFlags   flags,
5262                      GCancellable       *cancellable,
5263                      GError            **error)
5264 {
5265   GFileIface *iface;
5266   GFileMonitor *monitor;
5267
5268   g_return_val_if_fail (G_IS_FILE (file), NULL);
5269
5270   if (g_cancellable_set_error_if_cancelled (cancellable, error))
5271     return NULL;
5272
5273   iface = G_FILE_GET_IFACE (file);
5274
5275   monitor = NULL;
5276
5277   if (iface->monitor_file)
5278     monitor = (* iface->monitor_file) (file, flags, cancellable, NULL);
5279
5280   /* Fallback to polling */
5281   if (monitor == NULL)
5282     monitor = _g_poll_file_monitor_new (file);
5283
5284   return monitor;
5285 }
5286
5287 /**
5288  * g_file_monitor:
5289  * @file: input #GFile
5290  * @flags: a set of #GFileMonitorFlags
5291  * @cancellable: (allow-none): optional #GCancellable object,
5292  *     %NULL to ignore
5293  * @error: a #GError, or %NULL
5294  *
5295  * Obtains a file or directory monitor for the given file,
5296  * depending on the type of the file.
5297  *
5298  * If @cancellable is not %NULL, then the operation can be cancelled by
5299  * triggering the cancellable object from another thread. If the operation
5300  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
5301  *
5302  * Returns: (transfer full): a #GFileMonitor for the given @file,
5303  *     or %NULL on error.
5304  *     Free the returned object with g_object_unref().
5305  *
5306  * Since: 2.18
5307  */
5308 GFileMonitor *
5309 g_file_monitor (GFile              *file,
5310                 GFileMonitorFlags   flags,
5311                 GCancellable       *cancellable,
5312                 GError            **error)
5313 {
5314   if (g_file_query_file_type (file, 0, cancellable) == G_FILE_TYPE_DIRECTORY)
5315     return g_file_monitor_directory (file,
5316                                      flags & ~G_FILE_MONITOR_WATCH_HARD_LINKS,
5317                                      cancellable, error);
5318   else
5319     return g_file_monitor_file (file, flags, cancellable, error);
5320 }
5321
5322 /********************************************
5323  *   Default implementation of async ops    *
5324  ********************************************/
5325
5326 typedef struct {
5327   char *attributes;
5328   GFileQueryInfoFlags flags;
5329 } QueryInfoAsyncData;
5330
5331 static void
5332 query_info_data_free (QueryInfoAsyncData *data)
5333 {
5334   g_free (data->attributes);
5335   g_free (data);
5336 }
5337
5338 static void
5339 query_info_async_thread (GTask         *task,
5340                          gpointer       object,
5341                          gpointer       task_data,
5342                          GCancellable  *cancellable)
5343 {
5344   QueryInfoAsyncData *data = task_data;
5345   GFileInfo *info;
5346   GError *error = NULL;
5347
5348   info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error);
5349   if (info)
5350     g_task_return_pointer (task, info, g_object_unref);
5351   else
5352     g_task_return_error (task, error);
5353 }
5354
5355 static void
5356 g_file_real_query_info_async (GFile               *file,
5357                               const char          *attributes,
5358                               GFileQueryInfoFlags  flags,
5359                               int                  io_priority,
5360                               GCancellable        *cancellable,
5361                               GAsyncReadyCallback  callback,
5362                               gpointer             user_data)
5363 {
5364   GTask *task;
5365   QueryInfoAsyncData *data;
5366
5367   data = g_new0 (QueryInfoAsyncData, 1);
5368   data->attributes = g_strdup (attributes);
5369   data->flags = flags;
5370
5371   task = g_task_new (file, cancellable, callback, user_data);
5372   g_task_set_task_data (task, data, (GDestroyNotify)query_info_data_free);
5373   g_task_set_priority (task, io_priority);
5374   g_task_run_in_thread (task, query_info_async_thread);
5375   g_object_unref (task);
5376 }
5377
5378 static GFileInfo *
5379 g_file_real_query_info_finish (GFile         *file,
5380                                GAsyncResult  *res,
5381                                GError       **error)
5382 {
5383   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5384
5385   return g_task_propagate_pointer (G_TASK (res), error);
5386 }
5387
5388 static void
5389 query_filesystem_info_async_thread (GTask         *task,
5390                                     gpointer       object,
5391                                     gpointer       task_data,
5392                                     GCancellable  *cancellable)
5393 {
5394   const char *attributes = task_data;
5395   GFileInfo *info;
5396   GError *error = NULL;
5397
5398   info = g_file_query_filesystem_info (G_FILE (object), attributes, cancellable, &error);
5399   if (info)
5400     g_task_return_pointer (task, info, g_object_unref);
5401   else
5402     g_task_return_error (task, error);
5403 }
5404
5405 static void
5406 g_file_real_query_filesystem_info_async (GFile               *file,
5407                                          const char          *attributes,
5408                                          int                  io_priority,
5409                                          GCancellable        *cancellable,
5410                                          GAsyncReadyCallback  callback,
5411                                          gpointer             user_data)
5412 {
5413   GTask *task;
5414
5415   task = g_task_new (file, cancellable, callback, user_data);
5416   g_task_set_task_data (task, g_strdup (attributes), g_free);
5417   g_task_set_priority (task, io_priority);
5418   g_task_run_in_thread (task, query_filesystem_info_async_thread);
5419   g_object_unref (task);
5420 }
5421
5422 static GFileInfo *
5423 g_file_real_query_filesystem_info_finish (GFile         *file,
5424                                           GAsyncResult  *res,
5425                                           GError       **error)
5426 {
5427   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5428
5429   return g_task_propagate_pointer (G_TASK (res), error);
5430 }
5431
5432 static void
5433 enumerate_children_async_thread (GTask         *task,
5434                                  gpointer       object,
5435                                  gpointer       task_data,
5436                                  GCancellable  *cancellable)
5437 {
5438   QueryInfoAsyncData *data = task_data;
5439   GFileEnumerator *enumerator;
5440   GError *error = NULL;
5441
5442   enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error);
5443   if (error)
5444     g_task_return_error (task, error);
5445   else
5446     g_task_return_pointer (task, enumerator, g_object_unref);
5447 }
5448
5449 static void
5450 g_file_real_enumerate_children_async (GFile               *file,
5451                                       const char          *attributes,
5452                                       GFileQueryInfoFlags  flags,
5453                                       int                  io_priority,
5454                                       GCancellable        *cancellable,
5455                                       GAsyncReadyCallback  callback,
5456                                       gpointer             user_data)
5457 {
5458   GTask *task;
5459   QueryInfoAsyncData *data;
5460
5461   data = g_new0 (QueryInfoAsyncData, 1);
5462   data->attributes = g_strdup (attributes);
5463   data->flags = flags;
5464
5465   task = g_task_new (file, cancellable, callback, user_data);
5466   g_task_set_task_data (task, data, (GDestroyNotify)query_info_data_free);
5467   g_task_set_priority (task, io_priority);
5468   g_task_run_in_thread (task, enumerate_children_async_thread);
5469   g_object_unref (task);
5470 }
5471
5472 static GFileEnumerator *
5473 g_file_real_enumerate_children_finish (GFile         *file,
5474                                        GAsyncResult  *res,
5475                                        GError       **error)
5476 {
5477   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5478
5479   return g_task_propagate_pointer (G_TASK (res), error);
5480 }
5481
5482 static void
5483 open_read_async_thread (GTask         *task,
5484                         gpointer       object,
5485                         gpointer       task_data,
5486                         GCancellable  *cancellable)
5487 {
5488   GFileInputStream *stream;
5489   GError *error = NULL;
5490
5491   stream = g_file_read (G_FILE (object), cancellable, &error);
5492   if (stream)
5493     g_task_return_pointer (task, stream, g_object_unref);
5494   else
5495     g_task_return_error (task, error);
5496 }
5497
5498 static void
5499 g_file_real_read_async (GFile               *file,
5500                         int                  io_priority,
5501                         GCancellable        *cancellable,
5502                         GAsyncReadyCallback  callback,
5503                         gpointer             user_data)
5504 {
5505   GTask *task;
5506
5507   task = g_task_new (file, cancellable, callback, user_data);
5508   g_task_set_priority (task, io_priority);
5509   g_task_run_in_thread (task, open_read_async_thread);
5510   g_object_unref (task);
5511 }
5512
5513 static GFileInputStream *
5514 g_file_real_read_finish (GFile         *file,
5515                          GAsyncResult  *res,
5516                          GError       **error)
5517 {
5518   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5519
5520   return g_task_propagate_pointer (G_TASK (res), error);
5521 }
5522
5523 static void
5524 append_to_async_thread (GTask         *task,
5525                         gpointer       source_object,
5526                         gpointer       task_data,
5527                         GCancellable  *cancellable)
5528 {
5529   GFileCreateFlags *data = task_data;
5530   GFileOutputStream *stream;
5531   GError *error = NULL;
5532
5533   stream = g_file_append_to (G_FILE (source_object), *data, cancellable, &error);
5534   if (stream)
5535     g_task_return_pointer (task, stream, g_object_unref);
5536   else
5537     g_task_return_error (task, error);
5538 }
5539
5540 static void
5541 g_file_real_append_to_async (GFile               *file,
5542                              GFileCreateFlags     flags,
5543                              int                  io_priority,
5544                              GCancellable        *cancellable,
5545                              GAsyncReadyCallback  callback,
5546                              gpointer             user_data)
5547 {
5548   GFileCreateFlags *data;
5549   GTask *task;
5550
5551   data = g_new0 (GFileCreateFlags, 1);
5552   *data = flags;
5553
5554   task = g_task_new (file, cancellable, callback, user_data);
5555   g_task_set_task_data (task, data, g_free);
5556   g_task_set_priority (task, io_priority);
5557
5558   g_task_run_in_thread (task, append_to_async_thread);
5559   g_object_unref (task);
5560 }
5561
5562 static GFileOutputStream *
5563 g_file_real_append_to_finish (GFile         *file,
5564                               GAsyncResult  *res,
5565                               GError       **error)
5566 {
5567   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5568
5569   return g_task_propagate_pointer (G_TASK (res), error);
5570 }
5571
5572 static void
5573 create_async_thread (GTask         *task,
5574                      gpointer       source_object,
5575                      gpointer       task_data,
5576                      GCancellable  *cancellable)
5577 {
5578   GFileCreateFlags *data = task_data;
5579   GFileOutputStream *stream;
5580   GError *error = NULL;
5581
5582   stream = g_file_create (G_FILE (source_object), *data, cancellable, &error);
5583   if (stream)
5584     g_task_return_pointer (task, stream, g_object_unref);
5585   else
5586     g_task_return_error (task, error);
5587 }
5588
5589 static void
5590 g_file_real_create_async (GFile               *file,
5591                           GFileCreateFlags     flags,
5592                           int                  io_priority,
5593                           GCancellable        *cancellable,
5594                           GAsyncReadyCallback  callback,
5595                           gpointer             user_data)
5596 {
5597   GFileCreateFlags *data;
5598   GTask *task;
5599
5600   data = g_new0 (GFileCreateFlags, 1);
5601   *data = flags;
5602
5603   task = g_task_new (file, cancellable, callback, user_data);
5604   g_task_set_task_data (task, data, g_free);
5605   g_task_set_priority (task, io_priority);
5606
5607   g_task_run_in_thread (task, create_async_thread);
5608   g_object_unref (task);
5609 }
5610
5611 static GFileOutputStream *
5612 g_file_real_create_finish (GFile         *file,
5613                            GAsyncResult  *res,
5614                            GError       **error)
5615 {
5616   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5617
5618   return g_task_propagate_pointer (G_TASK (res), error);
5619 }
5620
5621 typedef struct {
5622   GFileOutputStream *stream;
5623   char *etag;
5624   gboolean make_backup;
5625   GFileCreateFlags flags;
5626 } ReplaceAsyncData;
5627
5628 static void
5629 replace_async_data_free (ReplaceAsyncData *data)
5630 {
5631   if (data->stream)
5632     g_object_unref (data->stream);
5633   g_free (data->etag);
5634   g_free (data);
5635 }
5636
5637 static void
5638 replace_async_thread (GTask         *task,
5639                       gpointer       source_object,
5640                       gpointer       task_data,
5641                       GCancellable  *cancellable)
5642 {
5643   GFileOutputStream *stream;
5644   ReplaceAsyncData *data = task_data;
5645   GError *error = NULL;
5646
5647   stream = g_file_replace (G_FILE (source_object),
5648                            data->etag,
5649                            data->make_backup,
5650                            data->flags,
5651                            cancellable,
5652                            &error);
5653
5654   if (stream)
5655     g_task_return_pointer (task, stream, g_object_unref);
5656   else
5657     g_task_return_error (task, error);
5658 }
5659
5660 static void
5661 g_file_real_replace_async (GFile               *file,
5662                            const char          *etag,
5663                            gboolean             make_backup,
5664                            GFileCreateFlags     flags,
5665                            int                  io_priority,
5666                            GCancellable        *cancellable,
5667                            GAsyncReadyCallback  callback,
5668                            gpointer             user_data)
5669 {
5670   GTask *task;
5671   ReplaceAsyncData *data;
5672
5673   data = g_new0 (ReplaceAsyncData, 1);
5674   data->etag = g_strdup (etag);
5675   data->make_backup = make_backup;
5676   data->flags = flags;
5677
5678   task = g_task_new (file, cancellable, callback, user_data);
5679   g_task_set_task_data (task, data, (GDestroyNotify)replace_async_data_free);
5680   g_task_set_priority (task, io_priority);
5681
5682   g_task_run_in_thread (task, replace_async_thread);
5683   g_object_unref (task);
5684 }
5685
5686 static GFileOutputStream *
5687 g_file_real_replace_finish (GFile         *file,
5688                             GAsyncResult  *res,
5689                             GError       **error)
5690 {
5691   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5692
5693   return g_task_propagate_pointer (G_TASK (res), error);
5694 }
5695
5696 static void
5697 delete_async_thread (GTask        *task,
5698                      gpointer      object,
5699                      gpointer      task_data,
5700                      GCancellable *cancellable)
5701 {
5702   GError *error = NULL;
5703
5704   if (g_file_delete (G_FILE (object), cancellable, &error))
5705     g_task_return_boolean (task, TRUE);
5706   else
5707     g_task_return_error (task, error);
5708 }
5709
5710 static void
5711 g_file_real_delete_async (GFile               *file,
5712                           int                  io_priority,
5713                           GCancellable        *cancellable,
5714                           GAsyncReadyCallback  callback,
5715                           gpointer             user_data)
5716 {
5717   GTask *task;
5718
5719   task = g_task_new (file, cancellable, callback, user_data);
5720   g_task_set_priority (task, io_priority);
5721   g_task_run_in_thread (task, delete_async_thread);
5722   g_object_unref (task);
5723 }
5724
5725 static gboolean
5726 g_file_real_delete_finish (GFile         *file,
5727                            GAsyncResult  *res,
5728                            GError       **error)
5729 {
5730   g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
5731
5732   return g_task_propagate_boolean (G_TASK (res), error);
5733 }
5734
5735 static void
5736 trash_async_thread (GTask        *task,
5737                     gpointer      object,
5738                     gpointer      task_data,
5739                     GCancellable *cancellable)
5740 {
5741   GError *error = NULL;
5742
5743   if (g_file_trash (G_FILE (object), cancellable, &error))
5744     g_task_return_boolean (task, TRUE);
5745   else
5746     g_task_return_error (task, error);
5747 }
5748
5749 static void
5750 g_file_real_trash_async (GFile               *file,
5751                          int                  io_priority,
5752                          GCancellable        *cancellable,
5753                          GAsyncReadyCallback  callback,
5754                          gpointer             user_data)
5755 {
5756   GTask *task;
5757
5758   task = g_task_new (file, cancellable, callback, user_data);
5759   g_task_set_priority (task, io_priority);
5760   g_task_run_in_thread (task, trash_async_thread);
5761   g_object_unref (task);
5762 }
5763
5764 static gboolean
5765 g_file_real_trash_finish (GFile         *file,
5766                           GAsyncResult  *res,
5767                           GError       **error)
5768 {
5769   g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
5770
5771   return g_task_propagate_boolean (G_TASK (res), error);
5772 }
5773
5774 static void
5775 make_directory_async_thread (GTask        *task,
5776                              gpointer      object,
5777                              gpointer      task_data,
5778                              GCancellable *cancellable)
5779 {
5780   GError *error = NULL;
5781
5782   if (g_file_make_directory (G_FILE (object), cancellable, &error))
5783     g_task_return_boolean (task, TRUE);
5784   else
5785     g_task_return_error (task, error);
5786 }
5787
5788 static void
5789 g_file_real_make_directory_async (GFile               *file,
5790                                   int                  io_priority,
5791                                   GCancellable        *cancellable,
5792                                   GAsyncReadyCallback  callback,
5793                                   gpointer             user_data)
5794 {
5795   GTask *task;
5796
5797   task = g_task_new (file, cancellable, callback, user_data);
5798   g_task_set_priority (task, io_priority);
5799   g_task_run_in_thread (task, make_directory_async_thread);
5800   g_object_unref (task);
5801 }
5802
5803 static gboolean
5804 g_file_real_make_directory_finish (GFile         *file,
5805                                    GAsyncResult  *res,
5806                                    GError       **error)
5807 {
5808   g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
5809
5810   return g_task_propagate_boolean (G_TASK (res), error);
5811 }
5812
5813 static void
5814 open_readwrite_async_thread (GTask        *task,
5815                              gpointer      object,
5816                              gpointer      task_data,
5817                              GCancellable *cancellable)
5818 {
5819   GFileIOStream *stream;
5820   GError *error = NULL;
5821
5822   stream = g_file_open_readwrite (G_FILE (object), cancellable, &error);
5823
5824   if (stream == NULL)
5825     g_task_return_error (task, error);
5826   else
5827     g_task_return_pointer (task, stream, g_object_unref);
5828 }
5829
5830 static void
5831 g_file_real_open_readwrite_async (GFile               *file,
5832                                   int                  io_priority,
5833                                   GCancellable        *cancellable,
5834                                   GAsyncReadyCallback  callback,
5835                                   gpointer             user_data)
5836 {
5837   GTask *task;
5838
5839   task = g_task_new (file, cancellable, callback, user_data);
5840   g_task_set_priority (task, io_priority);
5841
5842   g_task_run_in_thread (task, open_readwrite_async_thread);
5843   g_object_unref (task);
5844 }
5845
5846 static GFileIOStream *
5847 g_file_real_open_readwrite_finish (GFile         *file,
5848                                    GAsyncResult  *res,
5849                                    GError       **error)
5850 {
5851   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5852
5853   return g_task_propagate_pointer (G_TASK (res), error);
5854 }
5855
5856 static void
5857 create_readwrite_async_thread (GTask        *task,
5858                                gpointer      object,
5859                                gpointer      task_data,
5860                                GCancellable *cancellable)
5861 {
5862   GFileCreateFlags *data = task_data;
5863   GFileIOStream *stream;
5864   GError *error = NULL;
5865
5866   stream = g_file_create_readwrite (G_FILE (object), *data, cancellable, &error);
5867
5868   if (stream == NULL)
5869     g_task_return_error (task, error);
5870   else
5871     g_task_return_pointer (task, stream, g_object_unref);
5872 }
5873
5874 static void
5875 g_file_real_create_readwrite_async (GFile               *file,
5876                                     GFileCreateFlags     flags,
5877                                     int                  io_priority,
5878                                     GCancellable        *cancellable,
5879                                     GAsyncReadyCallback  callback,
5880                                     gpointer             user_data)
5881 {
5882   GFileCreateFlags *data;
5883   GTask *task;
5884
5885   data = g_new0 (GFileCreateFlags, 1);
5886   *data = flags;
5887
5888   task = g_task_new (file, cancellable, callback, user_data);
5889   g_task_set_task_data (task, data, g_free);
5890   g_task_set_priority (task, io_priority);
5891
5892   g_task_run_in_thread (task, create_readwrite_async_thread);
5893   g_object_unref (task);
5894 }
5895
5896 static GFileIOStream *
5897 g_file_real_create_readwrite_finish (GFile         *file,
5898                                      GAsyncResult  *res,
5899                                      GError       **error)
5900 {
5901   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5902
5903   return g_task_propagate_pointer (G_TASK (res), error);
5904 }
5905
5906 typedef struct {
5907   char *etag;
5908   gboolean make_backup;
5909   GFileCreateFlags flags;
5910 } ReplaceRWAsyncData;
5911
5912 static void
5913 replace_rw_async_data_free (ReplaceRWAsyncData *data)
5914 {
5915   g_free (data->etag);
5916   g_free (data);
5917 }
5918
5919 static void
5920 replace_readwrite_async_thread (GTask        *task,
5921                                 gpointer      object,
5922                                 gpointer      task_data,
5923                                 GCancellable *cancellable)
5924 {
5925   GFileIOStream *stream;
5926   GError *error = NULL;
5927   ReplaceRWAsyncData *data = task_data;
5928
5929   stream = g_file_replace_readwrite (G_FILE (object),
5930                                      data->etag,
5931                                      data->make_backup,
5932                                      data->flags,
5933                                      cancellable,
5934                                      &error);
5935
5936   if (stream == NULL)
5937     g_task_return_error (task, error);
5938   else
5939     g_task_return_pointer (task, stream, g_object_unref);
5940 }
5941
5942 static void
5943 g_file_real_replace_readwrite_async (GFile               *file,
5944                                      const char          *etag,
5945                                      gboolean             make_backup,
5946                                      GFileCreateFlags     flags,
5947                                      int                  io_priority,
5948                                      GCancellable        *cancellable,
5949                                      GAsyncReadyCallback  callback,
5950                                      gpointer             user_data)
5951 {
5952   GTask *task;
5953   ReplaceRWAsyncData *data;
5954
5955   data = g_new0 (ReplaceRWAsyncData, 1);
5956   data->etag = g_strdup (etag);
5957   data->make_backup = make_backup;
5958   data->flags = flags;
5959
5960   task = g_task_new (file, cancellable, callback, user_data);
5961   g_task_set_task_data (task, data, (GDestroyNotify)replace_rw_async_data_free);
5962   g_task_set_priority (task, io_priority);
5963
5964   g_task_run_in_thread (task, replace_readwrite_async_thread);
5965   g_object_unref (task);
5966 }
5967
5968 static GFileIOStream *
5969 g_file_real_replace_readwrite_finish (GFile         *file,
5970                                       GAsyncResult  *res,
5971                                       GError       **error)
5972 {
5973   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
5974
5975   return g_task_propagate_pointer (G_TASK (res), error);
5976 }
5977
5978 static void
5979 set_display_name_async_thread (GTask        *task,
5980                                gpointer      object,
5981                                gpointer      task_data,
5982                                GCancellable *cancellable)
5983 {
5984   GError *error = NULL;
5985   char *name = task_data;
5986   GFile *file;
5987
5988   file = g_file_set_display_name (G_FILE (object), name, cancellable, &error);
5989
5990   if (file == NULL)
5991     g_task_return_error (task, error);
5992   else
5993     g_task_return_pointer (task, file, g_object_unref);
5994 }
5995
5996 static void
5997 g_file_real_set_display_name_async (GFile               *file,
5998                                     const char          *display_name,
5999                                     int                  io_priority,
6000                                     GCancellable        *cancellable,
6001                                     GAsyncReadyCallback  callback,
6002                                     gpointer             user_data)
6003 {
6004   GTask *task;
6005
6006   task = g_task_new (file, cancellable, callback, user_data);
6007   g_task_set_task_data (task, g_strdup (display_name), g_free);
6008   g_task_set_priority (task, io_priority);
6009
6010   g_task_run_in_thread (task, set_display_name_async_thread);
6011   g_object_unref (task);
6012 }
6013
6014 static GFile *
6015 g_file_real_set_display_name_finish (GFile         *file,
6016                                      GAsyncResult  *res,
6017                                      GError       **error)
6018 {
6019   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
6020
6021   return g_task_propagate_pointer (G_TASK (res), error);
6022 }
6023
6024 typedef struct {
6025   GFileQueryInfoFlags flags;
6026   GFileInfo *info;
6027   gboolean res;
6028   GError *error;
6029 } SetInfoAsyncData;
6030
6031 static void
6032 set_info_data_free (SetInfoAsyncData *data)
6033 {
6034   if (data->info)
6035     g_object_unref (data->info);
6036   if (data->error)
6037     g_error_free (data->error);
6038   g_free (data);
6039 }
6040
6041 static void
6042 set_info_async_thread (GTask        *task,
6043                        gpointer      object,
6044                        gpointer      task_data,
6045                        GCancellable *cancellable)
6046 {
6047   SetInfoAsyncData *data = task_data;
6048
6049   data->error = NULL;
6050   data->res = g_file_set_attributes_from_info (G_FILE (object),
6051                                                data->info,
6052                                                data->flags,
6053                                                cancellable,
6054                                                &data->error);
6055 }
6056
6057 static void
6058 g_file_real_set_attributes_async (GFile               *file,
6059                                   GFileInfo           *info,
6060                                   GFileQueryInfoFlags  flags,
6061                                   int                  io_priority,
6062                                   GCancellable        *cancellable,
6063                                   GAsyncReadyCallback  callback,
6064                                   gpointer             user_data)
6065 {
6066   GTask *task;
6067   SetInfoAsyncData *data;
6068
6069   data = g_new0 (SetInfoAsyncData, 1);
6070   data->info = g_file_info_dup (info);
6071   data->flags = flags;
6072
6073   task = g_task_new (file, cancellable, callback, user_data);
6074   g_task_set_task_data (task, data, (GDestroyNotify)set_info_data_free);
6075   g_task_set_priority (task, io_priority);
6076
6077   g_task_run_in_thread (task, set_info_async_thread);
6078   g_object_unref (task);
6079 }
6080
6081 static gboolean
6082 g_file_real_set_attributes_finish (GFile         *file,
6083                                    GAsyncResult  *res,
6084                                    GFileInfo    **info,
6085                                    GError       **error)
6086 {
6087   SetInfoAsyncData *data;
6088
6089   g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
6090
6091   data = g_task_get_task_data (G_TASK (res));
6092
6093   if (info)
6094     *info = g_object_ref (data->info);
6095
6096   if (error != NULL && data->error)
6097     *error = g_error_copy (data->error);
6098
6099   return data->res;
6100 }
6101
6102 static void
6103 find_enclosing_mount_async_thread (GTask        *task,
6104                                    gpointer      object,
6105                                    gpointer      task_data,
6106                                    GCancellable *cancellable)
6107 {
6108   GError *error = NULL;
6109   GMount *mount;
6110
6111   mount = g_file_find_enclosing_mount (G_FILE (object), cancellable, &error);
6112
6113   if (mount == NULL)
6114     g_task_return_error (task, error);
6115   else
6116     g_task_return_pointer (task, mount, g_object_unref);
6117 }
6118
6119 static void
6120 g_file_real_find_enclosing_mount_async (GFile               *file,
6121                                         int                  io_priority,
6122                                         GCancellable        *cancellable,
6123                                         GAsyncReadyCallback  callback,
6124                                         gpointer             user_data)
6125 {
6126   GTask *task;
6127
6128   task = g_task_new (file, cancellable, callback, user_data);
6129   g_task_set_priority (task, io_priority);
6130
6131   g_task_run_in_thread (task, find_enclosing_mount_async_thread);
6132   g_object_unref (task);
6133 }
6134
6135 static GMount *
6136 g_file_real_find_enclosing_mount_finish (GFile         *file,
6137                                          GAsyncResult  *res,
6138                                          GError       **error)
6139 {
6140   g_return_val_if_fail (g_task_is_valid (res, file), NULL);
6141
6142   return g_task_propagate_pointer (G_TASK (res), error);
6143 }
6144
6145
6146 typedef struct {
6147   GFile *source;
6148   GFile *destination;
6149   GFileCopyFlags flags;
6150   GFileProgressCallback progress_cb;
6151   gpointer progress_cb_data;
6152 } CopyAsyncData;
6153
6154 static void
6155 copy_async_data_free (CopyAsyncData *data)
6156 {
6157   g_object_unref (data->source);
6158   g_object_unref (data->destination);
6159   g_slice_free (CopyAsyncData, data);
6160 }
6161
6162 typedef struct {
6163   CopyAsyncData *data;
6164   goffset current_num_bytes;
6165   goffset total_num_bytes;
6166 } ProgressData;
6167
6168 static gboolean
6169 copy_async_progress_in_main (gpointer user_data)
6170 {
6171   ProgressData *progress = user_data;
6172   CopyAsyncData *data = progress->data;
6173
6174   data->progress_cb (progress->current_num_bytes,
6175                      progress->total_num_bytes,
6176                      data->progress_cb_data);
6177
6178   return FALSE;
6179 }
6180
6181 static void
6182 copy_async_progress_callback (goffset  current_num_bytes,
6183                               goffset  total_num_bytes,
6184                               gpointer user_data)
6185 {
6186   GTask *task = user_data;
6187   CopyAsyncData *data = g_task_get_task_data (task);
6188   ProgressData *progress;
6189
6190   progress = g_new (ProgressData, 1);
6191   progress->data = data;
6192   progress->current_num_bytes = current_num_bytes;
6193   progress->total_num_bytes = total_num_bytes;
6194
6195   g_main_context_invoke_full (g_task_get_context (task),
6196                               g_task_get_priority (task),
6197                               copy_async_progress_in_main,
6198                               progress,
6199                               g_free);
6200 }
6201
6202 static void
6203 copy_async_thread (GTask        *task,
6204                    gpointer      source,
6205                    gpointer      task_data,
6206                    GCancellable *cancellable)
6207 {
6208   CopyAsyncData *data = task_data;
6209   gboolean result;
6210   GError *error = NULL;
6211
6212   result = g_file_copy (data->source,
6213                         data->destination,
6214                         data->flags,
6215                         cancellable,
6216                         (data->progress_cb != NULL) ? copy_async_progress_callback : NULL,
6217                         task,
6218                         &error);
6219   if (result)
6220     g_task_return_boolean (task, TRUE);
6221   else
6222     g_task_return_error (task, error);
6223 }
6224
6225 static void
6226 g_file_real_copy_async (GFile                  *source,
6227                         GFile                  *destination,
6228                         GFileCopyFlags          flags,
6229                         int                     io_priority,
6230                         GCancellable           *cancellable,
6231                         GFileProgressCallback   progress_callback,
6232                         gpointer                progress_callback_data,
6233                         GAsyncReadyCallback     callback,
6234                         gpointer                user_data)
6235 {
6236   GTask *task;
6237   CopyAsyncData *data;
6238
6239   data = g_slice_new (CopyAsyncData);
6240   data->source = g_object_ref (source);
6241   data->destination = g_object_ref (destination);
6242   data->flags = flags;
6243   data->progress_cb = progress_callback;
6244   data->progress_cb_data = progress_callback_data;
6245
6246   task = g_task_new (source, cancellable, callback, user_data);
6247   g_task_set_task_data (task, data, (GDestroyNotify)copy_async_data_free);
6248   g_task_set_priority (task, io_priority);
6249   g_task_run_in_thread (task, copy_async_thread);
6250   g_object_unref (task);
6251 }
6252
6253 static gboolean
6254 g_file_real_copy_finish (GFile        *file,
6255                          GAsyncResult *res,
6256                          GError      **error)
6257 {
6258   g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
6259
6260   return g_task_propagate_boolean (G_TASK (res), error);
6261 }
6262
6263
6264 /********************************************
6265  *   Default VFS operations                 *
6266  ********************************************/
6267
6268 /**
6269  * g_file_new_for_path:
6270  * @path: a string containing a relative or absolute path.
6271  *     The string must be encoded in the glib filename encoding.
6272  *
6273  * Constructs a #GFile for a given path. This operation never
6274  * fails, but the returned object might not support any I/O
6275  * operation if @path is malformed.
6276  *
6277  * Returns: (transfer full): a new #GFile for the given @path.
6278  *   Free the returned object with g_object_unref().
6279  */
6280 GFile *
6281 g_file_new_for_path (const char *path)
6282 {
6283   g_return_val_if_fail (path != NULL, NULL);
6284
6285   return g_vfs_get_file_for_path (g_vfs_get_default (), path);
6286 }
6287
6288 /**
6289  * g_file_new_for_uri:
6290  * @uri: a UTF-8 string containing a URI
6291  *
6292  * Constructs a #GFile for a given URI. This operation never
6293  * fails, but the returned object might not support any I/O
6294  * operation if @uri is malformed or if the uri type is
6295  * not supported.
6296  *
6297  * Returns: (transfer full): a new #GFile for the given @uri.
6298  *     Free the returned object with g_object_unref().
6299  */
6300 GFile *
6301 g_file_new_for_uri (const char *uri)
6302 {
6303   g_return_val_if_fail (uri != NULL, NULL);
6304
6305   return g_vfs_get_file_for_uri (g_vfs_get_default (), uri);
6306 }
6307
6308 /**
6309  * g_file_new_tmp:
6310  * @tmpl: (type filename) (allow-none): Template for the file
6311  *   name, as in g_file_open_tmp(), or %NULL for a default template
6312  * @iostream: (out): on return, a #GFileIOStream for the created file
6313  * @error: a #GError, or %NULL
6314  *
6315  * Opens a file in the preferred directory for temporary files (as
6316  * returned by g_get_tmp_dir()) and returns a #GFile and
6317  * #GFileIOStream pointing to it.
6318  *
6319  * @tmpl should be a string in the GLib file name encoding
6320  * containing a sequence of six 'X' characters, and containing no
6321  * directory components. If it is %NULL, a default template is used.
6322  *
6323  * Unlike the other #GFile constructors, this will return %NULL if
6324  * a temporary file could not be created.
6325  *
6326  * Returns: (transfer full): a new #GFile.
6327  *     Free the returned object with g_object_unref().
6328  *
6329  * Since: 2.32
6330  */
6331 GFile *
6332 g_file_new_tmp (const char     *tmpl,
6333                 GFileIOStream **iostream,
6334                 GError        **error)
6335 {
6336   gint fd;
6337   gchar *path;
6338   GFile *file;
6339   GFileOutputStream *output;
6340
6341   g_return_val_if_fail (iostream != NULL, NULL);
6342
6343   fd = g_file_open_tmp (tmpl, &path, error);
6344   if (fd == -1)
6345     return NULL;
6346
6347   file = g_file_new_for_path (path);
6348
6349   output = _g_local_file_output_stream_new (fd);
6350   *iostream = _g_local_file_io_stream_new (G_LOCAL_FILE_OUTPUT_STREAM (output));
6351
6352   g_object_unref (output);
6353   g_free (path);
6354
6355   return file;
6356 }
6357
6358 /**
6359  * g_file_parse_name:
6360  * @parse_name: a file name or path to be parsed
6361  *
6362  * Constructs a #GFile with the given @parse_name (i.e. something
6363  * given by g_file_get_parse_name()). This operation never fails,
6364  * but the returned object might not support any I/O operation if
6365  * the @parse_name cannot be parsed.
6366  *
6367  * Returns: (transfer full): a new #GFile.
6368  */
6369 GFile *
6370 g_file_parse_name (const char *parse_name)
6371 {
6372   g_return_val_if_fail (parse_name != NULL, NULL);
6373
6374   return g_vfs_parse_name (g_vfs_get_default (), parse_name);
6375 }
6376
6377 static gboolean
6378 is_valid_scheme_character (char c)
6379 {
6380   return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.';
6381 }
6382
6383 /* Following RFC 2396, valid schemes are built like:
6384  *       scheme        = alpha *( alpha | digit | "+" | "-" | "." )
6385  */
6386 static gboolean
6387 has_valid_scheme (const char *uri)
6388 {
6389   const char *p;
6390
6391   p = uri;
6392
6393   if (!g_ascii_isalpha (*p))
6394     return FALSE;
6395
6396   do {
6397     p++;
6398   } while (is_valid_scheme_character (*p));
6399
6400   return *p == ':';
6401 }
6402
6403 static GFile *
6404 new_for_cmdline_arg (const gchar *arg,
6405                      const gchar *cwd)
6406 {
6407   GFile *file;
6408   char *filename;
6409
6410   if (g_path_is_absolute (arg))
6411     return g_file_new_for_path (arg);
6412
6413   if (has_valid_scheme (arg))
6414     return g_file_new_for_uri (arg);
6415
6416   if (cwd == NULL)
6417     {
6418       char *current_dir;
6419
6420       current_dir = g_get_current_dir ();
6421       filename = g_build_filename (current_dir, arg, NULL);
6422       g_free (current_dir);
6423     }
6424   else
6425     filename = g_build_filename (cwd, arg, NULL);
6426
6427   file = g_file_new_for_path (filename);
6428   g_free (filename);
6429
6430   return file;
6431 }
6432
6433 /**
6434  * g_file_new_for_commandline_arg:
6435  * @arg: a command line string
6436  *
6437  * Creates a #GFile with the given argument from the command line.
6438  * The value of @arg can be either a URI, an absolute path or a
6439  * relative path resolved relative to the current working directory.
6440  * This operation never fails, but the returned object might not
6441  * support any I/O operation if @arg points to a malformed path.
6442  *
6443  * Note that on Windows, this function expects its argument to be in
6444  * UTF-8 -- not the system code page.  This means that you
6445  * should not use this function with string from argv as it is passed
6446  * to main().  g_win32_get_command_line() will return a UTF-8 version of
6447  * the commandline.  #GApplication also uses UTF-8 but
6448  * g_application_command_line_create_file_for_arg() may be more useful
6449  * for you there.  It is also always possible to use this function with
6450  * #GOptionContext arguments of type %G_OPTION_ARG_FILENAME.
6451  *
6452  * Returns: (transfer full): a new #GFile.
6453  *    Free the returned object with g_object_unref().
6454  */
6455 GFile *
6456 g_file_new_for_commandline_arg (const char *arg)
6457 {
6458   g_return_val_if_fail (arg != NULL, NULL);
6459
6460   return new_for_cmdline_arg (arg, NULL);
6461 }
6462
6463 /**
6464  * g_file_new_for_commandline_arg_and_cwd:
6465  * @arg: a command line string
6466  * @cwd: the current working directory of the commandline
6467  *
6468  * Creates a #GFile with the given argument from the command line.
6469  *
6470  * This function is similar to g_file_new_for_commandline_arg() except
6471  * that it allows for passing the current working directory as an
6472  * argument instead of using the current working directory of the
6473  * process.
6474  *
6475  * This is useful if the commandline argument was given in a context
6476  * other than the invocation of the current process.
6477  *
6478  * See also g_application_command_line_create_file_for_arg().
6479  *
6480  * Returns: (transfer full): a new #GFile
6481  *
6482  * Since: 2.36
6483  **/
6484 GFile *
6485 g_file_new_for_commandline_arg_and_cwd (const gchar *arg,
6486                                         const gchar *cwd)
6487 {
6488   g_return_val_if_fail (arg != NULL, NULL);
6489   g_return_val_if_fail (cwd != NULL, NULL);
6490
6491   return new_for_cmdline_arg (arg, cwd);
6492 }
6493
6494 /**
6495  * g_file_mount_enclosing_volume:
6496  * @location: input #GFile
6497  * @flags: flags affecting the operation
6498  * @mount_operation: (allow-none): a #GMountOperation
6499  *     or %NULL to avoid user interaction
6500  * @cancellable: (allow-none): optional #GCancellable object,
6501  *     %NULL to ignore
6502  * @callback: (allow-none): a #GAsyncReadyCallback to call
6503  *     when the request is satisfied, or %NULL
6504  * @user_data: the data to pass to callback function
6505  *
6506  * Starts a @mount_operation, mounting the volume that contains
6507  * the file @location.
6508  *
6509  * When this operation has completed, @callback will be called with
6510  * @user_user data, and the operation can be finalized with
6511  * g_file_mount_enclosing_volume_finish().
6512  *
6513  * If @cancellable is not %NULL, then the operation can be cancelled by
6514  * triggering the cancellable object from another thread. If the operation
6515  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
6516  */
6517 void
6518 g_file_mount_enclosing_volume (GFile               *location,
6519                                GMountMountFlags     flags,
6520                                GMountOperation     *mount_operation,
6521                                GCancellable        *cancellable,
6522                                GAsyncReadyCallback  callback,
6523                                gpointer             user_data)
6524 {
6525   GFileIface *iface;
6526
6527   g_return_if_fail (G_IS_FILE (location));
6528
6529   iface = G_FILE_GET_IFACE (location);
6530
6531   if (iface->mount_enclosing_volume == NULL)
6532     {
6533       g_task_report_new_error (location, callback, user_data,
6534                                g_file_mount_enclosing_volume,
6535                                G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
6536                                _("volume doesn't implement mount"));
6537       return;
6538     }
6539
6540   (* iface->mount_enclosing_volume) (location, flags, mount_operation, cancellable, callback, user_data);
6541
6542 }
6543
6544 /**
6545  * g_file_mount_enclosing_volume_finish:
6546  * @location: input #GFile
6547  * @result: a #GAsyncResult
6548  * @error: a #GError, or %NULL
6549  *
6550  * Finishes a mount operation started by g_file_mount_enclosing_volume().
6551  *
6552  * Returns: %TRUE if successful. If an error has occurred,
6553  *     this function will return %FALSE and set @error
6554  *     appropriately if present.
6555  */
6556 gboolean
6557 g_file_mount_enclosing_volume_finish (GFile         *location,
6558                                       GAsyncResult  *result,
6559                                       GError       **error)
6560 {
6561   GFileIface *iface;
6562
6563   g_return_val_if_fail (G_IS_FILE (location), FALSE);
6564   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
6565
6566   if (g_async_result_legacy_propagate_error (result, error))
6567     return FALSE;
6568   else if (g_async_result_is_tagged (result, g_file_mount_enclosing_volume))
6569     return g_task_propagate_boolean (G_TASK (result), error);
6570
6571   iface = G_FILE_GET_IFACE (location);
6572
6573   return (* iface->mount_enclosing_volume_finish) (location, result, error);
6574 }
6575
6576 /********************************************
6577  *   Utility functions                      *
6578  ********************************************/
6579
6580 /**
6581  * g_file_query_default_handler:
6582  * @file: a #GFile to open
6583  * @cancellable: optional #GCancellable object, %NULL to ignore
6584  * @error: a #GError, or %NULL
6585  *
6586  * Returns the #GAppInfo that is registered as the default
6587  * application to handle the file specified by @file.
6588  *
6589  * If @cancellable is not %NULL, then the operation can be cancelled by
6590  * triggering the cancellable object from another thread. If the operation
6591  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
6592  *
6593  * Returns: (transfer full): a #GAppInfo if the handle was found,
6594  *     %NULL if there were errors.
6595  *     When you are done with it, release it with g_object_unref()
6596  */
6597 GAppInfo *
6598 g_file_query_default_handler (GFile         *file,
6599                               GCancellable  *cancellable,
6600                               GError       **error)
6601 {
6602   char *uri_scheme;
6603   const char *content_type;
6604   GAppInfo *appinfo;
6605   GFileInfo *info;
6606   char *path;
6607
6608   uri_scheme = g_file_get_uri_scheme (file);
6609   if (uri_scheme && uri_scheme[0] != '\0')
6610     {
6611       appinfo = g_app_info_get_default_for_uri_scheme (uri_scheme);
6612       g_free (uri_scheme);
6613
6614       if (appinfo != NULL)
6615         return appinfo;
6616     }
6617
6618   info = g_file_query_info (file,
6619                             G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
6620                             0,
6621                             cancellable,
6622                             error);
6623   if (info == NULL)
6624     return NULL;
6625
6626   appinfo = NULL;
6627
6628   content_type = g_file_info_get_content_type (info);
6629   if (content_type)
6630     {
6631       /* Don't use is_native(), as we want to support fuse paths if available */
6632       path = g_file_get_path (file);
6633       appinfo = g_app_info_get_default_for_type (content_type,
6634                                                  path == NULL);
6635       g_free (path);
6636     }
6637
6638   g_object_unref (info);
6639
6640   if (appinfo != NULL)
6641     return appinfo;
6642
6643   g_set_error_literal (error, G_IO_ERROR,
6644                        G_IO_ERROR_NOT_SUPPORTED,
6645                        _("No application is registered as handling this file"));
6646   return NULL;
6647 }
6648
6649 #define GET_CONTENT_BLOCK_SIZE 8192
6650
6651 /**
6652  * g_file_load_contents:
6653  * @file: input #GFile
6654  * @cancellable: optional #GCancellable object, %NULL to ignore
6655  * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
6656  * @length: (out) (allow-none): a location to place the length of the contents of the file,
6657  *    or %NULL if the length is not needed
6658  * @etag_out: (out) (allow-none): a location to place the current entity tag for the file,
6659  *    or %NULL if the entity tag is not needed
6660  * @error: a #GError, or %NULL
6661  *
6662  * Loads the content of the file into memory. The data is always
6663  * zero-terminated, but this is not included in the resultant @length.
6664  * The returned @content should be freed with g_free() when no longer
6665  * needed.
6666  *
6667  * If @cancellable is not %NULL, then the operation can be cancelled by
6668  * triggering the cancellable object from another thread. If the operation
6669  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
6670  *
6671  * Returns: %TRUE if the @file's contents were successfully loaded.
6672  *     %FALSE if there were errors.
6673  */
6674 gboolean
6675 g_file_load_contents (GFile         *file,
6676                       GCancellable  *cancellable,
6677                       char         **contents,
6678                       gsize         *length,
6679                       char         **etag_out,
6680                       GError       **error)
6681 {
6682   GFileInputStream *in;
6683   GByteArray *content;
6684   gsize pos;
6685   gssize res;
6686   GFileInfo *info;
6687
6688   g_return_val_if_fail (G_IS_FILE (file), FALSE);
6689   g_return_val_if_fail (contents != NULL, FALSE);
6690
6691   in = g_file_read (file, cancellable, error);
6692   if (in == NULL)
6693     return FALSE;
6694
6695   content = g_byte_array_new ();
6696   pos = 0;
6697
6698   g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
6699   while ((res = g_input_stream_read (G_INPUT_STREAM (in),
6700                                      content->data + pos,
6701                                      GET_CONTENT_BLOCK_SIZE,
6702                                      cancellable, error)) > 0)
6703     {
6704       pos += res;
6705       g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
6706     }
6707
6708   if (etag_out)
6709     {
6710       *etag_out = NULL;
6711
6712       info = g_file_input_stream_query_info (in,
6713                                              G_FILE_ATTRIBUTE_ETAG_VALUE,
6714                                              cancellable,
6715                                              NULL);
6716       if (info)
6717         {
6718           *etag_out = g_strdup (g_file_info_get_etag (info));
6719           g_object_unref (info);
6720         }
6721     }
6722
6723   /* Ignore errors on close */
6724   g_input_stream_close (G_INPUT_STREAM (in), cancellable, NULL);
6725   g_object_unref (in);
6726
6727   if (res < 0)
6728     {
6729       /* error is set already */
6730       g_byte_array_free (content, TRUE);
6731       return FALSE;
6732     }
6733
6734   if (length)
6735     *length = pos;
6736
6737   /* Zero terminate (we got an extra byte allocated for this */
6738   content->data[pos] = 0;
6739
6740   *contents = (char *)g_byte_array_free (content, FALSE);
6741
6742   return TRUE;
6743 }
6744
6745 typedef struct {
6746   GTask *task;
6747   GFileReadMoreCallback read_more_callback;
6748   GByteArray *content;
6749   gsize pos;
6750   char *etag;
6751 } LoadContentsData;
6752
6753
6754 static void
6755 load_contents_data_free (LoadContentsData *data)
6756 {
6757   if (data->content)
6758     g_byte_array_free (data->content, TRUE);
6759   g_free (data->etag);
6760   g_free (data);
6761 }
6762
6763 static void
6764 load_contents_close_callback (GObject      *obj,
6765                               GAsyncResult *close_res,
6766                               gpointer      user_data)
6767 {
6768   GInputStream *stream = G_INPUT_STREAM (obj);
6769   LoadContentsData *data = user_data;
6770
6771   /* Ignore errors here, we're only reading anyway */
6772   g_input_stream_close_finish (stream, close_res, NULL);
6773   g_object_unref (stream);
6774
6775   g_task_return_boolean (data->task, TRUE);
6776   g_object_unref (data->task);
6777 }
6778
6779 static void
6780 load_contents_fstat_callback (GObject      *obj,
6781                               GAsyncResult *stat_res,
6782                               gpointer      user_data)
6783 {
6784   GInputStream *stream = G_INPUT_STREAM (obj);
6785   LoadContentsData *data = user_data;
6786   GFileInfo *info;
6787
6788   info = g_file_input_stream_query_info_finish (G_FILE_INPUT_STREAM (stream),
6789                                                 stat_res, NULL);
6790   if (info)
6791     {
6792       data->etag = g_strdup (g_file_info_get_etag (info));
6793       g_object_unref (info);
6794     }
6795
6796   g_input_stream_close_async (stream, 0,
6797                               g_task_get_cancellable (data->task),
6798                               load_contents_close_callback, data);
6799 }
6800
6801 static void
6802 load_contents_read_callback (GObject      *obj,
6803                              GAsyncResult *read_res,
6804                              gpointer      user_data)
6805 {
6806   GInputStream *stream = G_INPUT_STREAM (obj);
6807   LoadContentsData *data = user_data;
6808   GError *error = NULL;
6809   gssize read_size;
6810
6811   read_size = g_input_stream_read_finish (stream, read_res, &error);
6812
6813   if (read_size < 0)
6814     {
6815       g_task_return_error (data->task, error);
6816       g_object_unref (data->task);
6817
6818       /* Close the file ignoring any error */
6819       g_input_stream_close_async (stream, 0, NULL, NULL, NULL);
6820       g_object_unref (stream);
6821     }
6822   else if (read_size == 0)
6823     {
6824       g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
6825                                             G_FILE_ATTRIBUTE_ETAG_VALUE,
6826                                             0,
6827                                             g_task_get_cancellable (data->task),
6828                                             load_contents_fstat_callback,
6829                                             data);
6830     }
6831   else if (read_size > 0)
6832     {
6833       data->pos += read_size;
6834
6835       g_byte_array_set_size (data->content,
6836                              data->pos + GET_CONTENT_BLOCK_SIZE);
6837
6838
6839       if (data->read_more_callback &&
6840           !data->read_more_callback ((char *)data->content->data, data->pos,
6841                                      g_async_result_get_user_data (G_ASYNC_RESULT (data->task))))
6842         g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
6843                                               G_FILE_ATTRIBUTE_ETAG_VALUE,
6844                                               0,
6845                                               g_task_get_cancellable (data->task),
6846                                               load_contents_fstat_callback,
6847                                               data);
6848       else
6849         g_input_stream_read_async (stream,
6850                                    data->content->data + data->pos,
6851                                    GET_CONTENT_BLOCK_SIZE,
6852                                    0,
6853                                    g_task_get_cancellable (data->task),
6854                                    load_contents_read_callback,
6855                                    data);
6856     }
6857 }
6858
6859 static void
6860 load_contents_open_callback (GObject      *obj,
6861                              GAsyncResult *open_res,
6862                              gpointer      user_data)
6863 {
6864   GFile *file = G_FILE (obj);
6865   GFileInputStream *stream;
6866   LoadContentsData *data = user_data;
6867   GError *error = NULL;
6868
6869   stream = g_file_read_finish (file, open_res, &error);
6870
6871   if (stream)
6872     {
6873       g_byte_array_set_size (data->content,
6874                              data->pos + GET_CONTENT_BLOCK_SIZE);
6875       g_input_stream_read_async (G_INPUT_STREAM (stream),
6876                                  data->content->data + data->pos,
6877                                  GET_CONTENT_BLOCK_SIZE,
6878                                  0,
6879                                  g_task_get_cancellable (data->task),
6880                                  load_contents_read_callback,
6881                                  data);
6882     }
6883   else
6884     {
6885       g_task_return_error (data->task, error);
6886       g_object_unref (data->task);
6887     }
6888 }
6889
6890 /**
6891  * g_file_load_partial_contents_async: (skip)
6892  * @file: input #GFile
6893  * @cancellable: optional #GCancellable object, %NULL to ignore
6894  * @read_more_callback: a #GFileReadMoreCallback to receive partial data
6895  *     and to specify whether further data should be read
6896  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
6897  * @user_data: the data to pass to the callback functions
6898  *
6899  * Reads the partial contents of a file. A #GFileReadMoreCallback should
6900  * be used to stop reading from the file when appropriate, else this
6901  * function will behave exactly as g_file_load_contents_async(). This
6902  * operation can be finished by g_file_load_partial_contents_finish().
6903  *
6904  * Users of this function should be aware that @user_data is passed to
6905  * both the @read_more_callback and the @callback.
6906  *
6907  * If @cancellable is not %NULL, then the operation can be cancelled by
6908  * triggering the cancellable object from another thread. If the operation
6909  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
6910  */
6911 void
6912 g_file_load_partial_contents_async (GFile                 *file,
6913                                     GCancellable          *cancellable,
6914                                     GFileReadMoreCallback  read_more_callback,
6915                                     GAsyncReadyCallback    callback,
6916                                     gpointer               user_data)
6917 {
6918   LoadContentsData *data;
6919
6920   g_return_if_fail (G_IS_FILE (file));
6921
6922   data = g_new0 (LoadContentsData, 1);
6923   data->read_more_callback = read_more_callback;
6924   data->content = g_byte_array_new ();
6925
6926   data->task = g_task_new (file, cancellable, callback, user_data);
6927   g_task_set_task_data (data->task, data, (GDestroyNotify)load_contents_data_free);
6928
6929   g_file_read_async (file,
6930                      0,
6931                      g_task_get_cancellable (data->task),
6932                      load_contents_open_callback,
6933                      data);
6934 }
6935
6936 /**
6937  * g_file_load_partial_contents_finish:
6938  * @file: input #GFile
6939  * @res: a #GAsyncResult
6940  * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
6941  * @length: (out) (allow-none): a location to place the length of the contents of the file,
6942  *     or %NULL if the length is not needed
6943  * @etag_out: (out) (allow-none): a location to place the current entity tag for the file,
6944  *     or %NULL if the entity tag is not needed
6945  * @error: a #GError, or %NULL
6946  *
6947  * Finishes an asynchronous partial load operation that was started
6948  * with g_file_load_partial_contents_async(). The data is always
6949  * zero-terminated, but this is not included in the resultant @length.
6950  * The returned @content should be freed with g_free() when no longer
6951  * needed.
6952  *
6953  * Returns: %TRUE if the load was successful. If %FALSE and @error is
6954  *     present, it will be set appropriately.
6955  */
6956 gboolean
6957 g_file_load_partial_contents_finish (GFile         *file,
6958                                      GAsyncResult  *res,
6959                                      char         **contents,
6960                                      gsize         *length,
6961                                      char         **etag_out,
6962                                      GError       **error)
6963 {
6964   GTask *task;
6965   LoadContentsData *data;
6966
6967   g_return_val_if_fail (G_IS_FILE (file), FALSE);
6968   g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
6969   g_return_val_if_fail (contents != NULL, FALSE);
6970
6971   task = G_TASK (res);
6972
6973   if (!g_task_propagate_boolean (task, error))
6974     {
6975       if (length)
6976         *length = 0;
6977       return FALSE;
6978     }
6979
6980   data = g_task_get_task_data (task);
6981
6982   if (length)
6983     *length = data->pos;
6984
6985   if (etag_out)
6986     {
6987       *etag_out = data->etag;
6988       data->etag = NULL;
6989     }
6990
6991   /* Zero terminate */
6992   g_byte_array_set_size (data->content, data->pos + 1);
6993   data->content->data[data->pos] = 0;
6994
6995   *contents = (char *)g_byte_array_free (data->content, FALSE);
6996   data->content = NULL;
6997
6998   return TRUE;
6999 }
7000
7001 /**
7002  * g_file_load_contents_async:
7003  * @file: input #GFile
7004  * @cancellable: optional #GCancellable object, %NULL to ignore
7005  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
7006  * @user_data: the data to pass to callback function
7007  *
7008  * Starts an asynchronous load of the @file's contents.
7009  *
7010  * For more details, see g_file_load_contents() which is
7011  * the synchronous version of this call.
7012  *
7013  * When the load operation has completed, @callback will be called
7014  * with @user data. To finish the operation, call
7015  * g_file_load_contents_finish() with the #GAsyncResult returned by
7016  * the @callback.
7017  *
7018  * If @cancellable is not %NULL, then the operation can be cancelled by
7019  * triggering the cancellable object from another thread. If the operation
7020  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7021  */
7022 void
7023 g_file_load_contents_async (GFile               *file,
7024                            GCancellable        *cancellable,
7025                            GAsyncReadyCallback  callback,
7026                            gpointer             user_data)
7027 {
7028   g_file_load_partial_contents_async (file,
7029                                       cancellable,
7030                                       NULL,
7031                                       callback, user_data);
7032 }
7033
7034 /**
7035  * g_file_load_contents_finish:
7036  * @file: input #GFile
7037  * @res: a #GAsyncResult
7038  * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
7039  * @length: (out) (allow-none): a location to place the length of the contents of the file,
7040  *     or %NULL if the length is not needed
7041  * @etag_out: (out) (allow-none): a location to place the current entity tag for the file,
7042  *     or %NULL if the entity tag is not needed
7043  * @error: a #GError, or %NULL
7044  *
7045  * Finishes an asynchronous load of the @file's contents.
7046  * The contents are placed in @contents, and @length is set to the
7047  * size of the @contents string. The @content should be freed with
7048  * g_free() when no longer needed. If @etag_out is present, it will be
7049  * set to the new entity tag for the @file.
7050  *
7051  * Returns: %TRUE if the load was successful. If %FALSE and @error is
7052  *     present, it will be set appropriately.
7053  */
7054 gboolean
7055 g_file_load_contents_finish (GFile         *file,
7056                              GAsyncResult  *res,
7057                              char         **contents,
7058                              gsize         *length,
7059                              char         **etag_out,
7060                              GError       **error)
7061 {
7062   return g_file_load_partial_contents_finish (file,
7063                                               res,
7064                                               contents,
7065                                               length,
7066                                               etag_out,
7067                                               error);
7068 }
7069
7070 /**
7071  * g_file_replace_contents:
7072  * @file: input #GFile
7073  * @contents: (element-type guint8) (array length=length): a string containing the new contents for @file
7074  * @length: the length of @contents in bytes
7075  * @etag: (allow-none): the old [entity-tag][gfile-etag] for the document,
7076  *     or %NULL
7077  * @make_backup: %TRUE if a backup should be created
7078  * @flags: a set of #GFileCreateFlags
7079  * @new_etag: (allow-none) (out): a location to a new [entity tag][gfile-etag]
7080  *      for the document. This should be freed with g_free() when no longer
7081  *      needed, or %NULL
7082  * @cancellable: optional #GCancellable object, %NULL to ignore
7083  * @error: a #GError, or %NULL
7084  *
7085  * Replaces the contents of @file with @contents of @length bytes.
7086  *
7087  * If @etag is specified (not %NULL), any existing file must have that etag,
7088  * or the error %G_IO_ERROR_WRONG_ETAG will be returned.
7089  *
7090  * If @make_backup is %TRUE, this function will attempt to make a backup
7091  * of @file.
7092  *
7093  * If @cancellable is not %NULL, then the operation can be cancelled by
7094  * triggering the cancellable object from another thread. If the operation
7095  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7096  *
7097  * The returned @new_etag can be used to verify that the file hasn't
7098  * changed the next time it is saved over.
7099  *
7100  * Returns: %TRUE if successful. If an error has occurred, this function
7101  *     will return %FALSE and set @error appropriately if present.
7102  */
7103 gboolean
7104 g_file_replace_contents (GFile             *file,
7105                          const char        *contents,
7106                          gsize              length,
7107                          const char        *etag,
7108                          gboolean           make_backup,
7109                          GFileCreateFlags   flags,
7110                          char             **new_etag,
7111                          GCancellable      *cancellable,
7112                          GError           **error)
7113 {
7114   GFileOutputStream *out;
7115   gsize pos, remainder;
7116   gssize res;
7117   gboolean ret;
7118
7119   g_return_val_if_fail (G_IS_FILE (file), FALSE);
7120   g_return_val_if_fail (contents != NULL, FALSE);
7121
7122   out = g_file_replace (file, etag, make_backup, flags, cancellable, error);
7123   if (out == NULL)
7124     return FALSE;
7125
7126   pos = 0;
7127   remainder = length;
7128   while (remainder > 0 &&
7129          (res = g_output_stream_write (G_OUTPUT_STREAM (out),
7130                                        contents + pos,
7131                                        MIN (remainder, GET_CONTENT_BLOCK_SIZE),
7132                                        cancellable,
7133                                        error)) > 0)
7134     {
7135       pos += res;
7136       remainder -= res;
7137     }
7138
7139   if (remainder > 0 && res < 0)
7140     {
7141       /* Ignore errors on close */
7142       g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, NULL);
7143       g_object_unref (out);
7144
7145       /* error is set already */
7146       return FALSE;
7147     }
7148
7149   ret = g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, error);
7150
7151   if (new_etag)
7152     *new_etag = g_file_output_stream_get_etag (out);
7153
7154   g_object_unref (out);
7155
7156   return ret;
7157 }
7158
7159 typedef struct {
7160   GTask *task;
7161   GBytes *content;
7162   gsize pos;
7163   char *etag;
7164   gboolean failed;
7165 } ReplaceContentsData;
7166
7167 static void
7168 replace_contents_data_free (ReplaceContentsData *data)
7169 {
7170   g_bytes_unref (data->content);
7171   g_free (data->etag);
7172   g_free (data);
7173 }
7174
7175 static void
7176 replace_contents_close_callback (GObject      *obj,
7177                                  GAsyncResult *close_res,
7178                                  gpointer      user_data)
7179 {
7180   GOutputStream *stream = G_OUTPUT_STREAM (obj);
7181   ReplaceContentsData *data = user_data;
7182
7183   /* Ignore errors here, we're only reading anyway */
7184   g_output_stream_close_finish (stream, close_res, NULL);
7185   g_object_unref (stream);
7186
7187   if (!data->failed)
7188     {
7189       data->etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (stream));
7190       g_task_return_boolean (data->task, TRUE);
7191     }
7192   g_object_unref (data->task);
7193 }
7194
7195 static void
7196 replace_contents_write_callback (GObject      *obj,
7197                                  GAsyncResult *read_res,
7198                                  gpointer      user_data)
7199 {
7200   GOutputStream *stream = G_OUTPUT_STREAM (obj);
7201   ReplaceContentsData *data = user_data;
7202   GError *error = NULL;
7203   gssize write_size;
7204
7205   write_size = g_output_stream_write_finish (stream, read_res, &error);
7206
7207   if (write_size <= 0)
7208     {
7209       /* Error or EOF, close the file */
7210       if (write_size < 0)
7211         {
7212           data->failed = TRUE;
7213           g_task_return_error (data->task, error);
7214         }
7215       g_output_stream_close_async (stream, 0,
7216                                    g_task_get_cancellable (data->task),
7217                                    replace_contents_close_callback, data);
7218     }
7219   else if (write_size > 0)
7220     {
7221       const gchar *content;
7222       gsize length;
7223
7224       content = g_bytes_get_data (data->content, &length);
7225       data->pos += write_size;
7226
7227       if (data->pos >= length)
7228         g_output_stream_close_async (stream, 0,
7229                                      g_task_get_cancellable (data->task),
7230                                      replace_contents_close_callback, data);
7231       else
7232         g_output_stream_write_async (stream,
7233                                      content + data->pos,
7234                                      length - data->pos,
7235                                      0,
7236                                      g_task_get_cancellable (data->task),
7237                                      replace_contents_write_callback,
7238                                      data);
7239     }
7240 }
7241
7242 static void
7243 replace_contents_open_callback (GObject      *obj,
7244                                 GAsyncResult *open_res,
7245                                 gpointer      user_data)
7246 {
7247   GFile *file = G_FILE (obj);
7248   GFileOutputStream *stream;
7249   ReplaceContentsData *data = user_data;
7250   GError *error = NULL;
7251
7252   stream = g_file_replace_finish (file, open_res, &error);
7253
7254   if (stream)
7255     {
7256       const gchar *content;
7257       gsize length;
7258
7259       content = g_bytes_get_data (data->content, &length);
7260       g_output_stream_write_async (G_OUTPUT_STREAM (stream),
7261                                    content + data->pos,
7262                                    length - data->pos,
7263                                    0,
7264                                    g_task_get_cancellable (data->task),
7265                                    replace_contents_write_callback,
7266                                    data);
7267     }
7268   else
7269     {
7270       g_task_return_error (data->task, error);
7271       g_object_unref (data->task);
7272     }
7273 }
7274
7275 /**
7276  * g_file_replace_contents_async:
7277  * @file: input #GFile
7278  * @contents: (element-type guint8) (array length=length): string of contents to replace the file with
7279  * @length: the length of @contents in bytes
7280  * @etag: (allow-none): a new [entity tag][gfile-etag] for the @file, or %NULL
7281  * @make_backup: %TRUE if a backup should be created
7282  * @flags: a set of #GFileCreateFlags
7283  * @cancellable: optional #GCancellable object, %NULL to ignore
7284  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
7285  * @user_data: the data to pass to callback function
7286  *
7287  * Starts an asynchronous replacement of @file with the given
7288  * @contents of @length bytes. @etag will replace the document's
7289  * current entity tag.
7290  *
7291  * When this operation has completed, @callback will be called with
7292  * @user_user data, and the operation can be finalized with
7293  * g_file_replace_contents_finish().
7294  *
7295  * If @cancellable is not %NULL, then the operation can be cancelled by
7296  * triggering the cancellable object from another thread. If the operation
7297  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7298  *
7299  * If @make_backup is %TRUE, this function will attempt to
7300  * make a backup of @file.
7301  *
7302  * Note that no copy of @content will be made, so it must stay valid
7303  * until @callback is called. See g_file_replace_contents_bytes_async()
7304  * for a #GBytes version that will automatically hold a reference to the
7305  * contents (without copying) for the duration of the call.
7306  */
7307 void
7308 g_file_replace_contents_async  (GFile               *file,
7309                                 const char          *contents,
7310                                 gsize                length,
7311                                 const char          *etag,
7312                                 gboolean             make_backup,
7313                                 GFileCreateFlags     flags,
7314                                 GCancellable        *cancellable,
7315                                 GAsyncReadyCallback  callback,
7316                                 gpointer             user_data)
7317 {
7318   GBytes *bytes;
7319
7320   bytes = g_bytes_new_static (contents, length);
7321   g_file_replace_contents_bytes_async (file, bytes, etag, make_backup, flags,
7322       cancellable, callback, user_data);
7323   g_bytes_unref (bytes);
7324 }
7325
7326 /**
7327  * g_file_replace_contents_bytes_async:
7328  * @file: input #GFile
7329  * @contents: a #GBytes
7330  * @etag: (allow-none): a new [entity tag][gfile-etag] for the @file, or %NULL
7331  * @make_backup: %TRUE if a backup should be created
7332  * @flags: a set of #GFileCreateFlags
7333  * @cancellable: optional #GCancellable object, %NULL to ignore
7334  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
7335  * @user_data: the data to pass to callback function
7336  *
7337  * Same as g_file_replace_contents_async() but takes a #GBytes input instead.
7338  * This function will keep a ref on @contents until the operation is done.
7339  * Unlike g_file_replace_contents_async() this allows forgetting about the
7340  * content without waiting for the callback.
7341  *
7342  * When this operation has completed, @callback will be called with
7343  * @user_user data, and the operation can be finalized with
7344  * g_file_replace_contents_finish().
7345  *
7346  * Since: 2.40
7347  */
7348 void
7349 g_file_replace_contents_bytes_async  (GFile               *file,
7350                                       GBytes              *contents,
7351                                       const char          *etag,
7352                                       gboolean             make_backup,
7353                                       GFileCreateFlags     flags,
7354                                       GCancellable        *cancellable,
7355                                       GAsyncReadyCallback  callback,
7356                                       gpointer             user_data)
7357 {
7358   ReplaceContentsData *data;
7359
7360   g_return_if_fail (G_IS_FILE (file));
7361   g_return_if_fail (contents != NULL);
7362
7363   data = g_new0 (ReplaceContentsData, 1);
7364
7365   data->content = g_bytes_ref (contents);
7366
7367   data->task = g_task_new (file, cancellable, callback, user_data);
7368   g_task_set_task_data (data->task, data, (GDestroyNotify)replace_contents_data_free);
7369
7370   g_file_replace_async (file,
7371                         etag,
7372                         make_backup,
7373                         flags,
7374                         0,
7375                         g_task_get_cancellable (data->task),
7376                         replace_contents_open_callback,
7377                         data);
7378 }
7379
7380 /**
7381  * g_file_replace_contents_finish:
7382  * @file: input #GFile
7383  * @res: a #GAsyncResult
7384  * @new_etag: (out) (allow-none): a location of a new [entity tag][gfile-etag]
7385  *     for the document. This should be freed with g_free() when it is no
7386  *     longer needed, or %NULL
7387  * @error: a #GError, or %NULL
7388  *
7389  * Finishes an asynchronous replace of the given @file. See
7390  * g_file_replace_contents_async(). Sets @new_etag to the new entity
7391  * tag for the document, if present.
7392  *
7393  * Returns: %TRUE on success, %FALSE on failure.
7394  */
7395 gboolean
7396 g_file_replace_contents_finish (GFile         *file,
7397                                 GAsyncResult  *res,
7398                                 char         **new_etag,
7399                                 GError       **error)
7400 {
7401   GTask *task;
7402   ReplaceContentsData *data;
7403
7404   g_return_val_if_fail (G_IS_FILE (file), FALSE);
7405   g_return_val_if_fail (g_task_is_valid (res, file), FALSE);
7406
7407   task = G_TASK (res);
7408
7409   if (!g_task_propagate_boolean (task, error))
7410     return FALSE;
7411
7412   data = g_task_get_task_data (task);
7413
7414   if (new_etag)
7415     {
7416       *new_etag = data->etag;
7417       data->etag = NULL; /* Take ownership */
7418     }
7419
7420   return TRUE;
7421 }
7422
7423 gboolean
7424 g_file_real_measure_disk_usage (GFile                         *file,
7425                                 GFileMeasureFlags              flags,
7426                                 GCancellable                  *cancellable,
7427                                 GFileMeasureProgressCallback   progress_callback,
7428                                 gpointer                       progress_data,
7429                                 guint64                       *disk_usage,
7430                                 guint64                       *num_dirs,
7431                                 guint64                       *num_files,
7432                                 GError                       **error)
7433 {
7434   g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
7435                        "Operation not supported for the current backend.");
7436   return FALSE;
7437 }
7438
7439 typedef struct
7440 {
7441   GFileMeasureFlags             flags;
7442   GFileMeasureProgressCallback  progress_callback;
7443   gpointer                      progress_data;
7444 } MeasureTaskData;
7445
7446 typedef struct
7447 {
7448   guint64 disk_usage;
7449   guint64 num_dirs;
7450   guint64 num_files;
7451 } MeasureResult;
7452
7453 typedef struct
7454 {
7455   GFileMeasureProgressCallback callback;
7456   gpointer                     user_data;
7457   gboolean                     reporting;
7458   guint64                      current_size;
7459   guint64                      num_dirs;
7460   guint64                      num_files;
7461 } MeasureProgress;
7462
7463 static gboolean
7464 measure_disk_usage_invoke_progress (gpointer user_data)
7465 {
7466   MeasureProgress *progress = user_data;
7467
7468   (* progress->callback) (progress->reporting,
7469                           progress->current_size, progress->num_dirs, progress->num_files,
7470                           progress->user_data);
7471
7472   return FALSE;
7473 }
7474
7475 static void
7476 measure_disk_usage_progress (gboolean reporting,
7477                              guint64  current_size,
7478                              guint64  num_dirs,
7479                              guint64  num_files,
7480                              gpointer user_data)
7481 {
7482   MeasureProgress progress;
7483   GTask *task = user_data;
7484   MeasureTaskData *data;
7485
7486   data = g_task_get_task_data (task);
7487
7488   progress.callback = data->progress_callback;
7489   progress.user_data = data->progress_data;
7490   progress.reporting = reporting;
7491   progress.current_size = current_size;
7492   progress.num_dirs = num_dirs;
7493   progress.num_files = num_files;
7494
7495   g_main_context_invoke_full (g_task_get_context (task),
7496                               g_task_get_priority (task),
7497                               measure_disk_usage_invoke_progress,
7498                               g_memdup (&progress, sizeof progress),
7499                               g_free);
7500 }
7501
7502 static void
7503 measure_disk_usage_thread (GTask        *task,
7504                            gpointer      source_object,
7505                            gpointer      task_data,
7506                            GCancellable *cancellable)
7507 {
7508   MeasureTaskData *data = task_data;
7509   GError *error = NULL;
7510   MeasureResult result;
7511
7512   if (g_file_measure_disk_usage (source_object, data->flags, cancellable,
7513                                  data->progress_callback ? measure_disk_usage_progress : NULL, task,
7514                                  &result.disk_usage, &result.num_dirs, &result.num_files,
7515                                  &error))
7516     g_task_return_pointer (task, g_memdup (&result, sizeof result), g_free);
7517   else
7518     g_task_return_error (task, error);
7519 }
7520
7521 static void
7522 g_file_real_measure_disk_usage_async (GFile                        *file,
7523                                       GFileMeasureFlags             flags,
7524                                       gint                          io_priority,
7525                                       GCancellable                 *cancellable,
7526                                       GFileMeasureProgressCallback  progress_callback,
7527                                       gpointer                      progress_data,
7528                                       GAsyncReadyCallback           callback,
7529                                       gpointer                      user_data)
7530 {
7531   MeasureTaskData data;
7532   GTask *task;
7533
7534   data.flags = flags;
7535   data.progress_callback = progress_callback;
7536   data.progress_data = progress_data;
7537
7538   task = g_task_new (file, cancellable, callback, user_data);
7539   g_task_set_task_data (task, g_memdup (&data, sizeof data), g_free);
7540   g_task_set_priority (task, io_priority);
7541
7542   g_task_run_in_thread (task, measure_disk_usage_thread);
7543   g_object_unref (task);
7544 }
7545
7546 static gboolean
7547 g_file_real_measure_disk_usage_finish (GFile         *file,
7548                                        GAsyncResult  *result,
7549                                        guint64       *disk_usage,
7550                                        guint64       *num_dirs,
7551                                        guint64       *num_files,
7552                                        GError       **error)
7553 {
7554   MeasureResult *measure_result;
7555
7556   g_return_val_if_fail (g_task_is_valid (result, file), FALSE);
7557
7558   measure_result = g_task_propagate_pointer (G_TASK (result), error);
7559
7560   if (measure_result == NULL)
7561     return FALSE;
7562
7563   if (disk_usage)
7564     *disk_usage = measure_result->disk_usage;
7565
7566   if (num_dirs)
7567     *num_dirs = measure_result->num_dirs;
7568
7569   if (num_files)
7570     *num_files = measure_result->num_files;
7571
7572   g_free (measure_result);
7573
7574   return TRUE;
7575 }
7576
7577 /**
7578  * g_file_measure_disk_usage:
7579  * @file: a #GFile
7580  * @flags: #GFileMeasureFlags
7581  * @cancellable: (allow-none): optional #GCancellable
7582  * @progress_callback: (allow-none): a #GFileMeasureProgressCallback
7583  * @progress_data: user_data for @progress_callback
7584  * @disk_usage: (allow-none) (out): the number of bytes of disk space used
7585  * @num_dirs: (allow-none) (out): the number of directories encountered
7586  * @num_files: (allow-none) (out): the number of non-directories encountered
7587  * @error: (allow-none): %NULL, or a pointer to a %NULL #GError pointer
7588  *
7589  * Recursively measures the disk usage of @file.
7590  *
7591  * This is essentially an analog of the 'du' command, but it also
7592  * reports the number of directories and non-directory files encountered
7593  * (including things like symbolic links).
7594  *
7595  * By default, errors are only reported against the toplevel file
7596  * itself.  Errors found while recursing are silently ignored, unless
7597  * %G_FILE_DISK_USAGE_REPORT_ALL_ERRORS is given in @flags.
7598  *
7599  * The returned size, @disk_usage, is in bytes and should be formatted
7600  * with g_format_size() in order to get something reasonable for showing
7601  * in a user interface.
7602  *
7603  * @progress_callback and @progress_data can be given to request
7604  * periodic progress updates while scanning.  See the documentation for
7605  * #GFileMeasureProgressCallback for information about when and how the
7606  * callback will be invoked.
7607  *
7608  * Returns: %TRUE if successful, with the out parameters set.
7609  *          %FALSE otherwise, with @error set.
7610  *
7611  * Since: 2.38
7612  **/
7613 gboolean
7614 g_file_measure_disk_usage (GFile                         *file,
7615                            GFileMeasureFlags              flags,
7616                            GCancellable                  *cancellable,
7617                            GFileMeasureProgressCallback   progress_callback,
7618                            gpointer                       progress_data,
7619                            guint64                       *disk_usage,
7620                            guint64                       *num_dirs,
7621                            guint64                       *num_files,
7622                            GError                       **error)
7623 {
7624   g_return_val_if_fail (G_IS_FILE (file), FALSE);
7625   g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
7626   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
7627
7628   return G_FILE_GET_IFACE (file)->measure_disk_usage (file, flags, cancellable,
7629                                                       progress_callback, progress_data,
7630                                                       disk_usage, num_dirs, num_files,
7631                                                       error);
7632 }
7633
7634 /**
7635  * g_file_measure_disk_usage_async:
7636  * @file: a #GFile
7637  * @flags: #GFileMeasureFlags
7638  * @io_priority: the [I/O priority][io-priority] of the request
7639  * @cancellable: (allow-none): optional #GCancellable
7640  * @progress_callback: (allow-none): a #GFileMeasureProgressCallback
7641  * @progress_data: user_data for @progress_callback
7642  * @callback: (allow-none): a #GAsyncReadyCallback to call when complete
7643  * @user_data: the data to pass to callback function
7644  *
7645  * Recursively measures the disk usage of @file.
7646  *
7647  * This is the asynchronous version of g_file_measure_disk_usage().  See
7648  * there for more information.
7649  *
7650  * Since: 2.38
7651  **/
7652 void
7653 g_file_measure_disk_usage_async (GFile                        *file,
7654                                  GFileMeasureFlags             flags,
7655                                  gint                          io_priority,
7656                                  GCancellable                 *cancellable,
7657                                  GFileMeasureProgressCallback  progress_callback,
7658                                  gpointer                      progress_data,
7659                                  GAsyncReadyCallback           callback,
7660                                  gpointer                      user_data)
7661 {
7662   g_return_if_fail (G_IS_FILE (file));
7663   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
7664
7665   G_FILE_GET_IFACE (file)->measure_disk_usage_async (file, flags, io_priority, cancellable,
7666                                                      progress_callback, progress_data,
7667                                                      callback, user_data);
7668 }
7669
7670 /**
7671  * g_file_measure_disk_usage_finish:
7672  * @file: a #GFile
7673  * @result: the #GAsyncResult passed to your #GAsyncReadyCallback
7674  * @disk_usage: (allow-none) (out): the number of bytes of disk space used
7675  * @num_dirs: (allow-none) (out): the number of directories encountered
7676  * @num_files: (allow-none) (out): the number of non-directories encountered
7677  * @error: (allow-none): %NULL, or a pointer to a %NULL #GError pointer
7678  *
7679  * Collects the results from an earlier call to
7680  * g_file_measure_disk_usage_async().  See g_file_measure_disk_usage() for
7681  * more information.
7682  *
7683  * Returns: %TRUE if successful, with the out parameters set.
7684  *          %FALSE otherwise, with @error set.
7685  *
7686  * Since: 2.38
7687  **/
7688 gboolean
7689 g_file_measure_disk_usage_finish (GFile         *file,
7690                                   GAsyncResult  *result,
7691                                   guint64       *disk_usage,
7692                                   guint64       *num_dirs,
7693                                   guint64       *num_files,
7694                                   GError       **error)
7695 {
7696   g_return_val_if_fail (G_IS_FILE (file), FALSE);
7697   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
7698
7699   return G_FILE_GET_IFACE (file)->measure_disk_usage_finish (file, result, disk_usage, num_dirs, num_files, error);
7700 }
7701
7702 /**
7703  * g_file_start_mountable:
7704  * @file: input #GFile
7705  * @flags: flags affecting the operation
7706  * @start_operation: (allow-none): a #GMountOperation, or %NULL to avoid user interaction
7707  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
7708  * @callback: (allow-none): a #GAsyncReadyCallback to call when the request is satisfied, or %NULL
7709  * @user_data: the data to pass to callback function
7710  *
7711  * Starts a file of type #G_FILE_TYPE_MOUNTABLE.
7712  * Using @start_operation, you can request callbacks when, for instance,
7713  * passwords are needed during authentication.
7714  *
7715  * If @cancellable is not %NULL, then the operation can be cancelled by
7716  * triggering the cancellable object from another thread. If the operation
7717  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7718  *
7719  * When the operation is finished, @callback will be called.
7720  * You can then call g_file_mount_mountable_finish() to get
7721  * the result of the operation.
7722  *
7723  * Since: 2.22
7724  */
7725 void
7726 g_file_start_mountable (GFile               *file,
7727                         GDriveStartFlags     flags,
7728                         GMountOperation     *start_operation,
7729                         GCancellable        *cancellable,
7730                         GAsyncReadyCallback  callback,
7731                         gpointer             user_data)
7732 {
7733   GFileIface *iface;
7734
7735   g_return_if_fail (G_IS_FILE (file));
7736
7737   iface = G_FILE_GET_IFACE (file);
7738
7739   if (iface->start_mountable == NULL)
7740     {
7741       g_task_report_new_error (file, callback, user_data,
7742                                g_file_start_mountable,
7743                                G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
7744                                _("Operation not supported"));
7745       return;
7746     }
7747
7748   (* iface->start_mountable) (file,
7749                               flags,
7750                               start_operation,
7751                               cancellable,
7752                               callback,
7753                               user_data);
7754 }
7755
7756 /**
7757  * g_file_start_mountable_finish:
7758  * @file: input #GFile
7759  * @result: a #GAsyncResult
7760  * @error: a #GError, or %NULL
7761  *
7762  * Finishes a start operation. See g_file_start_mountable() for details.
7763  *
7764  * Finish an asynchronous start operation that was started
7765  * with g_file_start_mountable().
7766  *
7767  * Returns: %TRUE if the operation finished successfully. %FALSE
7768  * otherwise.
7769  *
7770  * Since: 2.22
7771  */
7772 gboolean
7773 g_file_start_mountable_finish (GFile         *file,
7774                                GAsyncResult  *result,
7775                                GError       **error)
7776 {
7777   GFileIface *iface;
7778
7779   g_return_val_if_fail (G_IS_FILE (file), FALSE);
7780   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
7781
7782   if (g_async_result_legacy_propagate_error (result, error))
7783     return FALSE;
7784   else if (g_async_result_is_tagged (result, g_file_start_mountable))
7785     return g_task_propagate_boolean (G_TASK (result), error);
7786
7787   iface = G_FILE_GET_IFACE (file);
7788   return (* iface->start_mountable_finish) (file, result, error);
7789 }
7790
7791 /**
7792  * g_file_stop_mountable:
7793  * @file: input #GFile
7794  * @flags: flags affecting the operation
7795  * @mount_operation: (allow-none): a #GMountOperation,
7796  *     or %NULL to avoid user interaction.
7797  * @cancellable: (allow-none): optional #GCancellable object,
7798  *     %NULL to ignore
7799  * @callback: (allow-none): a #GAsyncReadyCallback to call
7800  *     when the request is satisfied, or %NULL
7801  * @user_data: the data to pass to callback function
7802  *
7803  * Stops a file of type #G_FILE_TYPE_MOUNTABLE.
7804  *
7805  * If @cancellable is not %NULL, then the operation can be cancelled by
7806  * triggering the cancellable object from another thread. If the operation
7807  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7808  *
7809  * When the operation is finished, @callback will be called.
7810  * You can then call g_file_stop_mountable_finish() to get
7811  * the result of the operation.
7812  *
7813  * Since: 2.22
7814  */
7815 void
7816 g_file_stop_mountable (GFile               *file,
7817                        GMountUnmountFlags   flags,
7818                        GMountOperation     *mount_operation,
7819                        GCancellable        *cancellable,
7820                        GAsyncReadyCallback  callback,
7821                        gpointer             user_data)
7822 {
7823   GFileIface *iface;
7824
7825   g_return_if_fail (G_IS_FILE (file));
7826
7827   iface = G_FILE_GET_IFACE (file);
7828
7829   if (iface->stop_mountable == NULL)
7830     {
7831       g_task_report_new_error (file, callback, user_data,
7832                                g_file_stop_mountable,
7833                                G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
7834                                _("Operation not supported"));
7835       return;
7836     }
7837
7838   (* iface->stop_mountable) (file,
7839                              flags,
7840                              mount_operation,
7841                              cancellable,
7842                              callback,
7843                              user_data);
7844 }
7845
7846 /**
7847  * g_file_stop_mountable_finish:
7848  * @file: input #GFile
7849  * @result: a #GAsyncResult
7850  * @error: a #GError, or %NULL
7851  *
7852  * Finishes an stop operation, see g_file_stop_mountable() for details.
7853  *
7854  * Finish an asynchronous stop operation that was started
7855  * with g_file_stop_mountable().
7856  *
7857  * Returns: %TRUE if the operation finished successfully.
7858  *     %FALSE otherwise.
7859  *
7860  * Since: 2.22
7861  */
7862 gboolean
7863 g_file_stop_mountable_finish (GFile         *file,
7864                               GAsyncResult  *result,
7865                               GError       **error)
7866 {
7867   GFileIface *iface;
7868
7869   g_return_val_if_fail (G_IS_FILE (file), FALSE);
7870   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
7871
7872   if (g_async_result_legacy_propagate_error (result, error))
7873     return FALSE;
7874   else if (g_async_result_is_tagged (result, g_file_stop_mountable))
7875     return g_task_propagate_boolean (G_TASK (result), error);
7876
7877   iface = G_FILE_GET_IFACE (file);
7878   return (* iface->stop_mountable_finish) (file, result, error);
7879 }
7880
7881 /**
7882  * g_file_poll_mountable:
7883  * @file: input #GFile
7884  * @cancellable: optional #GCancellable object, %NULL to ignore
7885  * @callback: (allow-none): a #GAsyncReadyCallback to call
7886  *     when the request is satisfied, or %NULL
7887  * @user_data: the data to pass to callback function
7888  *
7889  * Polls a file of type #G_FILE_TYPE_MOUNTABLE.
7890  *
7891  * If @cancellable is not %NULL, then the operation can be cancelled by
7892  * triggering the cancellable object from another thread. If the operation
7893  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7894  *
7895  * When the operation is finished, @callback will be called.
7896  * You can then call g_file_mount_mountable_finish() to get
7897  * the result of the operation.
7898  *
7899  * Since: 2.22
7900  */
7901 void
7902 g_file_poll_mountable (GFile               *file,
7903                        GCancellable        *cancellable,
7904                        GAsyncReadyCallback  callback,
7905                        gpointer             user_data)
7906 {
7907   GFileIface *iface;
7908
7909   g_return_if_fail (G_IS_FILE (file));
7910
7911   iface = G_FILE_GET_IFACE (file);
7912
7913   if (iface->poll_mountable == NULL)
7914     {
7915       g_task_report_new_error (file, callback, user_data,
7916                                g_file_poll_mountable,
7917                                G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
7918                                _("Operation not supported"));
7919       return;
7920     }
7921
7922   (* iface->poll_mountable) (file,
7923                              cancellable,
7924                              callback,
7925                              user_data);
7926 }
7927
7928 /**
7929  * g_file_poll_mountable_finish:
7930  * @file: input #GFile
7931  * @result: a #GAsyncResult
7932  * @error: a #GError, or %NULL
7933  *
7934  * Finishes a poll operation. See g_file_poll_mountable() for details.
7935  *
7936  * Finish an asynchronous poll operation that was polled
7937  * with g_file_poll_mountable().
7938  *
7939  * Returns: %TRUE if the operation finished successfully. %FALSE
7940  * otherwise.
7941  *
7942  * Since: 2.22
7943  */
7944 gboolean
7945 g_file_poll_mountable_finish (GFile         *file,
7946                               GAsyncResult  *result,
7947                               GError       **error)
7948 {
7949   GFileIface *iface;
7950
7951   g_return_val_if_fail (G_IS_FILE (file), FALSE);
7952   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
7953
7954   if (g_async_result_legacy_propagate_error (result, error))
7955     return FALSE;
7956   else if (g_async_result_is_tagged (result, g_file_poll_mountable))
7957     return g_task_propagate_boolean (G_TASK (result), error);
7958
7959   iface = G_FILE_GET_IFACE (file);
7960   return (* iface->poll_mountable_finish) (file, result, error);
7961 }
7962
7963 /**
7964  * g_file_supports_thread_contexts:
7965  * @file: a #GFile
7966  *
7967  * Checks if @file supports
7968  * [thread-default contexts][g-main-context-push-thread-default-context].
7969  * If this returns %FALSE, you cannot perform asynchronous operations on
7970  * @file in a thread that has a thread-default context.
7971  *
7972  * Returns: Whether or not @file supports thread-default contexts.
7973  *
7974  * Since: 2.22
7975  */
7976 gboolean
7977 g_file_supports_thread_contexts (GFile *file)
7978 {
7979  GFileIface *iface;
7980
7981  g_return_val_if_fail (G_IS_FILE (file), FALSE);
7982
7983  iface = G_FILE_GET_IFACE (file);
7984  return iface->supports_thread_contexts;
7985 }