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