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