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