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