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