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