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