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