Reintroduce g_file_contains_file, keep around for one unstable release
[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 #include <string.h>
27 #include <sys/types.h>
28 #ifdef HAVE_PWD_H
29 #include <pwd.h>
30 #endif
31 #include "gfile.h"
32 #include "gvfs.h"
33 #include "gioscheduler.h"
34 #include <glocalfile.h>
35 #include "gsimpleasyncresult.h"
36 #include "gfileattribute-priv.h"
37 #include "gpollfilemonitor.h"
38 #include "glibintl.h"
39
40 #include "gioalias.h"
41
42 /**
43  * SECTION:gfile
44  * @short_description: File and Directory Handling
45  * @include: gio/gio.h
46  * @see_also: #GFileInfo, #GFileEnumerator
47  * 
48  * #GFile is a high level abstraction for manipulating files on a 
49  * virtual file system. #GFile<!-- -->s are lightweight, immutable 
50  * objects that do no I/O upon creation. It is necessary to understand that
51  * #GFile objects do not represent files, merely an identifier for a file. All
52  * file content I/O is implemented as streaming operations (see #GInputStream and 
53  * #GOutputStream).
54  *
55  * To construct a #GFile, you can use: 
56  * g_file_new_for_path() if you have a path.
57  * g_file_new_for_uri() if you have a URI.
58  * g_file_new_for_commandline_arg() for a command line argument.
59  * g_file_parse_name() from a utf8 string gotten from g_file_get_parse_name().
60  * 
61  * One way to think of a #GFile is as an abstraction of a pathname. For normal
62  * files the system pathname is what is stored internally, but as #GFile<!-- -->s
63  * are extensible it could also be something else that corresponds to a pathname
64  * in a userspace implementation of a filesystem.
65  *
66  * #GFile<!-- -->s make up hierarchies of directories and files that correspond to the
67  * files on a filesystem. You can move through the file system with #GFile using
68  * g_file_get_parent() to get an identifier for the parent directory, g_file_get_child()
69  * to get a child within a directory, g_file_resolve_relative_path() to resolve a relative
70  * path between two #GFile<!-- -->s. There can be multiple hierarchies, so you may not
71  * end up at the same root if you repeatedly call g_file_get_parent() on two different
72  * files.
73  *
74  * All #GFile<!-- -->s have a basename (get with g_file_get_basename()). These names
75  * are byte strings that are used to identify the file on the filesystem (relative to
76  * its parent directory) and there is no guarantees that they have any particular charset
77  * encoding or even make any sense at all. If you want to use filenames in a user
78  * interface you should use the display name that you can get by requesting the
79  * %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME attribute with g_file_query_info().
80  * This is guaranteed to be in utf8 and can be used in a user interface. But always
81  * store the real basename or the #GFile to use to actually access the file, because
82  * there is no way to go from a display name to the actual name.
83  *
84  * Using #GFile as an identifier has the same weaknesses as using a path in that
85  * there may be multiple aliases for the same file. For instance, hard or
86  * soft links may cause two different #GFile<!-- -->s to refer to the same file.
87  * Other possible causes for aliases are: case insensitive filesystems, short
88  * and long names on Fat/NTFS, or bind mounts in linux. If you want to check if
89  * two #GFile<!-- -->s point to the same file you can query for the
90  * %G_FILE_ATTRIBUTE_ID_FILE attribute. Note that #GFile does some trivial
91  * canonicalization of pathnames passed in, so that trivial differences in the
92  * path string used at creation (dupplicated slashes, slash at end of path, "."
93  * or ".." path segments, etc) does not create different #GFile<!-- -->s.
94  * 
95  * Many #GFile operations have both synchronous and asynchronous versions 
96  * to suit your application. Asynchronous versions of synchronous functions 
97  * simply have _async() appended to their function names. The asynchronous 
98  * I/O functions call a #GAsyncReadyCallback which is then used to finalize 
99  * the operation, producing a GAsyncResult which is then passed to the 
100  * function's matching _finish() 
101  * operation. 
102  *
103  * Some #GFile operations do not have synchronous analogs, as they may
104  * take a very long time to finish, and blocking may leave an application
105  * unusable. Notable cases include:
106  * g_file_mount_mountable() to mount a mountable file.
107  * g_file_unmount_mountable() to unmount a mountable file.
108  * g_file_eject_mountable() to eject a mountable file.
109  * 
110  * <para id="gfile-etag"><indexterm><primary>entity tag</primary></indexterm>
111  * One notable feature of #GFile<!-- -->s are entity tags, or "etags" for 
112  * short. Entity tags are somewhat like a more abstract version of the 
113  * traditional mtime, and can be used to quickly determine if the file has
114  * been modified from the version on the file system. See the HTTP 1.1 
115  * <ulink url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">specification</ulink>
116  * for HTTP Etag headers, which are a very similar concept.
117  * </para>
118  **/
119
120 static void g_file_base_init (gpointer g_class);
121 static void g_file_class_init (gpointer g_class,
122                                gpointer class_data);
123
124 static void               g_file_real_query_info_async            (GFile                  *file,
125                                                                    const char             *attributes,
126                                                                    GFileQueryInfoFlags     flags,
127                                                                    int                     io_priority,
128                                                                    GCancellable           *cancellable,
129                                                                    GAsyncReadyCallback     callback,
130                                                                    gpointer                user_data);
131 static GFileInfo *        g_file_real_query_info_finish           (GFile                  *file,
132                                                                    GAsyncResult           *res,
133                                                                    GError                **error);
134 static void               g_file_real_query_filesystem_info_async (GFile                  *file,
135                                                                    const char             *attributes,
136                                                                    int                     io_priority,
137                                                                    GCancellable           *cancellable,
138                                                                    GAsyncReadyCallback     callback,
139                                                                    gpointer                user_data);
140 static GFileInfo *        g_file_real_query_filesystem_info_finish (GFile                  *file,
141                                                                    GAsyncResult           *res,
142                                                                    GError                **error);
143 static void               g_file_real_enumerate_children_async    (GFile                  *file,
144                                                                    const char             *attributes,
145                                                                    GFileQueryInfoFlags     flags,
146                                                                    int                     io_priority,
147                                                                    GCancellable           *cancellable,
148                                                                    GAsyncReadyCallback     callback,
149                                                                    gpointer                user_data);
150 static GFileEnumerator *  g_file_real_enumerate_children_finish   (GFile                  *file,
151                                                                    GAsyncResult           *res,
152                                                                    GError                **error);
153 static void               g_file_real_read_async                  (GFile                  *file,
154                                                                    int                     io_priority,
155                                                                    GCancellable           *cancellable,
156                                                                    GAsyncReadyCallback     callback,
157                                                                    gpointer                user_data);
158 static GFileInputStream * g_file_real_read_finish                 (GFile                  *file,
159                                                                    GAsyncResult           *res,
160                                                                    GError                **error);
161 static void               g_file_real_append_to_async             (GFile                  *file,
162                                                                    GFileCreateFlags        flags,
163                                                                    int                     io_priority,
164                                                                    GCancellable           *cancellable,
165                                                                    GAsyncReadyCallback     callback,
166                                                                    gpointer                user_data);
167 static GFileOutputStream *g_file_real_append_to_finish            (GFile                  *file,
168                                                                    GAsyncResult           *res,
169                                                                    GError                **error);
170 static void               g_file_real_create_async                (GFile                  *file,
171                                                                    GFileCreateFlags        flags,
172                                                                    int                     io_priority,
173                                                                    GCancellable           *cancellable,
174                                                                    GAsyncReadyCallback     callback,
175                                                                    gpointer                user_data);
176 static GFileOutputStream *g_file_real_create_finish               (GFile                  *file,
177                                                                    GAsyncResult           *res,
178                                                                    GError                **error);
179 static void               g_file_real_replace_async               (GFile                  *file,
180                                                                    const char             *etag,
181                                                                    gboolean                make_backup,
182                                                                    GFileCreateFlags        flags,
183                                                                    int                     io_priority,
184                                                                    GCancellable           *cancellable,
185                                                                    GAsyncReadyCallback     callback,
186                                                                    gpointer                user_data);
187 static GFileOutputStream *g_file_real_replace_finish              (GFile                  *file,
188                                                                    GAsyncResult           *res,
189                                                                    GError                **error);
190 static gboolean           g_file_real_set_attributes_from_info    (GFile                  *file,
191                                                                    GFileInfo              *info,
192                                                                    GFileQueryInfoFlags     flags,
193                                                                    GCancellable           *cancellable,
194                                                                    GError                **error);
195 static void               g_file_real_set_display_name_async      (GFile                  *file,
196                                                                    const char             *display_name,
197                                                                    int                     io_priority,
198                                                                    GCancellable           *cancellable,
199                                                                    GAsyncReadyCallback     callback,
200                                                                    gpointer                user_data);
201 static GFile *            g_file_real_set_display_name_finish     (GFile                  *file,
202                                                                    GAsyncResult           *res,
203                                                                    GError                **error);
204 static void               g_file_real_set_attributes_async        (GFile                  *file,
205                                                                    GFileInfo              *info,
206                                                                    GFileQueryInfoFlags     flags,
207                                                                    int                     io_priority,
208                                                                    GCancellable           *cancellable,
209                                                                    GAsyncReadyCallback     callback,
210                                                                    gpointer                user_data);
211 static gboolean           g_file_real_set_attributes_finish       (GFile                  *file,
212                                                                    GAsyncResult           *res,
213                                                                    GFileInfo             **info,
214                                                                    GError                **error);
215 static void               g_file_real_find_enclosing_mount_async  (GFile                  *file,
216                                                                    int                     io_priority,
217                                                                    GCancellable           *cancellable,
218                                                                    GAsyncReadyCallback     callback,
219                                                                    gpointer                user_data);
220 static GMount *           g_file_real_find_enclosing_mount_finish (GFile                  *file,
221                                                                    GAsyncResult           *res,
222                                                                    GError                **error);
223 static void               g_file_real_copy_async                  (GFile                  *source,
224                                                                    GFile                  *destination,
225                                                                    GFileCopyFlags          flags,
226                                                                    int                     io_priority,
227                                                                    GCancellable           *cancellable,
228                                                                    GFileProgressCallback   progress_callback,
229                                                                    gpointer                progress_callback_data,
230                                                                    GAsyncReadyCallback     callback,
231                                                                    gpointer                user_data);
232 static gboolean           g_file_real_copy_finish                 (GFile                  *file,
233                                                                    GAsyncResult           *res,
234                                                                    GError                **error);
235
236 GType
237 g_file_get_type (void)
238 {
239   static GType file_type = 0;
240
241   if (! file_type)
242     {
243       static const GTypeInfo file_info =
244       {
245         sizeof (GFileIface), /* class_size */
246         g_file_base_init,   /* base_init */
247         NULL,           /* base_finalize */
248         g_file_class_init,
249         NULL,           /* class_finalize */
250         NULL,           /* class_data */
251         0,
252         0,              /* n_preallocs */
253         NULL
254       };
255
256       file_type =
257         g_type_register_static (G_TYPE_INTERFACE, I_("GFile"),
258                                 &file_info, 0);
259
260       g_type_interface_add_prerequisite (file_type, G_TYPE_OBJECT);
261     }
262
263   return file_type;
264 }
265
266 static void
267 g_file_class_init (gpointer g_class,
268                    gpointer class_data)
269 {
270   GFileIface *iface = g_class;
271
272   iface->enumerate_children_async = g_file_real_enumerate_children_async;
273   iface->enumerate_children_finish = g_file_real_enumerate_children_finish;
274   iface->set_display_name_async = g_file_real_set_display_name_async;
275   iface->set_display_name_finish = g_file_real_set_display_name_finish;
276   iface->query_info_async = g_file_real_query_info_async;
277   iface->query_info_finish = g_file_real_query_info_finish;
278   iface->query_filesystem_info_async = g_file_real_query_filesystem_info_async;
279   iface->query_filesystem_info_finish = g_file_real_query_filesystem_info_finish;
280   iface->set_attributes_async = g_file_real_set_attributes_async;
281   iface->set_attributes_finish = g_file_real_set_attributes_finish;
282   iface->read_async = g_file_real_read_async;
283   iface->read_finish = g_file_real_read_finish;
284   iface->append_to_async = g_file_real_append_to_async;
285   iface->append_to_finish = g_file_real_append_to_finish;
286   iface->create_async = g_file_real_create_async;
287   iface->create_finish = g_file_real_create_finish;
288   iface->replace_async = g_file_real_replace_async;
289   iface->replace_finish = g_file_real_replace_finish;
290   iface->find_enclosing_mount_async = g_file_real_find_enclosing_mount_async;
291   iface->find_enclosing_mount_finish = g_file_real_find_enclosing_mount_finish;
292   iface->set_attributes_from_info = g_file_real_set_attributes_from_info;
293   iface->copy_async = g_file_real_copy_async;
294   iface->copy_finish = g_file_real_copy_finish;
295 }
296
297 static void
298 g_file_base_init (gpointer g_class)
299 {
300 }
301
302
303 /**
304  * g_file_is_native:
305  * @file: input #GFile.
306  *
307  * Checks to see if a file is native to the platform.
308  *
309  * A native file s one expressed in the platform-native filename format,
310  * e.g. "C:\Windows" or "/usr/bin/". This does not mean the file is local,
311  * as it might be on a locally mounted remote filesystem.
312  *
313  * On some systems non-native files may be available using
314  * the native filesystem via a userspace filesystem (FUSE), in
315  * these cases this call will return %FALSE, but g_file_get_path()
316  * will still return a native path.
317  *
318  * This call does no blocking i/o.
319  * 
320  * Returns: %TRUE if file is native. 
321  **/
322 gboolean
323 g_file_is_native (GFile *file)
324 {
325   GFileIface *iface;
326
327   g_return_val_if_fail (G_IS_FILE (file), FALSE);
328
329   iface = G_FILE_GET_IFACE (file);
330
331   return (* iface->is_native) (file);
332 }
333
334
335 /**
336  * g_file_has_uri_scheme: 
337  * @file: input #GFile.
338  * @uri_scheme: a string containing a URI scheme.
339  *
340  * Checks to see if a #GFile has a given URI scheme.
341  *
342  * This call does no blocking i/o.
343  * 
344  * Returns: %TRUE if #GFile's backend supports the
345  *     given URI scheme, %FALSE if URI scheme is %NULL,
346  *     not supported, or #GFile is invalid.
347  **/
348 gboolean
349 g_file_has_uri_scheme (GFile      *file,
350                        const char *uri_scheme)
351 {
352   GFileIface *iface;
353   
354   g_return_val_if_fail (G_IS_FILE (file), FALSE);
355   g_return_val_if_fail (uri_scheme != NULL, FALSE);
356
357   iface = G_FILE_GET_IFACE (file);
358
359   return (* iface->has_uri_scheme) (file, uri_scheme);
360 }
361
362
363 /**
364  * g_file_get_uri_scheme:
365  * @file: input #GFile.
366  *
367  * Gets the URI scheme for a #GFile.
368  * RFC 3986 decodes the scheme as:
369  * <programlisting>
370  * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 
371  * </programlisting>
372  * Common schemes include "file", "http", "ftp", etc. 
373  *
374  * This call does no blocking i/o.
375  * 
376  * Returns: a string containing the URI scheme for the given 
377  *     #GFile. The returned string should be freed with g_free() 
378  *     when no longer needed.
379  **/
380 char *
381 g_file_get_uri_scheme (GFile *file)
382 {
383   GFileIface *iface;
384
385   g_return_val_if_fail (G_IS_FILE (file), NULL);
386
387   iface = G_FILE_GET_IFACE (file);
388
389   return (* iface->get_uri_scheme) (file);
390 }
391
392
393 /**
394  * g_file_get_basename:
395  * @file: input #GFile.
396  *
397  * Gets the base name (the last component of the path) for a given #GFile.
398  *
399  * If called for the top level of a system (such as the filesystem root
400  * or a uri like sftp://host/) it will return a single directory separator
401  * (and on Windows, possibly a drive letter).
402  *
403  * The base name is a byte string (*not* UTF-8). It has no defined encoding
404  * or rules other than it may not contain zero bytes.  If you want to use
405  * filenames in a user interface you should use the display name that you
406  * can get by requesting the %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME
407  * attribute with g_file_query_info().
408  * 
409  * This call does no blocking i/o.
410  * 
411  * Returns: string containing the #GFile's base name, or %NULL 
412  *     if given #GFile is invalid. The returned string should be 
413  *     freed with g_free() when no longer needed.
414  **/
415 char *
416 g_file_get_basename (GFile *file)
417 {
418   GFileIface *iface;
419   
420   g_return_val_if_fail (G_IS_FILE (file), NULL);
421
422   iface = G_FILE_GET_IFACE (file);
423
424   return (* iface->get_basename) (file);
425 }
426
427 /**
428  * g_file_get_path:
429  * @file: input #GFile.
430  *
431  * Gets the local pathname for #GFile, if one exists. 
432  *
433  * This call does no blocking i/o.
434  * 
435  * Returns: string containing the #GFile's path, or %NULL if 
436  *     no such path exists. The returned string should be 
437  *     freed with g_free() when no longer needed.
438  **/
439 char *
440 g_file_get_path (GFile *file)
441 {
442   GFileIface *iface;
443
444   g_return_val_if_fail (G_IS_FILE (file), NULL);
445
446   iface = G_FILE_GET_IFACE (file);
447
448   return (* iface->get_path) (file);
449 }
450
451 /**
452  * g_file_get_uri:
453  * @file: input #GFile.
454  *
455  * Gets the URI for the @file.
456  *
457  * This call does no blocking i/o.
458  * 
459  * Returns: a string containing the #GFile's URI.
460  *     The returned string should be freed with g_free() when no longer needed.
461  **/
462 char *
463 g_file_get_uri (GFile *file)
464 {
465   GFileIface *iface;
466   
467   g_return_val_if_fail (G_IS_FILE (file), NULL);
468
469   iface = G_FILE_GET_IFACE (file);
470
471   return (* iface->get_uri) (file);
472 }
473
474 /**
475  * g_file_get_parse_name:
476  * @file: input #GFile.
477  *
478  * Gets the parse name of the @file.
479  * A parse name is a UTF-8 string that describes the
480  * file such that one can get the #GFile back using
481  * g_file_parse_name().
482  *
483  * This is generally used to show the #GFile as a nice
484  * full-pathname kind of string in a user interface,
485  * like in a location entry.
486  *
487  * For local files with names that can safely be converted
488  * to UTF8 the pathname is used, otherwise the IRI is used
489  * (a form of URI that allows UTF8 characters unescaped).
490  *
491  * This call does no blocking i/o.
492  * 
493  * Returns: a string containing the #GFile's parse name. The returned 
494  *     string should be freed with g_free() when no longer needed.
495  **/
496 char *
497 g_file_get_parse_name (GFile *file)
498 {
499   GFileIface *iface;
500   
501   g_return_val_if_fail (G_IS_FILE (file), NULL);
502
503   iface = G_FILE_GET_IFACE (file);
504
505   return (* iface->get_parse_name) (file);
506 }
507
508 /**
509  * g_file_dup:
510  * @file: input #GFile.
511  *
512  * Duplicates a #GFile handle. This operation does not duplicate 
513  * the actual file or directory represented by the #GFile; see 
514  * g_file_copy() if attempting to copy a file. 
515  *
516  * This call does no blocking i/o.
517  * 
518  * Returns: #GFile that is a duplicate of the given #GFile. 
519  **/
520 GFile *
521 g_file_dup (GFile *file)
522 {
523   GFileIface *iface;
524   
525   g_return_val_if_fail (G_IS_FILE (file), NULL);
526
527   iface = G_FILE_GET_IFACE (file);
528
529   return (* iface->dup) (file);
530 }
531
532 /**
533  * g_file_hash:
534  * @file: #gconstpointer to a #GFile.
535  *
536  * Creates a hash value for a #GFile.
537  *
538  * This call does no blocking i/o.
539  * 
540  * Returns: 0 if @file is not a valid #GFile, otherwise an 
541  *     integer that can be used as hash value for the #GFile. 
542  *     This function is intended for easily hashing a #GFile to 
543  *     add to a #GHashTable or similar data structure.
544  **/
545 guint
546 g_file_hash (gconstpointer file)
547 {
548   GFileIface *iface;
549   
550   g_return_val_if_fail (G_IS_FILE (file), 0);
551
552   iface = G_FILE_GET_IFACE (file);
553
554   return (* iface->hash) ((GFile *)file);
555 }
556
557 /**
558  * g_file_equal:
559  * @file1: the first #GFile.
560  * @file2: the second #GFile.
561  *
562  * Checks equality of two given #GFile<!-- -->s. Note that two
563  * #GFile<!-- -->s that differ can still refer to the same
564  * file on the filesystem due to various forms of filename
565  * aliasing.
566  *
567  * This call does no blocking i/o.
568  * 
569  * Returns: %TRUE if @file1 and @file2 are equal.
570  *     %FALSE if either is not a #GFile.
571  **/
572 gboolean
573 g_file_equal (GFile *file1,
574               GFile *file2)
575 {
576   GFileIface *iface;
577   
578   g_return_val_if_fail (G_IS_FILE (file1), FALSE);
579   g_return_val_if_fail (G_IS_FILE (file2), FALSE);
580   
581   if (G_TYPE_FROM_INSTANCE (file1) != G_TYPE_FROM_INSTANCE (file2))
582     return FALSE;
583
584   iface = G_FILE_GET_IFACE (file1);
585   
586   return (* iface->equal) (file1, file2);
587 }
588
589
590 /**
591  * g_file_get_parent:
592  * @file: input #GFile.
593  *
594  * Gets the parent directory for the @file. 
595  * If the @file represents the root directory of the 
596  * file system, then %NULL will be returned.
597  *
598  * This call does no blocking i/o.
599  * 
600  * Returns: a #GFile structure to the parent of the given
601  *     #GFile or %NULL if there is no parent. 
602  **/
603 GFile *
604 g_file_get_parent (GFile *file)
605 {
606   GFileIface *iface;
607   
608   g_return_val_if_fail (G_IS_FILE (file), NULL);
609
610   iface = G_FILE_GET_IFACE (file);
611
612   return (* iface->get_parent) (file);
613 }
614
615 /**
616  * g_file_get_child:
617  * @file: input #GFile.
618  * @name: string containing the child's basename.
619  *
620  * Gets a child of @file with basename equal to @name.
621  *
622  * Note that the file with that specific name might not exist, but
623  * you can still have a #GFile that points to it. You can use this
624  * for instance to create that file.
625  *
626  * This call does no blocking i/o.
627  * 
628  * Returns: a #GFile to a child specified by @name.
629  **/
630 GFile *
631 g_file_get_child (GFile      *file,
632                   const char *name)
633 {
634   g_return_val_if_fail (G_IS_FILE (file), NULL);
635   g_return_val_if_fail (name != NULL, NULL);
636
637   return g_file_resolve_relative_path (file, name);
638 }
639
640 /**
641  * g_file_get_child_for_display_name:
642  * @file: input #GFile.
643  * @display_name: string to a possible child.
644  * @error: #GError.
645  *
646  * Gets the child of @file for a given @display_name (i.e. a UTF8
647  * version of the name). If this function fails, it returns %NULL and @error will be 
648  * set. This is very useful when constructing a GFile for a new file
649  * and the user entered the filename in the user interface, for instance
650  * when you select a directory and type a filename in the file selector.
651  * 
652  * This call does no blocking i/o.
653  * 
654  * Returns: a #GFile to the specified child, or 
655  *     %NULL if the display name couldn't be converted.  
656  **/
657 GFile *
658 g_file_get_child_for_display_name (GFile      *file,
659                                    const char *display_name,
660                                    GError **error)
661 {
662   GFileIface *iface;
663   
664   g_return_val_if_fail (G_IS_FILE (file), NULL);
665   g_return_val_if_fail (display_name != NULL, NULL);
666
667   iface = G_FILE_GET_IFACE (file);
668
669   return (* iface->get_child_for_display_name) (file, display_name, error);
670 }
671
672 /* Temporary keep this symbol for one release */
673 gboolean g_file_contains_file (GFile *parent, GFile *descendant);
674 gboolean
675 g_file_contains_file (GFile *parent,
676                       GFile *descendant)
677 {
678   /* This function is not in the header and will not be referenced by newly built code */
679   return g_file_has_prefix (descendant, parent);
680 }
681
682 /**
683  * g_file_has_prefix:
684  * @file: input #GFile.
685  * @prefix: input #GFile.
686  * 
687  * Checks whether @file has the prefix specified by @prefix. In other word, if the
688  * names of inital elements of @file<!-- -->s pathname match @prefix.
689  * 
690  * This call does no i/o, as it works purely on names. As such it can sometimes
691  * return %FALSE even if @file is inside a @prefix (from a filesystem point of view),
692  * because the prefix of @file is an alias of @prefix.
693  *
694  * Returns:  %TRUE if the @files's parent, grandparent, etc is @prefix. %FALSE otherwise.
695  **/
696 gboolean
697 g_file_has_prefix (GFile *file,
698                    GFile *prefix)
699 {
700   GFileIface *iface;
701   
702   g_return_val_if_fail (G_IS_FILE (file), FALSE);
703   g_return_val_if_fail (G_IS_FILE (prefix), FALSE);
704
705   if (G_TYPE_FROM_INSTANCE (file) != G_TYPE_FROM_INSTANCE (prefix))
706     return FALSE;
707   
708   iface = G_FILE_GET_IFACE (file);
709
710   /* The vtable function differs in arg order since we're
711      using the old contains_file call */
712   return (* iface->prefix_matches) (prefix, file);
713 }
714
715 /**
716  * g_file_get_relative_path:
717  * @parent: input #GFile.
718  * @descendant: input #GFile.
719  *
720  * Gets the path for @descendant relative to @parent. 
721  *
722  * This call does no blocking i/o.
723  * 
724  * Returns: string with the relative path from @descendant 
725  *     to @parent, or %NULL if @descendant doesn't have @parent as prefix. The returned string should be freed with 
726  *     g_free() when no longer needed.
727  **/
728 char *
729 g_file_get_relative_path (GFile *parent,
730                           GFile *descendant)
731 {
732   GFileIface *iface;
733   
734   g_return_val_if_fail (G_IS_FILE (parent), NULL);
735   g_return_val_if_fail (G_IS_FILE (descendant), NULL);
736
737   if (G_TYPE_FROM_INSTANCE (parent) != G_TYPE_FROM_INSTANCE (descendant))
738     return NULL;
739   
740   iface = G_FILE_GET_IFACE (parent);
741
742   return (* iface->get_relative_path) (parent, descendant);
743 }
744
745 /**
746  * g_file_resolve_relative_path:
747  * @file: input #GFile.
748  * @relative_path: a given relative path string.
749  *
750  * Resolves a relative path for @file to an absolute path.
751  *
752  * This call does no blocking i/o.
753  * 
754  * Returns: #GFile to the resolved path. %NULL if @relative_path 
755  *     is %NULL or if @file is invalid.
756  **/
757 GFile *
758 g_file_resolve_relative_path (GFile      *file,
759                               const char *relative_path)
760 {
761   GFileIface *iface;
762
763   g_return_val_if_fail (G_IS_FILE (file), NULL);
764   g_return_val_if_fail (relative_path != NULL, NULL);
765
766   iface = G_FILE_GET_IFACE (file);
767
768   return (* iface->resolve_relative_path) (file, relative_path);
769 }
770
771 /**
772  * g_file_enumerate_children:
773  * @file: input #GFile.
774  * @attributes: an attribute query string.
775  * @flags: a set of #GFileQueryInfoFlags.
776  * @cancellable: optional #GCancellable object, %NULL to ignore.
777  * @error: #GError for error reporting.
778  *
779  * Gets the requested information about the files in a directory. The result
780  * is a #GFileEnumerator object that will give out #GFileInfo objects for
781  * all the files in the directory.
782  *
783  * The @attribute value is a string that specifies the file attributes that
784  * should be gathered. It is not an error if it's not possible to read a particular
785  * requested attribute from a file - it just won't be set. @attribute should
786  * be a comma-separated list of attribute or attribute wildcards. The wildcard "*"
787  * means all attributes, and a wildcard like "standard::*" means all attributes in the standard
788  * namespace. An example attribute query be "standard::*,owner::user".
789  * The standard attributes are available as defines, like #G_FILE_ATTRIBUTE_STANDARD_NAME.
790  *
791  * If @cancellable is not %NULL, then the operation can be cancelled by
792  * triggering the cancellable object from another thread. If the operation
793  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
794  * 
795  * If the file does not exist, the G_IO_ERROR_NOT_FOUND error will be returned.
796  * If the file is not a directory, the G_FILE_ERROR_NOTDIR error will be returned.
797  * Other errors are possible too.
798  *
799  * Returns: A #GFileEnumerator if successful, %NULL on error. 
800  **/
801 GFileEnumerator *
802 g_file_enumerate_children (GFile                *file,
803                            const char           *attributes,
804                            GFileQueryInfoFlags   flags,
805                            GCancellable         *cancellable,
806                            GError              **error)
807                            
808 {
809   GFileIface *iface;
810   
811   g_return_val_if_fail (G_IS_FILE (file), NULL);
812
813   if (g_cancellable_set_error_if_cancelled (cancellable, error))
814     return NULL;
815   
816   iface = G_FILE_GET_IFACE (file);
817
818   if (iface->enumerate_children == NULL)
819     {
820       g_set_error (error, G_IO_ERROR,
821                    G_IO_ERROR_NOT_SUPPORTED,
822                    _("Operation not supported"));
823       return NULL;
824     }
825
826   return (* iface->enumerate_children) (file, attributes, flags,
827                                         cancellable, error);
828 }
829
830 /**
831  * g_file_enumerate_children_async:
832  * @file: input #GFile.
833  * @attributes: an attribute query string.
834  * @flags: a set of #GFileQueryInfoFlags.
835  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
836  *     of the request.
837  * @cancellable: optional #GCancellable object, %NULL to ignore.
838  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
839  * @user_data: the data to pass to callback function
840  *
841  * Asynchronously gets the requested information about the files in a directory. The result
842  * is a #GFileEnumerator object that will give out #GFileInfo objects for
843  * all the files in the directory.
844  *
845  * For more details, see g_file_enumerate_children() which is
846  * the synchronous version of this call.
847  *
848  * When the operation is finished, @callback will be called. You can then call
849  * g_file_enumerate_children_finish() to get the result of the operation.
850  **/
851 void
852 g_file_enumerate_children_async (GFile               *file,
853                                  const char          *attributes,
854                                  GFileQueryInfoFlags  flags,
855                                  int                  io_priority,
856                                  GCancellable        *cancellable,
857                                  GAsyncReadyCallback  callback,
858                                  gpointer             user_data)
859 {
860   GFileIface *iface;
861
862   g_return_if_fail (G_IS_FILE (file));
863
864   iface = G_FILE_GET_IFACE (file);
865   (* iface->enumerate_children_async) (file,
866                                        attributes,
867                                        flags,
868                                        io_priority,
869                                        cancellable,
870                                        callback,
871                                        user_data);
872 }
873
874 /**
875  * g_file_enumerate_children_finish:
876  * @file: input #GFile.
877  * @res: a #GAsyncResult.
878  * @error: a #GError.
879  * 
880  * Finishes an async enumerate children operation.
881  * See g_file_enumerate_children_async().
882  *
883  * Returns: a #GFileEnumerator or %NULL if an error occurred.
884  **/
885 GFileEnumerator *
886 g_file_enumerate_children_finish (GFile         *file,
887                                   GAsyncResult  *res,
888                                   GError       **error)
889 {
890   GFileIface *iface;
891   
892   g_return_val_if_fail (G_IS_FILE (file), NULL);
893   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
894
895   if (G_IS_SIMPLE_ASYNC_RESULT (res))
896     {
897       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
898       if (g_simple_async_result_propagate_error (simple, error))
899         return NULL;
900     }
901   
902   iface = G_FILE_GET_IFACE (file);
903   return (* iface->enumerate_children_finish) (file, res, error);
904 }
905
906 /**
907  * g_file_query_exists:
908  * @file: input #GFile.
909  * @cancellable: optional #GCancellable object, %NULL to ignore.
910  *
911  * Utility function to check if a particular file exists. This is
912  * implemented using g_file_query_info() and as such does blocking I/O.
913  *
914  * Note that in many cases it is racy to first check for file existance
915  * and then execute something based on the outcome of that, because the
916  * file might have been created or removed inbetween the operations. The
917  * general approach to handling that is to not check, but just do the
918  * operation and handle the errors as they come.
919  *
920  * As an example of race-free checking, take the case of reading a file, and
921  * if it doesn't exist, creating it. There are two racy versions: read it, and
922  * on error create it; and: check if it exists, if not create it. These
923  * can both result in two processes creating the file (with perhaps a partially
924  * written file as the result). The correct approach is to always try to create
925  * the file with g_file_create() which will either atomically create the file
926  * or fail with a G_IO_ERROR_EXISTS error.
927  *
928  * However, in many cases an existance check is useful in a user
929  * interface, for instance to make a menu item sensitive/insensitive, so that
930  * you don't have to fool users that something is possible and then just show
931  * and error dialog. If you do this, you should make sure to also handle the
932  * errors that can happen due to races when you execute the operation.
933  * 
934  * Returns: %TRUE if the file exists (and can be detected without error), %FALSE otherwise (or if cancelled).
935  */
936 gboolean
937 g_file_query_exists (GFile *file,
938                      GCancellable *cancellable)
939 {
940   GFileInfo *info;
941
942   info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE,
943                             G_FILE_QUERY_INFO_NONE,
944                             cancellable, NULL);
945   if (info != NULL)
946     {
947       g_object_unref (info);
948       return TRUE;
949     }
950   
951   return FALSE;
952 }
953
954 /**
955  * g_file_query_info:
956  * @file: input #GFile.
957  * @attributes: an attribute query string.
958  * @flags: a set of #GFileQueryInfoFlags.
959  * @cancellable: optional #GCancellable object, %NULL to ignore.
960  * @error: a #GError.
961  *
962  * Gets the requested information about specified @file. The result
963  * is a #GFileInfo object that contains key-value attributes (such as 
964  * the type or size of the file).
965  *
966  * The @attribute value is a string that specifies the file attributes that
967  * should be gathered. It is not an error if it's not possible to read a particular
968  * requested attribute from a file - it just won't be set. @attribute should
969  * be a comma-separated list of attribute or attribute wildcards. The wildcard "*"
970  * means all attributes, and a wildcard like "standard::*" means all attributes in the standard
971  * namespace. An example attribute query be "standard::*,owner::user".
972  * The standard attributes are available as defines, like #G_FILE_ATTRIBUTE_STANDARD_NAME.
973  * 
974  * If @cancellable is not %NULL, then the operation can be cancelled by
975  * triggering the cancellable object from another thread. If the operation
976  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
977  *
978  * For symlinks, normally the information about the target of the
979  * symlink is returned, rather than information about the symlink itself.
980  * However if you pass #G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS in @flags the
981  * information about the symlink itself will be returned. Also, for symlinks
982  * that point to non-existing files the information about the symlink itself
983  * will be returned.
984  *
985  * If the file does not exist, the G_IO_ERROR_NOT_FOUND error will be returned.
986  * Other errors are possible too, and depend on what kind of filesystem the file is on.
987  *
988  * Returns: a #GFileInfo for the given @file, or %NULL on error.
989  **/
990 GFileInfo *
991 g_file_query_info (GFile                *file,
992                    const char           *attributes,
993                    GFileQueryInfoFlags   flags,
994                    GCancellable         *cancellable,
995                    GError              **error)
996 {
997   GFileIface *iface;
998   
999   g_return_val_if_fail (G_IS_FILE (file), NULL);
1000
1001   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1002     return NULL;
1003   
1004   iface = G_FILE_GET_IFACE (file);
1005
1006   if (iface->query_info == NULL)
1007     {
1008       g_set_error (error, G_IO_ERROR,
1009                    G_IO_ERROR_NOT_SUPPORTED,
1010                    _("Operation not supported"));
1011       return NULL;
1012     }
1013   
1014   return (* iface->query_info) (file, attributes, flags, cancellable, error);
1015 }
1016
1017 /**
1018  * g_file_query_info_async:
1019  * @file: input #GFile.
1020  * @attributes: an attribute query string.
1021  * @flags: a set of #GFileQueryInfoFlags.
1022  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1023  *     of the request.
1024  * @cancellable: optional #GCancellable object, %NULL to ignore. 
1025  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1026  * @user_data: the data to pass to callback function
1027  * 
1028  * Asynchronously gets the requested information about specified @file. The result
1029  * is a #GFileInfo object that contains key-value attributes (such as type or size
1030  * for the file).
1031  * 
1032  * For more details, see g_file_query_info() which is
1033  * the synchronous version of this call.
1034  *
1035  * When the operation is finished, @callback will be called. You can then call
1036  * g_file_query_info_finish() to get the result of the operation.
1037  **/
1038 void
1039 g_file_query_info_async (GFile               *file,
1040                          const char          *attributes,
1041                          GFileQueryInfoFlags  flags,
1042                          int                  io_priority,
1043                          GCancellable        *cancellable,
1044                          GAsyncReadyCallback  callback,
1045                          gpointer             user_data)
1046 {
1047   GFileIface *iface;
1048   
1049   g_return_if_fail (G_IS_FILE (file));
1050
1051   iface = G_FILE_GET_IFACE (file);
1052   (* iface->query_info_async) (file,
1053                                attributes,
1054                                flags,
1055                                io_priority,
1056                                cancellable,
1057                                callback,
1058                                user_data);
1059 }
1060
1061 /**
1062  * g_file_query_info_finish:
1063  * @file: input #GFile.
1064  * @res: a #GAsyncResult. 
1065  * @error: a #GError. 
1066  * 
1067  * Finishes an asynchronous file info query. 
1068  * See g_file_query_info_async().
1069  * 
1070  * Returns: #GFileInfo for given @file or %NULL on error.
1071  **/
1072 GFileInfo *
1073 g_file_query_info_finish (GFile         *file,
1074                           GAsyncResult  *res,
1075                           GError       **error)
1076 {
1077   GFileIface *iface;
1078
1079   g_return_val_if_fail (G_IS_FILE (file), NULL);
1080   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1081
1082   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1083     {
1084       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1085       if (g_simple_async_result_propagate_error (simple, error))
1086         return NULL;
1087     }
1088   
1089   iface = G_FILE_GET_IFACE (file);
1090   return (* iface->query_info_finish) (file, res, error);
1091 }
1092
1093 /**
1094  * g_file_query_filesystem_info:
1095  * @file: input #GFile.
1096  * @attributes:  an attribute query string.
1097  * @cancellable: optional #GCancellable object, %NULL to ignore. 
1098  * @error: a #GError. 
1099  * 
1100  * Similar to g_file_query_info(), but obtains information
1101  * about the filesystem the @file is on, rather than the file itself.
1102  * For instance the amount of space available and the type of
1103  * the filesystem.
1104  *
1105  * The @attribute value is a string that specifies the file attributes that
1106  * should be gathered. It is not an error if it's not possible to read a particular
1107  * requested attribute from a file - it just won't be set. @attribute should
1108  * be a comma-separated list of attribute or attribute wildcards. The wildcard "*"
1109  * means all attributes, and a wildcard like "fs:*" means all attributes in the fs
1110  * namespace. The standard namespace for filesystem attributes is "fs".
1111  * Common attributes of interest are #G_FILE_ATTRIBUTE_FILESYSTEM_SIZE
1112  * (the total size of the filesystem in bytes), #G_FILE_ATTRIBUTE_FILESYSTEM_FREE (number of
1113  * bytes available), and #G_FILE_ATTRIBUTE_FILESYSTEM_TYPE (type of the filesystem).
1114  * 
1115  * If @cancellable is not %NULL, then the operation can be cancelled by
1116  * triggering the cancellable object from another thread. If the operation
1117  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1118  *
1119  * If the file does not exist, the G_IO_ERROR_NOT_FOUND error will be returned.
1120  * Other errors are possible too, and depend on what kind of filesystem the file is on.
1121  *
1122  * Returns: a #GFileInfo or %NULL if there was an error.
1123  **/
1124 GFileInfo *
1125 g_file_query_filesystem_info (GFile         *file,
1126                               const char    *attributes,
1127                               GCancellable  *cancellable,
1128                               GError       **error)
1129 {
1130   GFileIface *iface;
1131   
1132   g_return_val_if_fail (G_IS_FILE (file), NULL);
1133
1134   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1135     return NULL;
1136   
1137   iface = G_FILE_GET_IFACE (file);
1138
1139   if (iface->query_filesystem_info == NULL)
1140     {
1141       g_set_error (error, G_IO_ERROR,
1142                    G_IO_ERROR_NOT_SUPPORTED,
1143                    _("Operation not supported"));
1144       return NULL;
1145     }
1146   
1147   return (* iface->query_filesystem_info) (file, attributes, cancellable, error);
1148 }
1149
1150 /**
1151  * g_file_query_filesystem_info_async:
1152  * @file: input #GFile.
1153  * @attributes: an attribute query string.
1154  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1155  *     of the request.
1156  * @cancellable: optional #GCancellable object, %NULL to ignore. 
1157  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1158  * @user_data: the data to pass to callback function
1159  * 
1160  * Asynchronously gets the requested information about the filesystem
1161  * that the specified @file is on. The result is a #GFileInfo object
1162  * that contains key-value attributes (such as type or size for the
1163  * file).
1164  * 
1165  * For more details, see g_file_query_filesystem_info() which is the
1166  * synchronous version of this call.
1167  *
1168  * When the operation is finished, @callback will be called. You can
1169  * then call g_file_query_info_finish() to get the result of the
1170  * operation.
1171  **/
1172 void
1173 g_file_query_filesystem_info_async (GFile               *file,
1174                                     const char          *attributes,
1175                                     int                  io_priority,
1176                                     GCancellable        *cancellable,
1177                                     GAsyncReadyCallback  callback,
1178                                     gpointer             user_data)
1179 {
1180   GFileIface *iface;
1181   
1182   g_return_if_fail (G_IS_FILE (file));
1183
1184   iface = G_FILE_GET_IFACE (file);
1185   (* iface->query_filesystem_info_async) (file,
1186                                           attributes,
1187                                           io_priority,
1188                                           cancellable,
1189                                           callback,
1190                                           user_data);
1191 }
1192
1193 /**
1194  * g_file_query_filesystem_info_finish:
1195  * @file: input #GFile.
1196  * @res: a #GAsyncResult. 
1197  * @error: a #GError. 
1198  * 
1199  * Finishes an asynchronous filesystem info query.  See
1200  * g_file_query_filesystem_info_async().
1201  * 
1202  * Returns: #GFileInfo for given @file or %NULL on error.
1203  **/
1204 GFileInfo *
1205 g_file_query_filesystem_info_finish (GFile         *file,
1206                                      GAsyncResult  *res,
1207                                      GError       **error)
1208 {
1209   GFileIface *iface;
1210
1211   g_return_val_if_fail (G_IS_FILE (file), NULL);
1212   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1213
1214   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1215     {
1216       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1217       if (g_simple_async_result_propagate_error (simple, error))
1218         return NULL;
1219     }
1220   
1221   iface = G_FILE_GET_IFACE (file);
1222   return (* iface->query_filesystem_info_finish) (file, res, error);
1223 }
1224
1225 /**
1226  * g_file_find_enclosing_mount:
1227  * @file: input #GFile.
1228  * @cancellable: optional #GCancellable object, %NULL to ignore. 
1229  * @error: a #GError. 
1230  *
1231  * Gets a #GMount for the #GFile. 
1232  *
1233  * If the #GFileIface for @file does not have a mount (e.g. possibly a 
1234  * remote share), @error will be set to %G_IO_ERROR_NOT_FOUND and %NULL
1235  * will be returned.
1236  * 
1237  * If @cancellable is not %NULL, then the operation can be cancelled by
1238  * triggering the cancellable object from another thread. If the operation
1239  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1240  * 
1241  * Returns: a #GMount where the @file is located or %NULL on error.
1242  **/
1243 GMount *
1244 g_file_find_enclosing_mount (GFile         *file,
1245                              GCancellable  *cancellable,
1246                              GError       **error)
1247 {
1248   GFileIface *iface;
1249
1250   g_return_val_if_fail (G_IS_FILE (file), NULL);
1251   
1252   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1253     return NULL;
1254
1255   iface = G_FILE_GET_IFACE (file);
1256   if (iface->find_enclosing_mount == NULL)
1257     {
1258       g_set_error (error, G_IO_ERROR,
1259                    G_IO_ERROR_NOT_FOUND,
1260                    _("Containing mount does not exist"));
1261       return NULL;
1262     }
1263   
1264   return (* iface->find_enclosing_mount) (file, cancellable, error);
1265 }
1266 /**
1267  * g_file_find_enclosing_mount_async:
1268  * @file: a #GFile
1269  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1270  *     of the request.
1271  * @cancellable: optional #GCancellable object, %NULL to ignore.
1272  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1273  * @user_data: the data to pass to callback function
1274  *
1275  * Asynchronously gets the mount for the file.
1276  *
1277  * For more details, see g_file_find_enclosing_mount() which is
1278  * the synchronous version of this call.
1279  *
1280  * When the operation is finished, @callback will be called. You can then call
1281  * g_file_find_enclosing_mount_finish() to get the result of the operation.
1282  */
1283 void
1284 g_file_find_enclosing_mount_async (GFile              *file,
1285                                    int                   io_priority,
1286                                    GCancellable         *cancellable,
1287                                    GAsyncReadyCallback   callback,
1288                                    gpointer              user_data)
1289 {
1290   GFileIface *iface;
1291
1292   g_return_if_fail (G_IS_FILE (file));
1293
1294   iface = G_FILE_GET_IFACE (file);
1295   (* iface->find_enclosing_mount_async) (file,
1296                                          io_priority,
1297                                          cancellable,
1298                                          callback,
1299                                          user_data);
1300 }
1301
1302 /**
1303  * g_file_find_enclosing_mount_finish:
1304  * @file: a #GFile
1305  * @res: a #GAsyncResult
1306  * @error: a #GError
1307  * 
1308  * Finishes an asynchronous find mount request. 
1309  * See g_file_find_enclosing_mount_async().
1310  * 
1311  * Returns: #GMount for given @file or %NULL on error.
1312  **/
1313 GMount *
1314 g_file_find_enclosing_mount_finish (GFile         *file,
1315                                     GAsyncResult  *res,
1316                                     GError       **error)
1317 {
1318   GFileIface *iface;
1319   
1320   g_return_val_if_fail (G_IS_FILE (file), NULL);
1321   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1322
1323   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1324     {
1325       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1326       if (g_simple_async_result_propagate_error (simple, error))
1327         return NULL;
1328     }
1329   
1330   iface = G_FILE_GET_IFACE (file);
1331   return (* iface->find_enclosing_mount_finish) (file, res, error);
1332 }
1333
1334
1335 /**
1336  * g_file_read:
1337  * @file: #GFile to read.
1338  * @cancellable: a #GCancellable
1339  * @error: a #GError, or %NULL
1340  *
1341  * Opens a file for reading. The result is a #GFileInputStream that
1342  * can be used to read the contents of the file.
1343  *
1344  * If @cancellable is not %NULL, then the operation can be cancelled by
1345  * triggering the cancellable object from another thread. If the operation
1346  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1347  * 
1348  * If the file does not exist, the G_IO_ERROR_NOT_FOUND error will be returned.
1349  * If the file is a directory, the G_IO_ERROR_IS_DIRECTORY error will be returned.
1350  * Other errors are possible too, and depend on what kind of filesystem the file is on.
1351  *
1352  * Returns: #GFileInputStream or %NULL on error.
1353  **/
1354 GFileInputStream *
1355 g_file_read (GFile         *file,
1356              GCancellable  *cancellable,
1357              GError       **error)
1358 {
1359   GFileIface *iface;
1360   
1361   g_return_val_if_fail (G_IS_FILE (file), NULL);
1362
1363   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1364     return NULL;
1365
1366   iface = G_FILE_GET_IFACE (file);
1367
1368   if (iface->read_fn == NULL)
1369     {
1370       g_set_error (error, G_IO_ERROR,
1371                    G_IO_ERROR_NOT_SUPPORTED,
1372                    _("Operation not supported"));
1373       return NULL;
1374     }
1375   
1376   return (* iface->read_fn) (file, cancellable, error);
1377 }
1378
1379 /**
1380  * g_file_append_to:
1381  * @file: input #GFile.
1382  * @flags: a set of #GFileCreateFlags.
1383  * @cancellable: optional #GCancellable object, %NULL to ignore.
1384  * @error: a #GError, or %NULL
1385  *
1386  * Gets an output stream for appending data to the file. If
1387  * the file doesn't already exist it is created.
1388  *
1389  * By default files created are generally readable by everyone,
1390  * but if you pass #G_FILE_CREATE_PRIVATE in @flags the file
1391  * will be made readable only to the current user, to the level that
1392  * is supported on the target filesystem.
1393  *
1394  * If @cancellable is not %NULL, then the operation can be cancelled by
1395  * triggering the cancellable object from another thread. If the operation
1396  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1397  *
1398  * Some file systems don't allow all file names, and may
1399  * return an G_IO_ERROR_INVALID_FILENAME error.
1400  * If the file is a directory the G_IO_ERROR_IS_DIRECTORY error will be
1401  * returned. Other errors are possible too, and depend on what kind of
1402  * filesystem the file is on.
1403  * 
1404  * Returns: a #GFileOutputStream.
1405  **/
1406 GFileOutputStream *
1407 g_file_append_to (GFile             *file,
1408                   GFileCreateFlags   flags,
1409                   GCancellable      *cancellable,
1410                   GError           **error)
1411 {
1412   GFileIface *iface;
1413
1414   g_return_val_if_fail (G_IS_FILE (file), NULL);
1415
1416   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1417     return NULL;
1418   
1419   iface = G_FILE_GET_IFACE (file);
1420
1421   if (iface->append_to == NULL)
1422     {
1423       g_set_error (error, G_IO_ERROR,
1424                    G_IO_ERROR_NOT_SUPPORTED,
1425                    _("Operation not supported"));
1426       return NULL;
1427     }
1428   
1429   return (* iface->append_to) (file, flags, cancellable, error);
1430 }
1431
1432 /**
1433  * g_file_create:
1434  * @file: input #GFile.
1435  * @flags: a set of #GFileCreateFlags.
1436  * @cancellable: optional #GCancellable object, %NULL to ignore.
1437  * @error: a #GError, or %NULL
1438  *
1439  * Creates a new file and returns an output stream for writing to it.
1440  * The file must not already exists.
1441  *
1442  * By default files created are generally readable by everyone,
1443  * but if you pass #G_FILE_CREATE_PRIVATE in @flags the file
1444  * will be made readable only to the current user, to the level that
1445  * is supported on the target filesystem.
1446  *
1447  * If @cancellable is not %NULL, then the operation can be cancelled by
1448  * triggering the cancellable object from another thread. If the operation
1449  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1450  *
1451  * If a file or directory with this name already exists the G_IO_ERROR_EXISTS
1452  * error will be returned.
1453  * Some file systems don't allow all file names, and may
1454  * return an G_IO_ERROR_INVALID_FILENAME error, and if the name
1455  * is to long G_IO_ERROR_FILENAME_TOO_LONG will be returned.
1456  * Other errors are possible too, and depend on what kind of
1457  * filesystem the file is on.
1458  * 
1459  * Returns: a #GFileOutputStream for the newly created file, or 
1460  * %NULL on error.
1461  **/
1462 GFileOutputStream *
1463 g_file_create (GFile             *file,
1464                GFileCreateFlags   flags,
1465                GCancellable      *cancellable,
1466                GError           **error)
1467 {
1468   GFileIface *iface;
1469   
1470   g_return_val_if_fail (G_IS_FILE (file), NULL);
1471
1472   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1473     return NULL;
1474   
1475   iface = G_FILE_GET_IFACE (file);
1476
1477   if (iface->create == NULL)
1478     {
1479       g_set_error (error, G_IO_ERROR,
1480                    G_IO_ERROR_NOT_SUPPORTED,
1481                    _("Operation not supported"));
1482       return NULL;
1483     }
1484   
1485   return (* iface->create) (file, flags, cancellable, error);
1486 }
1487
1488 /**
1489  * g_file_replace:
1490  * @file: input #GFile.
1491  * @etag: an optional <link linkend="gfile-etag">entity tag</link> for the 
1492  *     current #GFile, or #NULL to ignore.
1493  * @make_backup: %TRUE if a backup should be created.
1494  * @flags: a set of #GFileCreateFlags.
1495  * @cancellable: optional #GCancellable object, %NULL to ignore.
1496  * @error: a #GError, or %NULL
1497  *
1498  * Returns an output stream for overwriting the file, possibly
1499  * creating a backup copy of the file first.
1500  *
1501  * This will try to replace the file in the safest way possible so
1502  * that any errors during the writing will not affect an already
1503  * existing copy of the file. For instance, for local files it
1504  * may write to a temporary file and then atomically rename over
1505  * the destination when the stream is closed.
1506  * 
1507  * By default files created are generally readable by everyone,
1508  * but if you pass #G_FILE_CREATE_PRIVATE in @flags the file
1509  * will be made readable only to the current user, to the level that
1510  * is supported on the target filesystem.
1511  *
1512  * If @cancellable is not %NULL, then the operation can be cancelled by
1513  * triggering the cancellable object from another thread. If the operation
1514  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1515  * 
1516  * If you pass in a non-#NULL @etag value, then this value is
1517  * compared to the current entity tag of the file, and if they differ
1518  * an G_IO_ERROR_WRONG_ETAG error is returned. This generally means
1519  * that the file has been changed since you last read it. You can get
1520  * the new etag from g_file_output_stream_get_etag() after you've
1521  * finished writing and closed the #GFileOutputStream. When you load
1522  * a new file you can use g_file_input_stream_query_info() to get
1523  * the etag of the file.
1524  * 
1525  * If @make_backup is %TRUE, this function will attempt to make a backup
1526  * of the current file before overwriting it. If this fails a G_IO_ERROR_CANT_CREATE_BACKUP
1527  * error will be returned. If you want to replace anyway, try again with
1528  * @make_backup set to %FALSE.
1529  *
1530  * If the file is a directory the G_IO_ERROR_IS_DIRECTORY error will be returned,
1531  * and if the file is some other form of non-regular file then a
1532  * G_IO_ERROR_NOT_REGULAR_FILE error will be returned.
1533  * Some file systems don't allow all file names, and may
1534  * return an G_IO_ERROR_INVALID_FILENAME error, and if the name
1535  * is to long G_IO_ERROR_FILENAME_TOO_LONG will be returned.
1536  * Other errors are possible too, and depend on what kind of
1537  * filesystem the file is on.
1538  *
1539  * Returns: a #GFileOutputStream or %NULL on error. 
1540  **/
1541 GFileOutputStream *
1542 g_file_replace (GFile             *file,
1543                 const char        *etag,
1544                 gboolean           make_backup,
1545                 GFileCreateFlags   flags,
1546                 GCancellable      *cancellable,
1547                 GError           **error)
1548 {
1549   GFileIface *iface;
1550
1551   g_return_val_if_fail (G_IS_FILE (file), NULL);
1552
1553   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1554     return NULL;
1555   
1556   iface = G_FILE_GET_IFACE (file);
1557
1558   if (iface->replace == NULL)
1559     {
1560       g_set_error (error, G_IO_ERROR,
1561                    G_IO_ERROR_NOT_SUPPORTED,
1562                    _("Operation not supported"));
1563       return NULL;
1564     }
1565   
1566   
1567   /* Handle empty tag string as NULL in consistent way. */
1568   if (etag && *etag == 0)
1569     etag = NULL;
1570   
1571   return (* iface->replace) (file, etag, make_backup, flags, cancellable, error);
1572 }
1573
1574 /**
1575  * g_file_read_async:
1576  * @file: input #GFile.
1577  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1578  *     of the request. 
1579  * @cancellable: optional #GCancellable object, %NULL to ignore.
1580  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1581  * @user_data: the data to pass to callback function
1582  *
1583  * Asynchronously opens @file for reading.
1584  *
1585  * For more details, see g_file_read() which is
1586  * the synchronous version of this call.
1587  *
1588  * When the operation is finished, @callback will be called. You can then call
1589  * g_file_read_finish() to get the result of the operation.
1590  **/
1591 void
1592 g_file_read_async (GFile               *file,
1593                    int                  io_priority,
1594                    GCancellable        *cancellable,
1595                    GAsyncReadyCallback  callback,
1596                    gpointer             user_data)
1597 {
1598   GFileIface *iface;
1599   
1600   g_return_if_fail (G_IS_FILE (file));
1601
1602   iface = G_FILE_GET_IFACE (file);
1603   (* iface->read_async) (file,
1604                          io_priority,
1605                          cancellable,
1606                          callback,
1607                          user_data);
1608 }
1609
1610 /**
1611  * g_file_read_finish:
1612  * @file: input #GFile.
1613  * @res: a #GAsyncResult. 
1614  * @error: a #GError, or %NULL
1615  *
1616  * Finishes an asynchronous file read operation started with 
1617  * g_file_read_async(). 
1618  *  
1619  * Returns: a #GFileInputStream or %NULL on error.
1620  **/
1621 GFileInputStream *
1622 g_file_read_finish (GFile         *file,
1623                     GAsyncResult  *res,
1624                     GError       **error)
1625 {
1626   GFileIface *iface;
1627   
1628   g_return_val_if_fail (G_IS_FILE (file), NULL);
1629   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1630
1631   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1632     {
1633       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1634       if (g_simple_async_result_propagate_error (simple, error))
1635         return NULL;
1636     }
1637   
1638   iface = G_FILE_GET_IFACE (file);
1639   return (* iface->read_finish) (file, res, error);
1640 }
1641
1642 /**
1643  * g_file_append_to_async:
1644  * @file: input #GFile.
1645  * @flags: a set of #GFileCreateFlags.
1646  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1647  *     of the request. 
1648  * @cancellable: optional #GCancellable object, %NULL to ignore.
1649  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1650  * @user_data: the data to pass to callback function
1651  * 
1652  * Asynchronously opens @file for appending.
1653  *
1654  * For more details, see g_file_append_to() which is
1655  * the synchronous version of this call.
1656  *
1657  * When the operation is finished, @callback will be called. You can then call
1658  * g_file_append_to_finish() to get the result of the operation.
1659  **/
1660 void
1661 g_file_append_to_async (GFile               *file,
1662                         GFileCreateFlags     flags,
1663                         int                  io_priority,
1664                         GCancellable        *cancellable,
1665                         GAsyncReadyCallback  callback,
1666                         gpointer             user_data)
1667 {
1668   GFileIface *iface;
1669   
1670   g_return_if_fail (G_IS_FILE (file));
1671
1672   iface = G_FILE_GET_IFACE (file);
1673   (* iface->append_to_async) (file,
1674                               flags,
1675                               io_priority,
1676                               cancellable,
1677                               callback,
1678                               user_data);
1679 }
1680
1681 /**
1682  * g_file_append_to_finish:
1683  * @file: input #GFile.
1684  * @res: #GAsyncResult
1685  * @error: a #GError, or %NULL
1686  * 
1687  * Finishes an asynchronous file append operation started with 
1688  * g_file_append_to_async(). 
1689  * 
1690  * Returns: a valid #GFileOutputStream or %NULL on error.
1691  **/
1692 GFileOutputStream *
1693 g_file_append_to_finish (GFile         *file,
1694                          GAsyncResult  *res,
1695                          GError       **error)
1696 {
1697   GFileIface *iface;
1698   
1699   g_return_val_if_fail (G_IS_FILE (file), NULL);
1700   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1701
1702   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1703     {
1704       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1705       if (g_simple_async_result_propagate_error (simple, error))
1706         return NULL;
1707     }
1708   
1709   iface = G_FILE_GET_IFACE (file);
1710   return (* iface->append_to_finish) (file, res, error);
1711 }
1712
1713 /**
1714  * g_file_create_async:
1715  * @file: input #GFile.
1716  * @flags: a set of #GFileCreateFlags.
1717  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1718  *     of the request.
1719  * @cancellable: optional #GCancellable object, %NULL to ignore.
1720  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1721  * @user_data: the data to pass to callback function
1722  * 
1723  * Asynchronously creates a new file and returns an output stream for writing to it.
1724  * The file must not already exists.
1725  *
1726  * For more details, see g_file_create() which is
1727  * the synchronous version of this call.
1728  *
1729  * When the operation is finished, @callback will be called. You can then call
1730  * g_file_create_finish() to get the result of the operation.
1731  **/
1732 void
1733 g_file_create_async (GFile               *file,
1734                      GFileCreateFlags     flags,
1735                      int                  io_priority,
1736                      GCancellable        *cancellable,
1737                      GAsyncReadyCallback  callback,
1738                      gpointer             user_data)
1739 {
1740   GFileIface *iface;
1741   
1742   g_return_if_fail (G_IS_FILE (file));
1743
1744   iface = G_FILE_GET_IFACE (file);
1745   (* iface->create_async) (file,
1746                            flags,
1747                            io_priority,
1748                            cancellable,
1749                            callback,
1750                            user_data);
1751 }
1752
1753 /**
1754  * g_file_create_finish:
1755  * @file: input #GFile.
1756  * @res: a #GAsyncResult. 
1757  * @error: a #GError, or %NULL
1758  * 
1759  * Finishes an asynchronous file create operation started with 
1760  * g_file_create_async(). 
1761  * 
1762  * Returns: a #GFileOutputStream or %NULL on error.
1763  **/
1764 GFileOutputStream *
1765 g_file_create_finish (GFile         *file,
1766                       GAsyncResult  *res,
1767                       GError       **error)
1768 {
1769   GFileIface *iface;
1770   
1771   g_return_val_if_fail (G_IS_FILE (file), NULL);
1772   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1773
1774   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1775     {
1776       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1777       if (g_simple_async_result_propagate_error (simple, error))
1778         return NULL;
1779     }
1780   
1781   iface = G_FILE_GET_IFACE (file);
1782   return (* iface->create_finish) (file, res, error);
1783 }
1784
1785 /**
1786  * g_file_replace_async:
1787  * @file: input #GFile.
1788  * @etag: an <link linkend="gfile-etag">entity tag</link> for the 
1789  *     current #GFile, or NULL to ignore.
1790  * @make_backup: %TRUE if a backup should be created.
1791  * @flags: a set of #GFileCreateFlags.
1792  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1793  *     of the request.
1794  * @cancellable: optional #GCancellable object, %NULL to ignore.
1795  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1796  * @user_data: the data to pass to callback function
1797  *
1798  * Asynchronously overwrites the file, replacing the contents, possibly
1799  * creating a backup copy of the file first.
1800  *
1801  * For more details, see g_file_replace() which is
1802  * the synchronous version of this call.
1803  *
1804  * When the operation is finished, @callback will be called. You can then call
1805  * g_file_replace_finish() to get the result of the operation.
1806  **/
1807 void
1808 g_file_replace_async (GFile               *file,
1809                       const char          *etag,
1810                       gboolean             make_backup,
1811                       GFileCreateFlags     flags,
1812                       int                  io_priority,
1813                       GCancellable        *cancellable,
1814                       GAsyncReadyCallback  callback,
1815                       gpointer             user_data)
1816 {
1817   GFileIface *iface;
1818   
1819   g_return_if_fail (G_IS_FILE (file));
1820
1821   iface = G_FILE_GET_IFACE (file);
1822   (* iface->replace_async) (file,
1823                             etag,
1824                             make_backup,
1825                             flags,
1826                             io_priority,
1827                             cancellable,
1828                             callback,
1829                             user_data);
1830 }
1831
1832 /**
1833  * g_file_replace_finish:
1834  * @file: input #GFile.
1835  * @res: a #GAsyncResult. 
1836  * @error: a #GError, or %NULL
1837  * 
1838  * Finishes an asynchronous file replace operation started with 
1839  * g_file_replace_async(). 
1840  * 
1841  * Returns: a #GFileOutputStream, or %NULL on error.
1842  **/
1843 GFileOutputStream *
1844 g_file_replace_finish (GFile         *file,
1845                        GAsyncResult  *res,
1846                        GError       **error)
1847 {
1848   GFileIface *iface;
1849   
1850   g_return_val_if_fail (G_IS_FILE (file), NULL);
1851   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1852
1853   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1854     {
1855       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1856       if (g_simple_async_result_propagate_error (simple, error))
1857         return NULL;
1858     }
1859   
1860   iface = G_FILE_GET_IFACE (file);
1861   return (* iface->replace_finish) (file, res, error);
1862 }
1863
1864 static gboolean
1865 copy_symlink (GFile           *destination,
1866               GFileCopyFlags   flags,
1867               GCancellable    *cancellable,
1868               const char      *target,
1869               GError         **error)
1870 {
1871   GError *my_error;
1872   gboolean tried_delete;
1873   GFileInfo *info;
1874   GFileType file_type;
1875
1876   tried_delete = FALSE;
1877
1878  retry:
1879   my_error = NULL;
1880   if (!g_file_make_symbolic_link (destination, target, cancellable, &my_error))
1881     {
1882       /* Maybe it already existed, and we want to overwrite? */
1883       if (!tried_delete && (flags & G_FILE_COPY_OVERWRITE) && 
1884           my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_EXISTS)
1885         {
1886           g_error_free (my_error);
1887
1888
1889           /* Don't overwrite if the destination is a directory */
1890           info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_TYPE,
1891                                     G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1892                                     cancellable, &my_error);
1893           if (info != NULL)
1894             {
1895               file_type = g_file_info_get_file_type (info);
1896               g_object_unref (info);
1897               
1898               if (file_type == G_FILE_TYPE_DIRECTORY)
1899                 {
1900                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY,
1901                                _("Can't copy over directory"));
1902                   return FALSE;
1903                 }
1904             }
1905           
1906           if (!g_file_delete (destination, cancellable, error))
1907             return FALSE;
1908           
1909           tried_delete = TRUE;
1910           goto retry;
1911         }
1912             /* Nah, fail */
1913       g_propagate_error (error, my_error);
1914       return FALSE;
1915     }
1916
1917   return TRUE;
1918 }
1919
1920 static GInputStream *
1921 open_source_for_copy (GFile           *source,
1922                       GFile           *destination,
1923                       GFileCopyFlags   flags,
1924                       GCancellable    *cancellable,
1925                       GError         **error)
1926 {
1927   GError *my_error;
1928   GInputStream *in;
1929   GFileInfo *info;
1930   GFileType file_type;
1931   
1932   my_error = NULL;
1933   in = (GInputStream *)g_file_read (source, cancellable, &my_error);
1934   if (in != NULL)
1935     return in;
1936
1937   /* There was an error opening the source, try to set a good error for it: */
1938
1939   if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_IS_DIRECTORY)
1940     {
1941       /* The source is a directory, don't fail with WOULD_RECURSE immediately, 
1942        * as that is less useful to the app. Better check for errors on the 
1943        * target instead. 
1944        */
1945       g_error_free (my_error);
1946       my_error = NULL;
1947       
1948       info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_TYPE,
1949                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1950                                 cancellable, &my_error);
1951       if (info != NULL)
1952         {
1953           file_type = g_file_info_get_file_type (info);
1954           g_object_unref (info);
1955           
1956           if (flags & G_FILE_COPY_OVERWRITE)
1957             {
1958               if (file_type == G_FILE_TYPE_DIRECTORY)
1959                 {
1960                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_MERGE,
1961                                _("Can't copy directory over directory"));
1962                   return NULL;
1963                 }
1964               /* continue to would_recurse error */
1965             }
1966           else
1967             {
1968               g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
1969                            _("Target file exists"));
1970               return NULL;
1971             }
1972         }
1973       else
1974         {
1975           /* Error getting info from target, return that error 
1976            * (except for NOT_FOUND, which is no error here) 
1977            */
1978           if (my_error->domain != G_IO_ERROR && my_error->code != G_IO_ERROR_NOT_FOUND)
1979             {
1980               g_propagate_error (error, my_error);
1981               return NULL;
1982             }
1983           g_error_free (my_error);
1984         }
1985       
1986       g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE,
1987                    _("Can't recursively copy directory"));
1988       return NULL;
1989     }
1990
1991   g_propagate_error (error, my_error);
1992   return NULL;
1993 }
1994
1995 static gboolean
1996 should_copy (GFileAttributeInfo *info, 
1997              gboolean            as_move)
1998 {
1999   if (as_move)
2000     return info->flags & G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED;
2001   return info->flags & G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE;
2002 }
2003
2004 static char *
2005 build_attribute_list_for_copy (GFileAttributeInfoList *attributes,
2006                                GFileAttributeInfoList *namespaces,
2007                                gboolean                as_move)
2008 {
2009   GString *s;
2010   gboolean first;
2011   int i;
2012   
2013   first = TRUE;
2014   s = g_string_new ("");
2015
2016   if (attributes)
2017     {
2018       for (i = 0; i < attributes->n_infos; i++)
2019         {
2020           if (should_copy (&attributes->infos[i], as_move))
2021             {
2022               if (first)
2023                 first = FALSE;
2024               else
2025                 g_string_append_c (s, ',');
2026                 
2027               g_string_append (s, attributes->infos[i].name);
2028             }
2029         }
2030     }
2031
2032   if (namespaces)
2033     {
2034       for (i = 0; i < namespaces->n_infos; i++)
2035         {
2036           if (should_copy (&namespaces->infos[i], as_move))
2037             {
2038               if (first)
2039                 first = FALSE;
2040               else
2041                 g_string_append_c (s, ',');
2042                 
2043               g_string_append (s, namespaces->infos[i].name);
2044               g_string_append (s, ":*");
2045             }
2046         }
2047     }
2048
2049   return g_string_free (s, FALSE);
2050 }
2051
2052 /**
2053  * g_file_copy_attributes:
2054  * @source: a #GFile with attributes.
2055  * @destination: a #GFile to copy attributes to.
2056  * @flags: a set of #GFileCopyFlags.
2057  * @cancellable: optional #GCancellable object, %NULL to ignore.
2058  * @error: a #GError, %NULL to ignore.
2059  *
2060  * Copies the file attributes from @source to @destination. 
2061  *
2062  * Normally only a subset of the file attributes are copied,
2063  * those that are copies in a normal file copy operation
2064  * (which for instance does not include e.g. mtime). However
2065  * if #G_FILE_COPY_ALL_METADATA is specified in @flags, then
2066  * all the metadata that is possible to copy is copied.
2067  *
2068  * Returns: %TRUE if the attributes were copied successfully, %FALSE otherwise.
2069  **/
2070 gboolean
2071 g_file_copy_attributes (GFile           *source,
2072                         GFile           *destination,
2073                         GFileCopyFlags   flags,
2074                         GCancellable    *cancellable,
2075                         GError         **error)
2076 {
2077   GFileAttributeInfoList *attributes, *namespaces;
2078   char *attrs_to_read;
2079   gboolean res;
2080   GFileInfo *info;
2081   gboolean as_move;
2082   gboolean source_nofollow_symlinks;
2083
2084   as_move = flags & G_FILE_COPY_ALL_METADATA;
2085   source_nofollow_symlinks = flags & G_FILE_COPY_NOFOLLOW_SYMLINKS;
2086
2087   /* Ignore errors here, if the target supports no attributes there is nothing to copy */
2088   attributes = g_file_query_settable_attributes (destination, cancellable, NULL);
2089   namespaces = g_file_query_writable_namespaces (destination, cancellable, NULL);
2090
2091   if (attributes == NULL && namespaces == NULL)
2092     return TRUE;
2093
2094   attrs_to_read = build_attribute_list_for_copy (attributes, namespaces, as_move);
2095
2096   /* Ignore errors here, if we can't read some info (e.g. if it doesn't exist)
2097    * we just don't copy it. 
2098    */
2099   info = g_file_query_info (source, attrs_to_read,
2100                             source_nofollow_symlinks ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS:0,
2101                             cancellable,
2102                             NULL);
2103
2104   g_free (attrs_to_read);
2105   
2106   res = TRUE;
2107   if  (info)
2108     {
2109       res = g_file_set_attributes_from_info (destination,
2110                                              info, 0,
2111                                              cancellable,
2112                                              error);
2113       g_object_unref (info);
2114     }
2115   
2116   g_file_attribute_info_list_unref (attributes);
2117   g_file_attribute_info_list_unref (namespaces);
2118   
2119   return res;
2120 }
2121
2122 /* Closes the streams */
2123 static gboolean
2124 copy_stream_with_progress (GInputStream           *in,
2125                            GOutputStream          *out,
2126                            GCancellable           *cancellable,
2127                            GFileProgressCallback   progress_callback,
2128                            gpointer                progress_callback_data,
2129                            GError                **error)
2130 {
2131   gssize n_read, n_written;
2132   goffset current_size;
2133   char buffer[8192], *p;
2134   gboolean res;
2135   goffset total_size;
2136   GFileInfo *info;
2137
2138   total_size = 0;
2139   info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (in),
2140                                          G_FILE_ATTRIBUTE_STANDARD_SIZE,
2141                                          cancellable, NULL);
2142   if (info)
2143     {
2144       total_size = g_file_info_get_size (info);
2145       g_object_unref (info);
2146     }
2147   
2148   current_size = 0;
2149   res = TRUE;
2150   while (TRUE)
2151     {
2152       n_read = g_input_stream_read (in, buffer, sizeof (buffer), cancellable, error);
2153       if (n_read == -1)
2154         {
2155           res = FALSE;
2156           break;
2157         }
2158         
2159       if (n_read == 0)
2160         break;
2161
2162       current_size += n_read;
2163
2164       p = buffer;
2165       while (n_read > 0)
2166         {
2167           n_written = g_output_stream_write (out, p, n_read, cancellable, error);
2168           if (n_written == -1)
2169             {
2170               res = FALSE;
2171               break;
2172             }
2173
2174           p += n_written;
2175           n_read -= n_written;
2176         }
2177
2178       if (!res)
2179         break;
2180       
2181       if (progress_callback)
2182         progress_callback (current_size, total_size, progress_callback_data);
2183     }
2184
2185   if (!res)
2186     error = NULL; /* Ignore further errors */
2187
2188   /* Make sure we send full copied size */
2189   if (progress_callback)
2190     progress_callback (current_size, total_size, progress_callback_data);
2191
2192   
2193   /* Don't care about errors in source here */
2194   g_input_stream_close (in, cancellable, NULL);
2195
2196   /* But write errors on close are bad! */
2197   if (!g_output_stream_close (out, cancellable, error))
2198     res = FALSE;
2199
2200   g_object_unref (in);
2201   g_object_unref (out);
2202       
2203   return res;
2204 }
2205
2206 static gboolean
2207 file_copy_fallback (GFile                  *source,
2208                     GFile                  *destination,
2209                     GFileCopyFlags          flags,
2210                     GCancellable           *cancellable,
2211                     GFileProgressCallback   progress_callback,
2212                     gpointer                progress_callback_data,
2213                     GError                **error)
2214 {
2215   GInputStream *in;
2216   GOutputStream *out;
2217   GFileInfo *info;
2218   const char *target;
2219
2220   /* Maybe copy the symlink? */
2221   if (flags & G_FILE_COPY_NOFOLLOW_SYMLINKS)
2222     {
2223       info = g_file_query_info (source,
2224                                 G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
2225                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
2226                                 cancellable,
2227                                 error);
2228       if (info == NULL)
2229         return FALSE;
2230
2231       if (g_file_info_get_file_type (info) == G_FILE_TYPE_SYMBOLIC_LINK &&
2232           (target = g_file_info_get_symlink_target (info)) != NULL)
2233         {
2234           if (!copy_symlink (destination, flags, cancellable, target, error))
2235             {
2236               g_object_unref (info);
2237               return FALSE;
2238             }
2239           
2240           g_object_unref (info);
2241           goto copied_file;
2242         }
2243       
2244       g_object_unref (info);
2245     }
2246   
2247   in = open_source_for_copy (source, destination, flags, cancellable, error);
2248   if (in == NULL)
2249     return FALSE;
2250   
2251   if (flags & G_FILE_COPY_OVERWRITE)
2252     {
2253       out = (GOutputStream *)g_file_replace (destination,
2254                                              NULL, 0,
2255                                              flags & G_FILE_COPY_BACKUP,
2256                                              cancellable, error);
2257     }
2258   else
2259     {
2260       out = (GOutputStream *)g_file_create (destination, 0, cancellable, error);
2261     }
2262
2263   if (out == NULL)
2264     {
2265       g_object_unref (in);
2266       return FALSE;
2267     }
2268
2269   if (!copy_stream_with_progress (in, out, cancellable,
2270                                   progress_callback, progress_callback_data,
2271                                   error))
2272     return FALSE;
2273
2274  copied_file:
2275
2276   /* Ignore errors here. Failure to copy metadata is not a hard error */
2277   g_file_copy_attributes (source, destination,
2278                           flags, cancellable, NULL);
2279   
2280   return TRUE;
2281 }
2282
2283 /**
2284  * g_file_copy:
2285  * @source: input #GFile.
2286  * @destination: destination #GFile
2287  * @flags: set of #GFileCopyFlags
2288  * @cancellable: optional #GCancellable object, %NULL to ignore.
2289  * @progress_callback: function to callback with progress information
2290  * @progress_callback_data: user data to pass to @progress_callback
2291  * @error: #GError to set on error, or %NULL
2292  *
2293  * Copies the file @source to the location specified by @destination.
2294  * Can not handle recursive copies of directories.
2295  *
2296  * If the flag #G_FILE_COPY_OVERWRITE is specified an already
2297  * existing @destination file is overwritten.
2298  *
2299  * If the flag #G_FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks
2300  * will be copied as symlinks, otherwise the target of the
2301  * @source symlink will be copied.
2302  *
2303  * If @cancellable is not %NULL, then the operation can be cancelled by
2304  * triggering the cancellable object from another thread. If the operation
2305  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2306  * 
2307  * If @progress_callback is not %NULL, then the operation can be monitored by
2308  * setting this to a #GFileProgressCallback function. @progress_callback_data
2309  * will be passed to this function. It is guaranteed that this callback will
2310  * be called after all data has been transferred with the total number of bytes
2311  * copied during the operation.
2312  * 
2313  * If the @source file does not exist then the G_IO_ERROR_NOT_FOUND
2314  * error is returned, independent on the status of the @destination.
2315  *
2316  * If #G_FILE_COPY_OVERWRITE is not specified and the target exists, then the
2317  * error G_IO_ERROR_EXISTS is returned.
2318  *
2319  * If trying to overwrite a file over a directory the G_IO_ERROR_IS_DIRECTORY
2320  * error is returned. If trying to overwrite a directory with a directory the
2321  * G_IO_ERROR_WOULD_MERGE error is returned.
2322  *
2323  * If the source is a directory and the target does not exist, or #G_FILE_COPY_OVERWRITE is
2324  * specified and the target is a file, then the G_IO_ERROR_WOULD_RECURSE error
2325  * is returned.
2326  *
2327  * If you are interested in copying the #GFile object itself (not the on-disk
2328  * file), see g_file_dup().
2329  *
2330  * Returns: %TRUE on success, %FALSE otherwise.
2331  **/
2332 gboolean
2333 g_file_copy (GFile                  *source,
2334              GFile                  *destination,
2335              GFileCopyFlags          flags,
2336              GCancellable           *cancellable,
2337              GFileProgressCallback   progress_callback,
2338              gpointer                progress_callback_data,
2339              GError                **error)
2340 {
2341   GFileIface *iface;
2342   GError *my_error;
2343   gboolean res;
2344
2345   g_return_val_if_fail (G_IS_FILE (source), FALSE);
2346   g_return_val_if_fail (G_IS_FILE (destination), FALSE);
2347
2348   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2349     return FALSE;
2350   
2351   iface = G_FILE_GET_IFACE (destination);
2352   if (iface->copy)
2353     {
2354       my_error = NULL;
2355       res = (* iface->copy) (source, destination,
2356                              flags, cancellable,
2357                              progress_callback, progress_callback_data,
2358                              &my_error);
2359       
2360       if (res)
2361         return TRUE;
2362       
2363       if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2364         {
2365           g_propagate_error (error, my_error);
2366               return FALSE;
2367         }
2368     }
2369
2370   /* If the types are different, and the destination method failed
2371      also try the source method */
2372   if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination))
2373     {
2374       iface = G_FILE_GET_IFACE (source);
2375       
2376       if (iface->copy)
2377         {
2378           my_error = NULL;
2379           res = (* iface->copy) (source, destination,
2380                                  flags, cancellable,
2381                                  progress_callback, progress_callback_data,
2382                                  &my_error);
2383           
2384           if (res)
2385             return TRUE;
2386           
2387           if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2388             {
2389               g_propagate_error (error, my_error);
2390               return FALSE;
2391             }
2392         }
2393     }
2394   
2395   return file_copy_fallback (source, destination, flags, cancellable,
2396                              progress_callback, progress_callback_data,
2397                              error);
2398 }
2399
2400 /**
2401  * g_file_copy_async:
2402  * @source: input #GFile.
2403  * @destination: destination #GFile
2404  * @flags: set of #GFileCopyFlags
2405  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
2406  *     of the request. 
2407  * @cancellable: optional #GCancellable object, %NULL to ignore.
2408  * @progress_callback: function to callback with progress information
2409  * @progress_callback_data: user data to pass to @progress_callback
2410  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
2411  * @user_data: the data to pass to callback function
2412  *
2413  * Copies the file @source to the location specified by @destination 
2414  * asynchronously. For details of the behaviour, see g_file_copy().
2415  *
2416  * If @progress_callback is not %NULL, then that function that will be called
2417  * just like in g_file_copy(), however the callback will run in the main loop,
2418  * not in the thread that is doing the I/O operation.
2419  *
2420  * When the operation is finished, @callback will be called. You can then call
2421  * g_file_copy_finish() to get the result of the operation.
2422  **/
2423 void
2424 g_file_copy_async (GFile                  *source,
2425                    GFile                  *destination,
2426                    GFileCopyFlags          flags,
2427                    int                     io_priority,
2428                    GCancellable           *cancellable,
2429                    GFileProgressCallback   progress_callback,
2430                    gpointer                progress_callback_data,
2431                    GAsyncReadyCallback     callback,
2432                    gpointer                user_data)
2433 {
2434   GFileIface *iface;
2435
2436   g_return_if_fail (G_IS_FILE (source));
2437   g_return_if_fail (G_IS_FILE (destination));
2438
2439   iface = G_FILE_GET_IFACE (source);
2440   (* iface->copy_async) (source,
2441                          destination,
2442                          flags,
2443                          io_priority,
2444                          cancellable,
2445                          progress_callback,
2446                          progress_callback_data,
2447                          callback,
2448                          user_data);
2449 }
2450
2451 /**
2452  * g_file_copy_finish:
2453  * @file: input #GFile.
2454  * @res: a #GAsyncResult. 
2455  * @error: a #GError, or %NULL
2456  * 
2457  * Finishes copying the file started with 
2458  * g_file_copy_async().
2459  * 
2460  * Returns: a %TRUE on success, %FALSE on error.
2461  **/
2462 gboolean
2463 g_file_copy_finish (GFile        *file,
2464                     GAsyncResult *res,
2465                     GError      **error)
2466 {
2467   GFileIface *iface;
2468   
2469   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2470   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
2471
2472   if (G_IS_SIMPLE_ASYNC_RESULT (res))
2473     {
2474       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
2475       
2476       if (g_simple_async_result_propagate_error (simple, error))
2477         return FALSE;
2478     }
2479   
2480   iface = G_FILE_GET_IFACE (file);
2481   return (* iface->copy_finish) (file, res, error);
2482 }
2483
2484 /**
2485  * g_file_move:
2486  * @source: #GFile pointing to the source location.
2487  * @destination: #GFile pointing to the destination location.
2488  * @flags: set of #GFileCopyFlags.
2489  * @cancellable: optional #GCancellable object, %NULL to ignore.
2490  * @progress_callback: #GFileProgressCallback function for updates.
2491  * @progress_callback_data: gpointer to user data for the callback function.
2492  * @error: #GError for returning error conditions, or %NULL
2493  *
2494  *
2495  * Tries to move the file or directory @source to the location specified by @destination.
2496  * If native move operations are supported then this is used, otherwise a copy + delete
2497  * fallback is used. The native implementation may support moving directories (for instance
2498  * on moves inside the same filesystem), but the fallback code does not.
2499  * 
2500  * If the flag #G_FILE_COPY_OVERWRITE is specified an already
2501  * existing @destination file is overwritten.
2502  *
2503  * If the flag #G_FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks
2504  * will be copied as symlinks, otherwise the target of the
2505  * @source symlink will be copied.
2506  *
2507  * If @cancellable is not %NULL, then the operation can be cancelled by
2508  * triggering the cancellable object from another thread. If the operation
2509  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2510  * 
2511  * If @progress_callback is not %NULL, then the operation can be monitored by
2512  * setting this to a #GFileProgressCallback function. @progress_callback_data
2513  * will be passed to this function. It is guaranteed that this callback will
2514  * be called after all data has been transferred with the total number of bytes
2515  * copied during the operation.
2516  * 
2517  * If the @source file does not exist then the G_IO_ERROR_NOT_FOUND
2518  * error is returned, independent on the status of the @destination.
2519  *
2520  * If #G_FILE_COPY_OVERWRITE is not specified and the target exists, then the
2521  * error G_IO_ERROR_EXISTS is returned.
2522  *
2523  * If trying to overwrite a file over a directory the G_IO_ERROR_IS_DIRECTORY
2524  * error is returned. If trying to overwrite a directory with a directory the
2525  * G_IO_ERROR_WOULD_MERGE error is returned.
2526  *
2527  * If the source is a directory and the target does not exist, or #G_FILE_COPY_OVERWRITE is
2528  * specified and the target is a file, then the G_IO_ERROR_WOULD_RECURSE error
2529  * may be returned (if the native move operation isn't available).
2530  *
2531  * Returns: %TRUE on successful move, %FALSE otherwise.
2532  **/
2533 gboolean
2534 g_file_move (GFile                  *source,
2535              GFile                  *destination,
2536              GFileCopyFlags          flags,
2537              GCancellable           *cancellable,
2538              GFileProgressCallback   progress_callback,
2539              gpointer                progress_callback_data,
2540              GError                **error)
2541 {
2542   GFileIface *iface;
2543   GError *my_error;
2544   gboolean res;
2545
2546   g_return_val_if_fail (G_IS_FILE (source), FALSE);
2547   g_return_val_if_fail (G_IS_FILE (destination), FALSE);
2548
2549   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2550     return FALSE;
2551   
2552   iface = G_FILE_GET_IFACE (destination);
2553   if (iface->move)
2554     {
2555       my_error = NULL;
2556       res = (* iface->move) (source, destination,
2557                              flags, cancellable,
2558                              progress_callback, progress_callback_data,
2559                              &my_error);
2560       
2561       if (res)
2562         return TRUE;
2563       
2564       if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2565         {
2566           g_propagate_error (error, my_error);
2567           return FALSE;
2568         }
2569     }
2570
2571   /* If the types are different, and the destination method failed
2572      also try the source method */
2573   if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination))
2574     {
2575       iface = G_FILE_GET_IFACE (source);
2576       
2577       if (iface->move)
2578         {
2579           my_error = NULL;
2580           res = (* iface->move) (source, destination,
2581                                  flags, cancellable,
2582                                  progress_callback, progress_callback_data,
2583                                  &my_error);
2584           
2585           if (res)
2586             return TRUE;
2587           
2588           if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2589             {
2590               g_propagate_error (error, my_error);
2591               return FALSE;
2592             }
2593         }
2594     }
2595   
2596   if (flags & G_FILE_COPY_NO_FALLBACK_FOR_MOVE)
2597     {  
2598       g_set_error (error, G_IO_ERROR,
2599                    G_IO_ERROR_NOT_SUPPORTED,
2600                    _("Operation not supported"));
2601       return FALSE;
2602     }
2603   
2604   flags |= G_FILE_COPY_ALL_METADATA;
2605   if (!g_file_copy (source, destination, flags, cancellable,
2606                     progress_callback, progress_callback_data,
2607                     error))
2608     return FALSE;
2609
2610   return g_file_delete (source, cancellable, error);
2611 }
2612
2613 /**
2614  * g_file_make_directory
2615  * @file: input #GFile.
2616  * @cancellable: optional #GCancellable object, %NULL to ignore.
2617  * @error: a #GError, or %NULL 
2618  *
2619  * Creates a directory.
2620  * 
2621  * If @cancellable is not %NULL, then the operation can be cancelled by
2622  * triggering the cancellable object from another thread. If the operation
2623  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2624  * 
2625  * Returns: %TRUE on successful creation, %FALSE otherwise.
2626  **/
2627 gboolean
2628 g_file_make_directory (GFile         *file,
2629                        GCancellable  *cancellable,
2630                        GError       **error)
2631 {
2632   GFileIface *iface;
2633
2634   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2635
2636   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2637     return FALSE;
2638   
2639   iface = G_FILE_GET_IFACE (file);
2640
2641   if (iface->make_directory == NULL)
2642     {
2643       g_set_error (error, G_IO_ERROR,
2644                    G_IO_ERROR_NOT_SUPPORTED,
2645                    _("Operation not supported"));
2646       return FALSE;
2647     }
2648   
2649   return (* iface->make_directory) (file, cancellable, error);
2650 }
2651
2652 /**
2653  * g_file_make_symbolic_link:
2654  * @file: input #GFile.
2655  * @symlink_value: a string with the value of the new symlink.
2656  * @cancellable: optional #GCancellable object, %NULL to ignore.
2657  * @error: a #GError. 
2658  * 
2659  * Creates a symbolic link.
2660  *
2661  * If @cancellable is not %NULL, then the operation can be cancelled by
2662  * triggering the cancellable object from another thread. If the operation
2663  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2664  * 
2665  * Returns: %TRUE on the creation of a new symlink, %FALSE otherwise.
2666  **/
2667 gboolean
2668 g_file_make_symbolic_link (GFile         *file,
2669                            const char    *symlink_value,
2670                            GCancellable  *cancellable,
2671                            GError       **error)
2672 {
2673   GFileIface *iface;
2674
2675   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2676   g_return_val_if_fail (symlink_value != NULL, FALSE);
2677
2678   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2679     return FALSE;
2680
2681   if (*symlink_value == '\0')
2682     {
2683       g_set_error (error, G_IO_ERROR,
2684                    G_IO_ERROR_INVALID_ARGUMENT,
2685                    _("Invalid symlink value given"));
2686       return FALSE;
2687     }
2688   
2689   iface = G_FILE_GET_IFACE (file);
2690
2691   if (iface->make_symbolic_link == NULL)
2692     {
2693       g_set_error (error, G_IO_ERROR,
2694                    G_IO_ERROR_NOT_SUPPORTED,
2695                    _("Operation not supported"));
2696       return FALSE;
2697     }
2698   
2699   return (* iface->make_symbolic_link) (file, symlink_value, cancellable, error);
2700 }
2701
2702 /**
2703  * g_file_delete:
2704  * @file: input #GFile.
2705  * @cancellable: optional #GCancellable object, %NULL to ignore.
2706  * @error: a #GError, or %NULL 
2707  * 
2708  * Deletes a file.
2709  * 
2710  * If @cancellable is not %NULL, then the operation can be cancelled by
2711  * triggering the cancellable object from another thread. If the operation
2712  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2713  * 
2714  * Returns: %TRUE if the file was deleted. %FALSE otherwise.
2715  **/
2716 gboolean
2717 g_file_delete (GFile         *file,
2718                GCancellable  *cancellable,
2719                GError       **error)
2720 {
2721   GFileIface *iface;
2722   
2723   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2724
2725   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2726     return FALSE;
2727   
2728   iface = G_FILE_GET_IFACE (file);
2729
2730   if (iface->delete_file == NULL)
2731     {
2732       g_set_error (error, G_IO_ERROR,
2733                    G_IO_ERROR_NOT_SUPPORTED,
2734                    _("Operation not supported"));
2735       return FALSE;
2736     }
2737   
2738   return (* iface->delete_file) (file, cancellable, error);
2739 }
2740
2741 /**
2742  * g_file_trash:
2743  * @file: #GFile to send to trash.
2744  * @cancellable: optional #GCancellable object, %NULL to ignore.
2745  * @error: a #GError, or %NULL
2746  *
2747  * Sends @file to the "Trashcan", if possible. This is similar to
2748  * deleting it, but the user can recover it before emptying the trashcan.
2749  * Not all file systems support trashing, so this call can return the
2750  * %G_IO_ERROR_NOT_SUPPORTED error.
2751  *
2752  *
2753  * If @cancellable is not %NULL, then the operation can be cancelled by
2754  * triggering the cancellable object from another thread. If the operation
2755  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2756  * 
2757  * Returns: %TRUE on successful trash, %FALSE otherwise.
2758  **/
2759 gboolean
2760 g_file_trash (GFile         *file,
2761               GCancellable  *cancellable,
2762               GError       **error)
2763 {
2764   GFileIface *iface;
2765   
2766   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2767
2768   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2769     return FALSE;
2770   
2771   iface = G_FILE_GET_IFACE (file);
2772
2773   if (iface->trash == NULL)
2774     {
2775       g_set_error (error,
2776                    G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
2777                    _("Trash not supported"));
2778       return FALSE;
2779     }
2780   
2781   return (* iface->trash) (file, cancellable, error);
2782 }
2783
2784 /**
2785  * g_file_set_display_name:
2786  * @file: input #GFile.
2787  * @display_name: a string.
2788  * @cancellable: optional #GCancellable object, %NULL to ignore.
2789  * @error: a #GError, or %NULL
2790  * 
2791  * Renames @file to the specified display name.
2792  *
2793  * The display name is converted from UTF8 to the correct encoding for the target
2794  * filesystem if possible and the @file is renamed to this.
2795  * 
2796  * If you want to implement a rename operation in the user interface the edit name
2797  * (#G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME) should be used as the initial value in the rename
2798  * widget, and then the result after editing should be passed to g_file_set_display_name().
2799  *
2800  * On success the resulting converted filename is returned.
2801  * 
2802  * If @cancellable is not %NULL, then the operation can be cancelled by
2803  * triggering the cancellable object from another thread. If the operation
2804  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2805  * 
2806  * Returns: a #GFile specifying what @file was renamed to, or %NULL if there was an error.
2807  **/
2808 GFile *
2809 g_file_set_display_name (GFile         *file,
2810                          const char    *display_name,
2811                          GCancellable  *cancellable,
2812                          GError       **error)
2813 {
2814   GFileIface *iface;
2815   
2816   g_return_val_if_fail (G_IS_FILE (file), NULL);
2817   g_return_val_if_fail (display_name != NULL, NULL);
2818
2819   if (strchr (display_name, G_DIR_SEPARATOR) != NULL)
2820     {
2821       g_set_error (error,
2822                    G_IO_ERROR,
2823                    G_IO_ERROR_INVALID_ARGUMENT,
2824                    _("File names cannot contain '%c'"), G_DIR_SEPARATOR);
2825       return NULL;
2826     }
2827   
2828   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2829     return NULL;
2830   
2831   iface = G_FILE_GET_IFACE (file);
2832
2833   return (* iface->set_display_name) (file, display_name, cancellable, error);
2834 }
2835
2836 /**
2837  * g_file_set_display_name_async:
2838  * @file: input #GFile.
2839  * @display_name: a string.
2840  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
2841  *     of the request. 
2842  * @cancellable: optional #GCancellable object, %NULL to ignore.
2843  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
2844  * @user_data: the data to pass to callback function
2845  * 
2846  * Asynchronously sets the display name for a given #GFile.
2847  * 
2848  * For more details, see g_set_display_name() which is
2849  * the synchronous version of this call.
2850  *
2851  * When the operation is finished, @callback will be called. You can then call
2852  * g_file_set_display_name_finish() to get the result of the operation.
2853  **/
2854 void
2855 g_file_set_display_name_async (GFile               *file,
2856                                const char          *display_name,
2857                                int                  io_priority,
2858                                GCancellable        *cancellable,
2859                                GAsyncReadyCallback  callback,
2860                                gpointer             user_data)
2861 {
2862   GFileIface *iface;
2863   
2864   g_return_if_fail (G_IS_FILE (file));
2865   g_return_if_fail (display_name != NULL);
2866
2867   iface = G_FILE_GET_IFACE (file);
2868   (* iface->set_display_name_async) (file,
2869                                      display_name,
2870                                      io_priority,
2871                                      cancellable,
2872                                      callback,
2873                                      user_data);
2874 }
2875
2876 /**
2877  * g_file_set_display_name_finish:
2878  * @file: input #GFile.
2879  * @res: a #GAsyncResult. 
2880  * @error: a #GError, or %NULL
2881  * 
2882  * Finishes setting a display name started with 
2883  * g_file_set_display_name_async().
2884  * 
2885  * Returns: a #GFile or %NULL on error.
2886  **/
2887 GFile *
2888 g_file_set_display_name_finish (GFile         *file,
2889                                 GAsyncResult  *res,
2890                                 GError       **error)
2891 {
2892   GFileIface *iface;
2893   
2894   g_return_val_if_fail (G_IS_FILE (file), NULL);
2895   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2896
2897   if (G_IS_SIMPLE_ASYNC_RESULT (res))
2898     {
2899       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
2900       if (g_simple_async_result_propagate_error (simple, error))
2901         return NULL;
2902     }
2903   
2904   iface = G_FILE_GET_IFACE (file);
2905   return (* iface->set_display_name_finish) (file, res, error);
2906 }
2907
2908 /**
2909  * g_file_query_settable_attributes:
2910  * @file: input #GFile.
2911  * @cancellable: optional #GCancellable object, %NULL to ignore.
2912  * @error: a #GError, or %NULL
2913  * 
2914  * Obtain the list of settable attributes for the file.
2915  *
2916  * Returns the type and full attribute name of all the attributes 
2917  * that can be set on this file. This doesn't mean setting it will always 
2918  * succeed though, you might get an access failure, or some specific 
2919  * file may not support a specific attribute.
2920  *
2921  * If @cancellable is not %NULL, then the operation can be cancelled by
2922  * triggering the cancellable object from another thread. If the operation
2923  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2924  * 
2925  * Returns: a #GFileAttributeInfoList describing the settable attributes.
2926  * When you are done with it, release it with g_file_attribute_info_list_unref()
2927  **/
2928 GFileAttributeInfoList *
2929 g_file_query_settable_attributes (GFile         *file,
2930                                   GCancellable  *cancellable,
2931                                   GError       **error)
2932 {
2933   GFileIface *iface;
2934   GError *my_error;
2935   GFileAttributeInfoList *list;
2936
2937   g_return_val_if_fail (G_IS_FILE (file), NULL);
2938
2939   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2940     return NULL;
2941   
2942   iface = G_FILE_GET_IFACE (file);
2943
2944   if (iface->query_settable_attributes == NULL)
2945     return g_file_attribute_info_list_new ();
2946
2947   my_error = NULL;
2948   list = (* iface->query_settable_attributes) (file, cancellable, &my_error);
2949   
2950   if (list == NULL)
2951     {
2952       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
2953         {
2954           list = g_file_attribute_info_list_new ();
2955           g_error_free (my_error);
2956         }
2957       else
2958         g_propagate_error (error, my_error);
2959     }
2960   
2961   return list;
2962 }
2963
2964 /**
2965  * g_file_query_writable_namespaces:
2966  * @file: input #GFile.
2967  * @cancellable: optional #GCancellable object, %NULL to ignore.
2968  * @error: a #GError, or %NULL
2969  * 
2970  * Obtain the list of attribute namespaces where new attributes 
2971  * can be created by a user. An example of this is extended
2972  * attributes (in the "xattr" namespace).
2973  *
2974  * If @cancellable is not %NULL, then the operation can be cancelled by
2975  * triggering the cancellable object from another thread. If the operation
2976  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2977  * 
2978  * Returns: a #GFileAttributeInfoList describing the writable namespaces.
2979  * When you are done with it, release it with g_file_attribute_info_list_unref()
2980  **/
2981 GFileAttributeInfoList *
2982 g_file_query_writable_namespaces (GFile         *file,
2983                                   GCancellable  *cancellable,
2984                                   GError       **error)
2985 {
2986   GFileIface *iface;
2987   GError *my_error;
2988   GFileAttributeInfoList *list;
2989   
2990   g_return_val_if_fail (G_IS_FILE (file), NULL);
2991
2992   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2993     return NULL;
2994   
2995   iface = G_FILE_GET_IFACE (file);
2996
2997   if (iface->query_writable_namespaces == NULL)
2998     return g_file_attribute_info_list_new ();
2999
3000   my_error = NULL;
3001   list = (* iface->query_writable_namespaces) (file, cancellable, &my_error);
3002   
3003   if (list == NULL)
3004     {
3005       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
3006         {
3007           list = g_file_attribute_info_list_new ();
3008           g_error_free (my_error);
3009         }
3010       else
3011         g_propagate_error (error, my_error);
3012     }
3013   
3014   return list;
3015 }
3016
3017 /**
3018  * g_file_set_attribute:
3019  * @file: input #GFile.
3020  * @attribute: a string containing the attribute's name.
3021  * @type: The type of the attribute
3022  * @value_p: a pointer to the value (or the pointer itself if the type is a pointer type)
3023  * @flags: a set of #GFileQueryInfoFlags.
3024  * @cancellable: optional #GCancellable object, %NULL to ignore.
3025  * @error: a #GError, or %NULL
3026  * 
3027  * Sets an attribute in the file with attribute name @attribute to @value.
3028  * 
3029  * If @cancellable is not %NULL, then the operation can be cancelled by
3030  * triggering the cancellable object from another thread. If the operation
3031  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3032  * 
3033  * Returns: %TRUE if the attribute was set, %FALSE otherwise.
3034  **/
3035 gboolean
3036 g_file_set_attribute (GFile                      *file,
3037                       const char                 *attribute,
3038                       GFileAttributeType          type,
3039                       gpointer                    value_p,
3040                       GFileQueryInfoFlags         flags,
3041                       GCancellable               *cancellable,
3042                       GError                    **error)
3043 {
3044   GFileIface *iface;
3045   
3046   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3047   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
3048
3049   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3050     return FALSE;
3051   
3052   iface = G_FILE_GET_IFACE (file);
3053
3054   if (iface->set_attribute == NULL)
3055     {
3056       g_set_error (error, G_IO_ERROR,
3057                    G_IO_ERROR_NOT_SUPPORTED,
3058                    _("Operation not supported"));
3059       return FALSE;
3060     }
3061
3062   return (* iface->set_attribute) (file, attribute, type, value_p, flags, cancellable, error);
3063 }
3064
3065 /**
3066  * g_file_set_attributes_from_info:
3067  * @file: input #GFile.
3068  * @info: a #GFileInfo.
3069  * @flags: #GFileQueryInfoFlags
3070  * @cancellable: optional #GCancellable object, %NULL to ignore.
3071  * @error: a #GError, or %NULL 
3072  * 
3073  * Tries to set all attributes in the #GFileInfo on the target values, 
3074  * not stopping on the first error.
3075  * 
3076  * If there is any error during this operation then @error will be set to
3077  * the first error. Error on particular fields are flagged by setting 
3078  * the "status" field in the attribute value to 
3079  * %G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING, which means you can also detect
3080  * further errors.
3081  *
3082  * If @cancellable is not %NULL, then the operation can be cancelled by
3083  * triggering the cancellable object from another thread. If the operation
3084  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3085  * 
3086  * Returns: %TRUE if there was any error, %FALSE otherwise.
3087  **/
3088 gboolean
3089 g_file_set_attributes_from_info (GFile                *file,
3090                                  GFileInfo            *info,
3091                                  GFileQueryInfoFlags   flags,
3092                                  GCancellable         *cancellable,
3093                                  GError              **error)
3094 {
3095   GFileIface *iface;
3096
3097   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3098   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
3099
3100   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3101     return FALSE;
3102   
3103   g_file_info_clear_status (info);
3104   
3105   iface = G_FILE_GET_IFACE (file);
3106
3107   return (* iface->set_attributes_from_info) (file, 
3108                                               info, 
3109                                               flags, 
3110                                               cancellable, 
3111                                               error);
3112 }
3113
3114
3115 static gboolean
3116 g_file_real_set_attributes_from_info (GFile                *file,
3117                                       GFileInfo            *info,
3118                                       GFileQueryInfoFlags   flags,
3119                                       GCancellable         *cancellable,
3120                                       GError              **error)
3121 {
3122   char **attributes;
3123   int i;
3124   gboolean res;
3125   GFileAttributeValue *value;
3126   
3127   res = TRUE;
3128   
3129   attributes = g_file_info_list_attributes (info, NULL);
3130
3131   for (i = 0; attributes[i] != NULL; i++)
3132     {
3133       value = _g_file_info_get_attribute_value (info, attributes[i]);
3134
3135       if (value->status != G_FILE_ATTRIBUTE_STATUS_UNSET)
3136         continue;
3137
3138       if (!g_file_set_attribute (file, attributes[i],
3139                                  value->type, _g_file_attribute_value_peek_as_pointer (value),
3140                                  flags, cancellable, error))
3141         {
3142           value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING;
3143           res = FALSE;
3144           /* Don't set error multiple times */
3145           error = NULL;
3146         }
3147       else
3148         value->status = G_FILE_ATTRIBUTE_STATUS_SET;
3149     }
3150   
3151   g_strfreev (attributes);
3152   
3153   return res;
3154 }
3155
3156 /**
3157  * g_file_set_attributes_async:
3158  * @file: input #GFile.
3159  * @info: a #GFileInfo.
3160  * @flags: a #GFileQueryInfoFlags.
3161  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
3162  *     of the request. 
3163  * @cancellable: optional #GCancellable object, %NULL to ignore.
3164  * @callback: a #GAsyncReadyCallback. 
3165  * @user_data: a #gpointer.
3166  *
3167  * Asynchronously sets the attributes of @file with @info.
3168  * 
3169  * For more details, see g_file_set_attributes_from_info() which is
3170  * the synchronous version of this call.
3171  *
3172  * When the operation is finished, @callback will be called. You can then call
3173  * g_file_set_attributes_finish() to get the result of the operation.
3174  **/
3175 void
3176 g_file_set_attributes_async (GFile               *file,
3177                              GFileInfo           *info,
3178                              GFileQueryInfoFlags  flags,
3179                              int                  io_priority,
3180                              GCancellable        *cancellable,
3181                              GAsyncReadyCallback  callback,
3182                              gpointer             user_data)
3183 {
3184   GFileIface *iface;
3185   
3186   g_return_if_fail (G_IS_FILE (file));
3187   g_return_if_fail (G_IS_FILE_INFO (info));
3188
3189   iface = G_FILE_GET_IFACE (file);
3190   (* iface->set_attributes_async) (file, 
3191                                    info, 
3192                                    flags, 
3193                                    io_priority, 
3194                                    cancellable, 
3195                                    callback, 
3196                                    user_data);
3197 }
3198
3199 /**
3200  * g_file_set_attributes_finish:
3201  * @file: input #GFile.
3202  * @result: a #GAsyncResult.
3203  * @info: a #GFileInfo.
3204  * @error: a #GError, or %NULL
3205  * 
3206  * Finishes setting an attribute started in g_file_set_attributes_async().
3207  * 
3208  * Returns: %TRUE if the attributes were set correctly, %FALSE otherwise.
3209  **/
3210 gboolean
3211 g_file_set_attributes_finish (GFile         *file,
3212                               GAsyncResult  *result,
3213                               GFileInfo    **info,
3214                               GError       **error)
3215 {
3216   GFileIface *iface;
3217   
3218   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3219   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3220
3221   /* No standard handling of errors here, as we must set info even
3222    * on errors 
3223    */
3224   iface = G_FILE_GET_IFACE (file);
3225   return (* iface->set_attributes_finish) (file, result, info, error);
3226 }
3227
3228 /**
3229  * g_file_set_attribute_string:
3230  * @file: input #GFile.
3231  * @attribute: a string containing the attribute's name.
3232  * @value: a string containing the attribute's value.
3233  * @flags: #GFileQueryInfoFlags.
3234  * @cancellable: optional #GCancellable object, %NULL to ignore.
3235  * @error: a #GError, or %NULL
3236  * 
3237  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_STRING to @value. 
3238  * If @attribute is of a different type, this operation will fail.
3239  * 
3240  * If @cancellable is not %NULL, then the operation can be cancelled by
3241  * triggering the cancellable object from another thread. If the operation
3242  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3243  * 
3244  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
3245  **/
3246 gboolean
3247 g_file_set_attribute_string (GFile                *file,
3248                              const char           *attribute,
3249                              const char           *value,
3250                              GFileQueryInfoFlags   flags,
3251                              GCancellable         *cancellable,
3252                              GError              **error)
3253 {
3254   return g_file_set_attribute (file, attribute,
3255                                G_FILE_ATTRIBUTE_TYPE_STRING, (gpointer)value,
3256                                flags, cancellable, error);
3257 }
3258
3259 /**
3260  * g_file_set_attribute_byte_string:
3261  * @file: input #GFile.
3262  * @attribute: a string containing the attribute's name.
3263  * @value: a string containing the attribute's new value.
3264  * @flags: a #GFileQueryInfoFlags.
3265  * @cancellable: optional #GCancellable object, %NULL to ignore.
3266  * @error: a #GError, or %NULL
3267  * 
3268  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING to @value. 
3269  * If @attribute is of a different type, this operation will fail, 
3270  * returning %FALSE. 
3271  * 
3272  * If @cancellable is not %NULL, then the operation can be cancelled by
3273  * triggering the cancellable object from another thread. If the operation
3274  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3275  * 
3276  * Returns: %TRUE if the @attribute was successfully set to @value 
3277  * in the @file, %FALSE otherwise.
3278  **/
3279 gboolean
3280 g_file_set_attribute_byte_string  (GFile                *file,
3281                                    const char           *attribute,
3282                                    const char           *value,
3283                                    GFileQueryInfoFlags   flags,
3284                                    GCancellable         *cancellable,
3285                                    GError              **error)
3286 {
3287   return g_file_set_attribute (file, attribute,
3288                                G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, (gpointer)value,
3289                                flags, cancellable, error);
3290 }
3291
3292 /**
3293  * g_file_set_attribute_uint32:
3294  * @file: input #GFile.
3295  * @attribute: a string containing the attribute's name.
3296  * @value: a #guint32 containing the attribute's new value.
3297  * @flags: a #GFileQueryInfoFlags.
3298  * @cancellable: optional #GCancellable object, %NULL to ignore.
3299  * @error: a #GError, or %NULL
3300  * 
3301  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT32 to @value. 
3302  * If @attribute is of a different type, this operation will fail.
3303  * 
3304  * If @cancellable is not %NULL, then the operation can be cancelled by
3305  * triggering the cancellable object from another thread. If the operation
3306  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3307  * 
3308  * Returns: %TRUE if the @attribute was successfully set to @value 
3309  * in the @file, %FALSE otherwise.
3310  **/
3311 gboolean
3312 g_file_set_attribute_uint32 (GFile                *file,
3313                              const char           *attribute,
3314                              guint32               value,
3315                              GFileQueryInfoFlags   flags,
3316                              GCancellable         *cancellable,
3317                              GError              **error)
3318 {
3319   return g_file_set_attribute (file, attribute,
3320                                G_FILE_ATTRIBUTE_TYPE_UINT32, &value,
3321                                flags, cancellable, error);
3322 }
3323
3324 /**
3325  * g_file_set_attribute_int32:
3326  * @file: input #GFile.
3327  * @attribute: a string containing the attribute's name.
3328  * @value: a #gint32 containing the attribute's new value.
3329  * @flags: a #GFileQueryInfoFlags.
3330  * @cancellable: optional #GCancellable object, %NULL to ignore.
3331  * @error: a #GError, or %NULL
3332  * 
3333  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT32 to @value. 
3334  * If @attribute is of a different type, this operation will fail.
3335  * 
3336  * If @cancellable is not %NULL, then the operation can be cancelled by
3337  * triggering the cancellable object from another thread. If the operation
3338  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3339  * 
3340  * Returns: %TRUE if the @attribute was successfully set to @value 
3341  * in the @file, %FALSE otherwise. 
3342  **/
3343 gboolean
3344 g_file_set_attribute_int32 (GFile                *file,
3345                             const char           *attribute,
3346                             gint32                value,
3347                             GFileQueryInfoFlags   flags,
3348                             GCancellable         *cancellable,
3349                             GError              **error)
3350 {
3351   return g_file_set_attribute (file, attribute,
3352                                G_FILE_ATTRIBUTE_TYPE_INT32, &value,
3353                                flags, cancellable, error);
3354 }
3355
3356 /**
3357  * g_file_set_attribute_uint64:
3358  * @file: input #GFile. 
3359  * @attribute: a string containing the attribute's name.
3360  * @value: a #guint64 containing the attribute's new value.
3361  * @flags: a #GFileQueryInfoFlags.
3362  * @cancellable: optional #GCancellable object, %NULL to ignore.
3363  * @error: a #GError, or %NULL
3364  * 
3365  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT64 to @value. 
3366  * If @attribute is of a different type, this operation will fail.
3367  * 
3368  * If @cancellable is not %NULL, then the operation can be cancelled by
3369  * triggering the cancellable object from another thread. If the operation
3370  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3371  * 
3372  * Returns: %TRUE if the @attribute was successfully set to @value 
3373  * in the @file, %FALSE otherwise.
3374  **/
3375 gboolean
3376 g_file_set_attribute_uint64 (GFile                *file,
3377                              const char           *attribute,
3378                              guint64               value,
3379                              GFileQueryInfoFlags   flags,
3380                              GCancellable         *cancellable,
3381                              GError              **error)
3382  {
3383   return g_file_set_attribute (file, attribute,
3384                                G_FILE_ATTRIBUTE_TYPE_UINT64, &value,
3385                                flags, cancellable, error);
3386 }
3387
3388 /**
3389  * g_file_set_attribute_int64:
3390  * @file: input #GFile.
3391  * @attribute: a string containing the attribute's name.
3392  * @value: a #guint64 containing the attribute's new value.
3393  * @flags: a #GFileQueryInfoFlags.
3394  * @cancellable: optional #GCancellable object, %NULL to ignore.
3395  * @error: a #GError, or %NULL
3396  * 
3397  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT64 to @value. 
3398  * If @attribute is of a different type, this operation will fail.
3399  * 
3400  * If @cancellable is not %NULL, then the operation can be cancelled by
3401  * triggering the cancellable object from another thread. If the operation
3402  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3403  * 
3404  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
3405  **/
3406 gboolean
3407 g_file_set_attribute_int64 (GFile                *file,
3408                             const char           *attribute,
3409                             gint64                value,
3410                             GFileQueryInfoFlags   flags,
3411                             GCancellable         *cancellable,
3412                             GError              **error)
3413 {
3414   return g_file_set_attribute (file, attribute,
3415                                G_FILE_ATTRIBUTE_TYPE_INT64, &value,
3416                                flags, cancellable, error);
3417 }
3418
3419 /**
3420  * g_file_mount_mountable:
3421  * @file: input #GFile.
3422  * @flags: flags affecting the operation
3423  * @mount_operation: a #GMountOperation, or %NULL to avoid user interaction.
3424  * @cancellable: optional #GCancellable object, %NULL to ignore.
3425  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
3426  * @user_data: the data to pass to callback function
3427  * 
3428  * Mounts a file of type G_FILE_TYPE_MOUNTABLE.
3429  * Using @mount_operation, you can request callbacks when, for instance, 
3430  * passwords are needed during authentication.
3431  *
3432  * If @cancellable is not %NULL, then the operation can be cancelled by
3433  * triggering the cancellable object from another thread. If the operation
3434  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3435  *
3436  * When the operation is finished, @callback will be called. You can then call
3437  * g_file_mount_mountable_finish() to get the result of the operation.
3438  **/
3439 void
3440 g_file_mount_mountable (GFile               *file,
3441                         GMountMountFlags     flags,
3442                         GMountOperation     *mount_operation,
3443                         GCancellable        *cancellable,
3444                         GAsyncReadyCallback  callback,
3445                         gpointer             user_data)
3446 {
3447   GFileIface *iface;
3448
3449   g_return_if_fail (G_IS_FILE (file));
3450
3451   iface = G_FILE_GET_IFACE (file);
3452
3453   if (iface->mount_mountable == NULL) 
3454     {
3455       g_simple_async_report_error_in_idle (G_OBJECT (file),
3456                                            callback,
3457                                            user_data,
3458                                            G_IO_ERROR,
3459                                            G_IO_ERROR_NOT_SUPPORTED,
3460                                            _("Operation not supported"));
3461       return;
3462     }
3463   
3464   (* iface->mount_mountable) (file,
3465                               flags,
3466                               mount_operation,
3467                               cancellable,
3468                               callback,
3469                               user_data);
3470 }
3471
3472 /**
3473  * g_file_mount_mountable_finish:
3474  * @file: input #GFile.
3475  * @result: a #GAsyncResult.
3476  * @error: a #GError, or %NULL
3477  *
3478  * Finishes a mount operation. See g_file_mount_mountable() for details.
3479  * 
3480  * Finish an asynchronous mount operation that was started 
3481  * with g_file_mount_mountable().
3482  *
3483  * Returns: a #GFile or %NULL on error.
3484  **/
3485 GFile *
3486 g_file_mount_mountable_finish (GFile         *file,
3487                                GAsyncResult  *result,
3488                                GError       **error)
3489 {
3490   GFileIface *iface;
3491
3492   g_return_val_if_fail (G_IS_FILE (file), NULL);
3493   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
3494
3495   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3496     {
3497       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3498       if (g_simple_async_result_propagate_error (simple, error))
3499         return NULL;
3500     }
3501   
3502   iface = G_FILE_GET_IFACE (file);
3503   return (* iface->mount_mountable_finish) (file, result, error);
3504 }
3505
3506 /**
3507  * g_file_unmount_mountable:
3508  * @file: input #GFile.
3509  * @flags: flags affecting the operation
3510  * @cancellable: optional #GCancellable object, %NULL to ignore.
3511  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
3512  * @user_data: the data to pass to callback function
3513  *
3514  * Unmounts a file of type G_FILE_TYPE_MOUNTABLE.
3515  *
3516  * If @cancellable is not %NULL, then the operation can be cancelled by
3517  * triggering the cancellable object from another thread. If the operation
3518  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3519  *
3520  * When the operation is finished, @callback will be called. You can then call
3521  * g_file_unmount_mountable_finish() to get the result of the operation.
3522  **/
3523 void
3524 g_file_unmount_mountable (GFile               *file,
3525                           GMountUnmountFlags   flags,
3526                           GCancellable        *cancellable,
3527                           GAsyncReadyCallback  callback,
3528                           gpointer             user_data)
3529 {
3530   GFileIface *iface;
3531   
3532   g_return_if_fail (G_IS_FILE (file));
3533
3534   iface = G_FILE_GET_IFACE (file);
3535   
3536   if (iface->unmount_mountable == NULL)
3537     {
3538       g_simple_async_report_error_in_idle (G_OBJECT (file),
3539                                            callback,
3540                                            user_data,
3541                                            G_IO_ERROR,
3542                                            G_IO_ERROR_NOT_SUPPORTED,
3543                                            _("Operation not supported"));
3544       return;
3545     }
3546   
3547   (* iface->unmount_mountable) (file,
3548                                 flags,
3549                                 cancellable,
3550                                 callback,
3551                                 user_data);
3552 }
3553
3554 /**
3555  * g_file_unmount_mountable_finish:
3556  * @file: input #GFile.
3557  * @result: a #GAsyncResult.
3558  * @error: a #GError, or %NULL
3559  *
3560  * Finishes an unmount operation, see g_file_unmount_mountable() for details.
3561  * 
3562  * Finish an asynchronous unmount operation that was started 
3563  * with g_file_unmount_mountable().
3564  *
3565  * Returns: %TRUE if the operation finished successfully. %FALSE
3566  * otherwise.
3567  **/
3568 gboolean
3569 g_file_unmount_mountable_finish (GFile         *file,
3570                                  GAsyncResult  *result,
3571                                  GError       **error)
3572 {
3573   GFileIface *iface;
3574   
3575   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3576   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3577
3578   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3579     {
3580       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3581       if (g_simple_async_result_propagate_error (simple, error))
3582         return FALSE;
3583     }
3584   
3585   iface = G_FILE_GET_IFACE (file);
3586   return (* iface->unmount_mountable_finish) (file, result, error);
3587 }
3588
3589 /**
3590  * g_file_eject_mountable:
3591  * @file: input #GFile.
3592  * @flags: flags affecting the operation
3593  * @cancellable: optional #GCancellable object, %NULL to ignore.
3594  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
3595  * @user_data: the data to pass to callback function
3596  * 
3597  * Starts an asynchronous eject on a mountable.  
3598  * When this operation has completed, @callback will be called with
3599  * @user_user data, and the operation can be finalized with 
3600  * g_file_eject_mountable_finish().
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 void
3607 g_file_eject_mountable (GFile               *file,
3608                         GMountUnmountFlags   flags,
3609                         GCancellable        *cancellable,
3610                         GAsyncReadyCallback  callback,
3611                         gpointer             user_data)
3612 {
3613   GFileIface *iface;
3614
3615   g_return_if_fail (G_IS_FILE (file));
3616
3617   iface = G_FILE_GET_IFACE (file);
3618   
3619   if (iface->eject_mountable == NULL) 
3620     {
3621       g_simple_async_report_error_in_idle (G_OBJECT (file),
3622                                            callback,
3623                                            user_data,
3624                                            G_IO_ERROR,
3625                                            G_IO_ERROR_NOT_SUPPORTED,
3626                                            _("Operation not supported"));
3627       return;
3628     }
3629   
3630   (* iface->eject_mountable) (file,
3631                               flags,
3632                               cancellable,
3633                               callback,
3634                               user_data);
3635 }
3636
3637 /**
3638  * g_file_eject_mountable_finish:
3639  * @file: input #GFile.
3640  * @result: a #GAsyncResult.
3641  * @error: a #GError, or %NULL
3642  * 
3643  * Finishes an asynchronous eject operation started by 
3644  * g_file_eject_mountable().
3645  * 
3646  * Returns: %TRUE if the @file was ejected successfully. %FALSE 
3647  * otherwise.
3648  **/
3649 gboolean
3650 g_file_eject_mountable_finish (GFile         *file,
3651                                GAsyncResult  *result,
3652                                GError       **error)
3653 {
3654   GFileIface *iface;
3655   
3656   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3657   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3658
3659   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3660     {
3661       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3662       if (g_simple_async_result_propagate_error (simple, error))
3663         return FALSE;
3664     }
3665   
3666   iface = G_FILE_GET_IFACE (file);
3667   return (* iface->eject_mountable_finish) (file, result, error);
3668 }
3669
3670 /**
3671  * g_file_monitor_directory:
3672  * @file: input #GFile.
3673  * @flags: a set of #GFileMonitorFlags.
3674  * @cancellable: optional #GCancellable object, %NULL to ignore.
3675  * @error: a #GError, or %NULL.
3676  * 
3677  * Obtains a directory monitor for the given file.
3678  * This may fail if directory monitoring is not supported.
3679  *
3680  * If @cancellable is not %NULL, then the operation can be cancelled by
3681  * triggering the cancellable object from another thread. If the operation
3682  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3683  * 
3684  * Returns: a #GFileMonitor for the given @file, 
3685  * or %NULL on error.
3686  **/
3687 GFileMonitor*
3688 g_file_monitor_directory (GFile             *file,
3689                           GFileMonitorFlags  flags,
3690                           GCancellable      *cancellable,
3691                           GError           **error)
3692 {
3693   GFileIface *iface;
3694
3695   g_return_val_if_fail (G_IS_FILE (file), NULL);
3696
3697   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3698     return NULL;
3699
3700   iface = G_FILE_GET_IFACE (file);
3701
3702   if (iface->monitor_dir == NULL)
3703     {
3704       g_set_error (error, G_IO_ERROR,
3705                    G_IO_ERROR_NOT_SUPPORTED,
3706                    _("Operation not supported"));
3707       return NULL;
3708     }
3709
3710   return (* iface->monitor_dir) (file, flags, cancellable, error);
3711 }
3712
3713 /**
3714  * g_file_monitor_file:
3715  * @file: input #GFile.
3716  * @flags: a set of #GFileMonitorFlags.
3717  * @cancellable: optional #GCancellable object, %NULL to ignore.
3718  * @error: a #GError, or %NULL.
3719  * 
3720  * Obtains a file monitor for the given file. If no file notification
3721  * mechanism exists, then regular polling of the file is used.
3722  *
3723  * If @cancellable is not %NULL, then the operation can be cancelled by
3724  * triggering the cancellable object from another thread. If the operation
3725  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3726  * 
3727  * Returns: a #GFileMonitor for the given @file.
3728  **/
3729 GFileMonitor*
3730 g_file_monitor_file (GFile             *file,
3731                      GFileMonitorFlags  flags,
3732                      GCancellable      *cancellable,
3733                      GError           **error)
3734 {
3735   GFileIface *iface;
3736   GFileMonitor *monitor;
3737   
3738   g_return_val_if_fail (G_IS_FILE (file), NULL);
3739
3740   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3741     return NULL;
3742
3743   iface = G_FILE_GET_IFACE (file);
3744
3745   monitor = NULL;
3746   
3747   if (iface->monitor_file)
3748     monitor = (* iface->monitor_file) (file, flags, cancellable, NULL);
3749
3750 /* Fallback to polling */
3751   if (monitor == NULL)
3752     monitor = _g_poll_file_monitor_new (file);
3753
3754   return monitor;
3755 }
3756
3757 /********************************************
3758  *   Default implementation of async ops    *
3759  ********************************************/
3760
3761 typedef struct {
3762   char *attributes;
3763   GFileQueryInfoFlags flags;
3764   GFileInfo *info;
3765 } QueryInfoAsyncData;
3766
3767 static void
3768 query_info_data_free (QueryInfoAsyncData *data)
3769 {
3770   if (data->info)
3771     g_object_unref (data->info);
3772   g_free (data->attributes);
3773   g_free (data);
3774 }
3775
3776 static void
3777 query_info_async_thread (GSimpleAsyncResult *res,
3778                          GObject            *object,
3779                          GCancellable       *cancellable)
3780 {
3781   GError *error = NULL;
3782   QueryInfoAsyncData *data;
3783   GFileInfo *info;
3784   
3785   data = g_simple_async_result_get_op_res_gpointer (res);
3786   
3787   info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error);
3788
3789   if (info == NULL)
3790     {
3791       g_simple_async_result_set_from_error (res, error);
3792       g_error_free (error);
3793     }
3794   else
3795     data->info = info;
3796 }
3797
3798 static void
3799 g_file_real_query_info_async (GFile               *file,
3800                               const char          *attributes,
3801                               GFileQueryInfoFlags  flags,
3802                               int                  io_priority,
3803                               GCancellable        *cancellable,
3804                               GAsyncReadyCallback  callback,
3805                               gpointer             user_data)
3806 {
3807   GSimpleAsyncResult *res;
3808   QueryInfoAsyncData *data;
3809
3810   data = g_new0 (QueryInfoAsyncData, 1);
3811   data->attributes = g_strdup (attributes);
3812   data->flags = flags;
3813   
3814   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_info_async);
3815   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_info_data_free);
3816   
3817   g_simple_async_result_run_in_thread (res, query_info_async_thread, io_priority, cancellable);
3818   g_object_unref (res);
3819 }
3820
3821 static GFileInfo *
3822 g_file_real_query_info_finish (GFile         *file,
3823                                GAsyncResult  *res,
3824                                GError       **error)
3825 {
3826   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3827   QueryInfoAsyncData *data;
3828
3829   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_info_async);
3830
3831   data = g_simple_async_result_get_op_res_gpointer (simple);
3832   if (data->info)
3833     return g_object_ref (data->info);
3834   
3835   return NULL;
3836 }
3837
3838 typedef struct {
3839   char *attributes;
3840   GFileInfo *info;
3841 } QueryFilesystemInfoAsyncData;
3842
3843 static void
3844 query_filesystem_info_data_free (QueryFilesystemInfoAsyncData *data)
3845 {
3846   if (data->info)
3847     g_object_unref (data->info);
3848   g_free (data->attributes);
3849   g_free (data);
3850 }
3851
3852 static void
3853 query_filesystem_info_async_thread (GSimpleAsyncResult *res,
3854                                     GObject            *object,
3855                                     GCancellable       *cancellable)
3856 {
3857   GError *error = NULL;
3858   QueryFilesystemInfoAsyncData *data;
3859   GFileInfo *info;
3860   
3861   data = g_simple_async_result_get_op_res_gpointer (res);
3862   
3863   info = g_file_query_filesystem_info (G_FILE (object), data->attributes, cancellable, &error);
3864
3865   if (info == NULL)
3866     {
3867       g_simple_async_result_set_from_error (res, error);
3868       g_error_free (error);
3869     }
3870   else
3871     data->info = info;
3872 }
3873
3874 static void
3875 g_file_real_query_filesystem_info_async (GFile               *file,
3876                                          const char          *attributes,
3877                                          int                  io_priority,
3878                                          GCancellable        *cancellable,
3879                                          GAsyncReadyCallback  callback,
3880                                          gpointer             user_data)
3881 {
3882   GSimpleAsyncResult *res;
3883   QueryFilesystemInfoAsyncData *data;
3884
3885   data = g_new0 (QueryFilesystemInfoAsyncData, 1);
3886   data->attributes = g_strdup (attributes);
3887   
3888   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_filesystem_info_async);
3889   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_filesystem_info_data_free);
3890   
3891   g_simple_async_result_run_in_thread (res, query_filesystem_info_async_thread, io_priority, cancellable);
3892   g_object_unref (res);
3893 }
3894
3895 static GFileInfo *
3896 g_file_real_query_filesystem_info_finish (GFile         *file,
3897                                           GAsyncResult  *res,
3898                                           GError       **error)
3899 {
3900   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3901   QueryFilesystemInfoAsyncData *data;
3902
3903   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_filesystem_info_async);
3904
3905   data = g_simple_async_result_get_op_res_gpointer (simple);
3906   if (data->info)
3907     return g_object_ref (data->info);
3908   
3909   return NULL;
3910 }
3911
3912 typedef struct {
3913   char *attributes;
3914   GFileQueryInfoFlags flags;
3915   GFileEnumerator *enumerator;
3916 } EnumerateChildrenAsyncData;
3917
3918 static void
3919 enumerate_children_data_free (EnumerateChildrenAsyncData *data)
3920 {
3921   if (data->enumerator)
3922     g_object_unref (data->enumerator);
3923   g_free (data->attributes);
3924   g_free (data);
3925 }
3926
3927 static void
3928 enumerate_children_async_thread (GSimpleAsyncResult *res,
3929                                  GObject            *object,
3930                                  GCancellable       *cancellable)
3931 {
3932   GError *error = NULL;
3933   EnumerateChildrenAsyncData *data;
3934   GFileEnumerator *enumerator;
3935   
3936   data = g_simple_async_result_get_op_res_gpointer (res);
3937   
3938   enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error);
3939
3940   if (enumerator == NULL)
3941     {
3942       g_simple_async_result_set_from_error (res, error);
3943       g_error_free (error);
3944     }
3945   else
3946     data->enumerator = enumerator;
3947 }
3948
3949 static void
3950 g_file_real_enumerate_children_async (GFile               *file,
3951                                       const char          *attributes,
3952                                       GFileQueryInfoFlags  flags,
3953                                       int                  io_priority,
3954                                       GCancellable        *cancellable,
3955                                       GAsyncReadyCallback  callback,
3956                                       gpointer             user_data)
3957 {
3958   GSimpleAsyncResult *res;
3959   EnumerateChildrenAsyncData *data;
3960
3961   data = g_new0 (EnumerateChildrenAsyncData, 1);
3962   data->attributes = g_strdup (attributes);
3963   data->flags = flags;
3964   
3965   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_enumerate_children_async);
3966   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)enumerate_children_data_free);
3967   
3968   g_simple_async_result_run_in_thread (res, enumerate_children_async_thread, io_priority, cancellable);
3969   g_object_unref (res);
3970 }
3971
3972 static GFileEnumerator *
3973 g_file_real_enumerate_children_finish (GFile         *file,
3974                                        GAsyncResult  *res,
3975                                        GError       **error)
3976 {
3977   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3978   EnumerateChildrenAsyncData *data;
3979
3980   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_enumerate_children_async);
3981
3982   data = g_simple_async_result_get_op_res_gpointer (simple);
3983   if (data->enumerator)
3984     return g_object_ref (data->enumerator);
3985   
3986   return NULL;
3987 }
3988
3989 static void
3990 open_read_async_thread (GSimpleAsyncResult *res,
3991                         GObject            *object,
3992                         GCancellable       *cancellable)
3993 {
3994   GFileIface *iface;
3995   GFileInputStream *stream;
3996   GError *error = NULL;
3997
3998   iface = G_FILE_GET_IFACE (object);
3999
4000   stream = iface->read_fn (G_FILE (object), cancellable, &error);
4001
4002   if (stream == NULL)
4003     {
4004       g_simple_async_result_set_from_error (res, error);
4005       g_error_free (error);
4006     }
4007   else
4008     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
4009 }
4010
4011 static void
4012 g_file_real_read_async (GFile               *file,
4013                         int                  io_priority,
4014                         GCancellable        *cancellable,
4015                         GAsyncReadyCallback  callback,
4016                         gpointer             user_data)
4017 {
4018   GSimpleAsyncResult *res;
4019   
4020   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_read_async);
4021   
4022   g_simple_async_result_run_in_thread (res, open_read_async_thread, io_priority, cancellable);
4023   g_object_unref (res);
4024 }
4025
4026 static GFileInputStream *
4027 g_file_real_read_finish (GFile         *file,
4028                          GAsyncResult  *res,
4029                          GError       **error)
4030 {
4031   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4032   gpointer op;
4033
4034   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_read_async);
4035
4036   op = g_simple_async_result_get_op_res_gpointer (simple);
4037   if (op)
4038     return g_object_ref (op);
4039   
4040   return NULL;
4041 }
4042
4043 static void
4044 append_to_async_thread (GSimpleAsyncResult *res,
4045                         GObject            *object,
4046                         GCancellable       *cancellable)
4047 {
4048   GFileIface *iface;
4049   GFileCreateFlags *data;
4050   GFileOutputStream *stream;
4051   GError *error = NULL;
4052
4053   iface = G_FILE_GET_IFACE (object);
4054
4055   data = g_simple_async_result_get_op_res_gpointer (res);
4056
4057   stream = iface->append_to (G_FILE (object), *data, cancellable, &error);
4058
4059   if (stream == NULL)
4060     {
4061       g_simple_async_result_set_from_error (res, error);
4062       g_error_free (error);
4063     }
4064   else
4065     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
4066 }
4067
4068 static void
4069 g_file_real_append_to_async (GFile               *file,
4070                              GFileCreateFlags     flags,
4071                              int                  io_priority,
4072                              GCancellable        *cancellable,
4073                              GAsyncReadyCallback  callback,
4074                              gpointer             user_data)
4075 {
4076   GFileCreateFlags *data;
4077   GSimpleAsyncResult *res;
4078
4079   data = g_new0 (GFileCreateFlags, 1);
4080   *data = flags;
4081
4082   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_append_to_async);
4083   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
4084
4085   g_simple_async_result_run_in_thread (res, append_to_async_thread, io_priority, cancellable);
4086   g_object_unref (res);
4087 }
4088
4089 static GFileOutputStream *
4090 g_file_real_append_to_finish (GFile         *file,
4091                               GAsyncResult  *res,
4092                               GError       **error)
4093 {
4094   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4095   gpointer op;
4096
4097   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_append_to_async);
4098
4099   op = g_simple_async_result_get_op_res_gpointer (simple);
4100   if (op)
4101     return g_object_ref (op);
4102   
4103   return NULL;
4104 }
4105
4106 static void
4107 create_async_thread (GSimpleAsyncResult *res,
4108                      GObject            *object,
4109                      GCancellable       *cancellable)
4110 {
4111   GFileIface *iface;
4112   GFileCreateFlags *data;
4113   GFileOutputStream *stream;
4114   GError *error = NULL;
4115
4116   iface = G_FILE_GET_IFACE (object);
4117
4118   data = g_simple_async_result_get_op_res_gpointer (res);
4119
4120   stream = iface->create (G_FILE (object), *data, cancellable, &error);
4121
4122   if (stream == NULL)
4123     {
4124       g_simple_async_result_set_from_error (res, error);
4125       g_error_free (error);
4126     }
4127   else
4128     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
4129 }
4130
4131 static void
4132 g_file_real_create_async (GFile               *file,
4133                           GFileCreateFlags     flags,
4134                           int                  io_priority,
4135                           GCancellable        *cancellable,
4136                           GAsyncReadyCallback  callback,
4137                           gpointer             user_data)
4138 {
4139   GFileCreateFlags *data;
4140   GSimpleAsyncResult *res;
4141
4142   data = g_new0 (GFileCreateFlags, 1);
4143   *data = flags;
4144
4145   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_create_async);
4146   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
4147
4148   g_simple_async_result_run_in_thread (res, create_async_thread, io_priority, cancellable);
4149   g_object_unref (res);
4150 }
4151
4152 static GFileOutputStream *
4153 g_file_real_create_finish (GFile         *file,
4154                            GAsyncResult  *res,
4155                            GError       **error)
4156 {
4157   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4158   gpointer op;
4159
4160   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_create_async);
4161
4162   op = g_simple_async_result_get_op_res_gpointer (simple);
4163   if (op)
4164     return g_object_ref (op);
4165   
4166   return NULL;
4167 }
4168
4169 typedef struct {
4170   GFileOutputStream *stream;
4171   char *etag;
4172   gboolean make_backup;
4173   GFileCreateFlags flags;
4174 } ReplaceAsyncData;
4175
4176 static void
4177 replace_async_data_free (ReplaceAsyncData *data)
4178 {
4179   if (data->stream)
4180     g_object_unref (data->stream);
4181   g_free (data->etag);
4182   g_free (data);
4183 }
4184
4185 static void
4186 replace_async_thread (GSimpleAsyncResult *res,
4187                       GObject            *object,
4188                       GCancellable       *cancellable)
4189 {
4190   GFileIface *iface;
4191   GFileOutputStream *stream;
4192   GError *error = NULL;
4193   ReplaceAsyncData *data;
4194
4195   iface = G_FILE_GET_IFACE (object);
4196   
4197   data = g_simple_async_result_get_op_res_gpointer (res);
4198
4199   stream = iface->replace (G_FILE (object),
4200                            data->etag,
4201                            data->make_backup,
4202                            data->flags,
4203                            cancellable,
4204                            &error);
4205
4206   if (stream == NULL)
4207     {
4208       g_simple_async_result_set_from_error (res, error);
4209       g_error_free (error);
4210     }
4211   else
4212     data->stream = stream;
4213 }
4214
4215 static void
4216 g_file_real_replace_async (GFile               *file,
4217                            const char          *etag,
4218                            gboolean             make_backup,
4219                            GFileCreateFlags     flags,
4220                            int                  io_priority,
4221                            GCancellable        *cancellable,
4222                            GAsyncReadyCallback  callback,
4223                            gpointer             user_data)
4224 {
4225   GSimpleAsyncResult *res;
4226   ReplaceAsyncData *data;
4227
4228   data = g_new0 (ReplaceAsyncData, 1);
4229   data->etag = g_strdup (etag);
4230   data->make_backup = make_backup;
4231   data->flags = flags;
4232
4233   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_replace_async);
4234   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_async_data_free);
4235
4236   g_simple_async_result_run_in_thread (res, replace_async_thread, io_priority, cancellable);
4237   g_object_unref (res);
4238 }
4239
4240 static GFileOutputStream *
4241 g_file_real_replace_finish (GFile         *file,
4242                             GAsyncResult  *res,
4243                             GError       **error)
4244 {
4245   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4246   ReplaceAsyncData *data;
4247
4248   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_replace_async);
4249
4250   data = g_simple_async_result_get_op_res_gpointer (simple);
4251   if (data->stream)
4252     return g_object_ref (data->stream);
4253   
4254   return NULL;
4255 }
4256
4257 typedef struct {
4258   char *name;
4259   GFile *file;
4260 } SetDisplayNameAsyncData;
4261
4262 static void
4263 set_display_name_data_free (SetDisplayNameAsyncData *data)
4264 {
4265   g_free (data->name);
4266   if (data->file)
4267     g_object_unref (data->file);
4268   g_free (data);
4269 }
4270
4271 static void
4272 set_display_name_async_thread (GSimpleAsyncResult *res,
4273                                GObject            *object,
4274                                GCancellable       *cancellable)
4275 {
4276   GError *error = NULL;
4277   SetDisplayNameAsyncData *data;
4278   GFile *file;
4279   
4280   data = g_simple_async_result_get_op_res_gpointer (res);
4281   
4282   file = g_file_set_display_name (G_FILE (object), data->name, cancellable, &error);
4283
4284   if (file == NULL)
4285     {
4286       g_simple_async_result_set_from_error (res, error);
4287       g_error_free (error);
4288     }
4289   else
4290     data->file = file;
4291 }
4292
4293 static void
4294 g_file_real_set_display_name_async (GFile               *file,  
4295                                     const char          *display_name,
4296                                     int                  io_priority,
4297                                     GCancellable        *cancellable,
4298                                     GAsyncReadyCallback  callback,
4299                                     gpointer             user_data)
4300 {
4301   GSimpleAsyncResult *res;
4302   SetDisplayNameAsyncData *data;
4303
4304   data = g_new0 (SetDisplayNameAsyncData, 1);
4305   data->name = g_strdup (display_name);
4306   
4307   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_display_name_async);
4308   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_display_name_data_free);
4309   
4310   g_simple_async_result_run_in_thread (res, set_display_name_async_thread, io_priority, cancellable);
4311   g_object_unref (res);
4312 }
4313
4314 static GFile *
4315 g_file_real_set_display_name_finish (GFile         *file,
4316                                      GAsyncResult  *res,
4317                                      GError       **error)
4318 {
4319   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4320   SetDisplayNameAsyncData *data;
4321
4322   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_display_name_async);
4323
4324   data = g_simple_async_result_get_op_res_gpointer (simple);
4325   if (data->file)
4326     return g_object_ref (data->file);
4327   
4328   return NULL;
4329 }
4330
4331 typedef struct {
4332   GFileQueryInfoFlags flags;
4333   GFileInfo *info;
4334   gboolean res;
4335   GError *error;
4336 } SetInfoAsyncData;
4337
4338 static void
4339 set_info_data_free (SetInfoAsyncData *data)
4340 {
4341   if (data->info)
4342     g_object_unref (data->info);
4343   if (data->error)
4344     g_error_free (data->error);
4345   g_free (data);
4346 }
4347
4348 static void
4349 set_info_async_thread (GSimpleAsyncResult *res,
4350                        GObject            *object,
4351                        GCancellable       *cancellable)
4352 {
4353   SetInfoAsyncData *data;
4354   
4355   data = g_simple_async_result_get_op_res_gpointer (res);
4356   
4357   data->error = NULL;
4358   data->res = g_file_set_attributes_from_info (G_FILE (object),
4359                                                data->info,
4360                                                data->flags,
4361                                                cancellable,
4362                                                &data->error);
4363 }
4364
4365 static void
4366 g_file_real_set_attributes_async (GFile               *file,
4367                                   GFileInfo           *info,
4368                                   GFileQueryInfoFlags  flags,
4369                                   int                  io_priority,
4370                                   GCancellable        *cancellable,
4371                                   GAsyncReadyCallback  callback,
4372                                   gpointer             user_data)
4373 {
4374   GSimpleAsyncResult *res;
4375   SetInfoAsyncData *data;
4376
4377   data = g_new0 (SetInfoAsyncData, 1);
4378   data->info = g_file_info_dup (info);
4379   data->flags = flags;
4380   
4381   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_attributes_async);
4382   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_info_data_free);
4383   
4384   g_simple_async_result_run_in_thread (res, set_info_async_thread, io_priority, cancellable);
4385   g_object_unref (res);
4386 }
4387
4388 static gboolean
4389 g_file_real_set_attributes_finish (GFile         *file,
4390                                    GAsyncResult  *res,
4391                                    GFileInfo    **info,
4392                                    GError       **error)
4393 {
4394   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4395   SetInfoAsyncData *data;
4396   
4397   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_attributes_async);
4398
4399   data = g_simple_async_result_get_op_res_gpointer (simple);
4400
4401   if (info) 
4402     *info = g_object_ref (data->info);
4403
4404   if (error != NULL && data->error) 
4405     *error = g_error_copy (data->error);
4406   
4407   return data->res;
4408 }
4409
4410 static void
4411 find_enclosing_mount_async_thread (GSimpleAsyncResult *res,
4412                                     GObject            *object,
4413                                     GCancellable       *cancellable)
4414 {
4415   GError *error = NULL;
4416   GMount *mount;
4417   
4418   mount = g_file_find_enclosing_mount (G_FILE (object), cancellable, &error);
4419
4420   if (mount == NULL)
4421     {
4422       g_simple_async_result_set_from_error (res, error);
4423       g_error_free (error);
4424     }
4425   else
4426     g_simple_async_result_set_op_res_gpointer (res, mount, (GDestroyNotify)g_object_unref);
4427 }
4428
4429 static void
4430 g_file_real_find_enclosing_mount_async (GFile               *file,
4431                                         int                  io_priority,
4432                                         GCancellable        *cancellable,
4433                                         GAsyncReadyCallback  callback,
4434                                         gpointer             user_data)
4435 {
4436   GSimpleAsyncResult *res;
4437   
4438   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_find_enclosing_mount_async);
4439   
4440   g_simple_async_result_run_in_thread (res, find_enclosing_mount_async_thread, io_priority, cancellable);
4441   g_object_unref (res);
4442 }
4443
4444 static GMount *
4445 g_file_real_find_enclosing_mount_finish (GFile         *file,
4446                                           GAsyncResult  *res,
4447                                           GError       **error)
4448 {
4449   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4450   GMount *mount;
4451
4452   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_find_enclosing_mount_async);
4453
4454   mount = g_simple_async_result_get_op_res_gpointer (simple);
4455   return g_object_ref (mount);
4456 }
4457
4458
4459 typedef struct {
4460   GFile *source;
4461   GFile *destination;
4462   GFileCopyFlags flags;
4463   GFileProgressCallback progress_cb;
4464   gpointer progress_cb_data;
4465   GIOSchedulerJob *job;
4466 } CopyAsyncData;
4467
4468 static void
4469 copy_async_data_free (CopyAsyncData *data)
4470 {
4471   g_object_unref (data->source);
4472   g_object_unref (data->destination);
4473   g_free (data);
4474 }
4475
4476 typedef struct {
4477   CopyAsyncData *data;
4478   goffset current_num_bytes;
4479   goffset total_num_bytes;
4480 } ProgressData;
4481
4482 static gboolean
4483 copy_async_progress_in_main (gpointer user_data)
4484 {
4485   ProgressData *progress = user_data;
4486   CopyAsyncData *data = progress->data;
4487
4488   data->progress_cb (progress->current_num_bytes,
4489                      progress->total_num_bytes,
4490                      data->progress_cb_data);
4491
4492   return FALSE;
4493 }
4494
4495 static gboolean
4496 mainloop_barrier (gpointer user_data)
4497 {
4498   /* Does nothing, but ensures all queued idles before
4499      this are run */
4500   return FALSE;
4501 }
4502
4503
4504 static void
4505 copy_async_progress_callback (goffset  current_num_bytes,
4506                               goffset  total_num_bytes,
4507                               gpointer user_data)
4508 {
4509   CopyAsyncData *data = user_data;
4510   ProgressData *progress;
4511
4512   progress = g_new (ProgressData, 1);
4513   progress->data = data;
4514   progress->current_num_bytes = current_num_bytes;
4515   progress->total_num_bytes = total_num_bytes;
4516   
4517   g_io_scheduler_job_send_to_mainloop_async (data->job,
4518                                              copy_async_progress_in_main,
4519                                              progress,
4520                                              g_free);
4521 }
4522
4523 static gboolean
4524 copy_async_thread (GIOSchedulerJob *job,
4525                    GCancellable    *cancellable,
4526                    gpointer         user_data)
4527 {
4528   GSimpleAsyncResult *res;
4529   CopyAsyncData *data;
4530   gboolean result;
4531   GError *error;
4532
4533   res = user_data;
4534   data = g_simple_async_result_get_op_res_gpointer (res);
4535
4536   error = NULL;
4537   data->job = job;
4538   result = g_file_copy (data->source,
4539                         data->destination,
4540                         data->flags,
4541                         cancellable,
4542                         (data->progress_cb != NULL) ? copy_async_progress_callback : NULL,
4543                         data,
4544                         &error);
4545
4546   /* Ensure all progress callbacks are done running in main thread */
4547   if (data->progress_cb != NULL)
4548     g_io_scheduler_job_send_to_mainloop (job,
4549                                          mainloop_barrier,
4550                                          NULL, NULL);
4551   
4552   if (!result)
4553     {
4554       g_simple_async_result_set_from_error (res, error);
4555       g_error_free (error);
4556     }
4557
4558   g_simple_async_result_complete_in_idle (res);
4559
4560   return FALSE;
4561 }
4562
4563 static void
4564 g_file_real_copy_async (GFile                  *source,
4565                         GFile                  *destination,
4566                         GFileCopyFlags          flags,
4567                         int                     io_priority,
4568                         GCancellable           *cancellable,
4569                         GFileProgressCallback   progress_callback,
4570                         gpointer                progress_callback_data,
4571                         GAsyncReadyCallback     callback,
4572                         gpointer                user_data)
4573 {
4574   GSimpleAsyncResult *res;
4575   CopyAsyncData *data;
4576
4577   data = g_new0 (CopyAsyncData, 1);
4578   data->source = g_object_ref (source);
4579   data->destination = g_object_ref (destination);
4580   data->flags = flags;
4581   data->progress_cb = progress_callback;
4582   data->progress_cb_data = progress_callback_data;
4583
4584   res = g_simple_async_result_new (G_OBJECT (source), callback, user_data, g_file_real_copy_async);
4585   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)copy_async_data_free);
4586
4587   g_io_scheduler_push_job (copy_async_thread, res, g_object_unref, io_priority, cancellable);
4588 }
4589
4590 static gboolean
4591 g_file_real_copy_finish (GFile        *file,
4592                          GAsyncResult *res,
4593                          GError      **error)
4594 {
4595   /* Error handled in g_file_copy_finish() */
4596   return TRUE;
4597 }
4598
4599
4600 /********************************************
4601  *   Default VFS operations                 *
4602  ********************************************/
4603
4604 /**
4605  * g_file_new_for_path:
4606  * @path: a string containing a relative or absolute path.
4607  * 
4608  * Constructs a #GFile for a given path. This operation never
4609  * fails, but the returned object might not support any I/O
4610  * operation if @path is malformed.
4611  * 
4612  * Returns: a new #GFile for the given @path. 
4613  **/
4614 GFile *
4615 g_file_new_for_path (const char *path)
4616 {
4617   g_return_val_if_fail (path != NULL, NULL);
4618
4619   return g_vfs_get_file_for_path (g_vfs_get_default (), path);
4620 }
4621  
4622 /**
4623  * g_file_new_for_uri:
4624  * @uri: a string containing a URI.
4625  * 
4626  * Constructs a #GFile for a given URI. This operation never 
4627  * fails, but the returned object might not support any I/O 
4628  * operation if @uri is malformed or if the uri type is 
4629  * not supported.
4630  * 
4631  * Returns: a #GFile for the given @uri.
4632  **/ 
4633 GFile *
4634 g_file_new_for_uri (const char *uri)
4635 {
4636   g_return_val_if_fail (uri != NULL, NULL);
4637
4638   return g_vfs_get_file_for_uri (g_vfs_get_default (), uri);
4639 }
4640   
4641 /**
4642  * g_file_parse_name:
4643  * @parse_name: a file name or path to be parsed.
4644  * 
4645  * Constructs a #GFile with the given @parse_name (i.e. something given by g_file_get_parse_name()).
4646  * This operation never fails, but the returned object might not support any I/O
4647  * operation if the @parse_name cannot be parsed.
4648  * 
4649  * Returns: a new #GFile.
4650  **/
4651 GFile *
4652 g_file_parse_name (const char *parse_name)
4653 {
4654   g_return_val_if_fail (parse_name != NULL, NULL);
4655
4656   return g_vfs_parse_name (g_vfs_get_default (), parse_name);
4657 }
4658
4659 static gboolean
4660 is_valid_scheme_character (char c)
4661 {
4662   return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.';
4663 }
4664
4665 static gboolean
4666 has_valid_scheme (const char *uri)
4667 {
4668   const char *p;
4669   
4670   p = uri;
4671   
4672   if (!is_valid_scheme_character (*p))
4673     return FALSE;
4674
4675   do {
4676     p++;
4677   } while (is_valid_scheme_character (*p));
4678
4679   return *p == ':';
4680 }
4681
4682 /**
4683  * g_file_new_for_commandline_arg:
4684  * @arg: a command line string.
4685  * 
4686  * Creates a #GFile with the given argument from the command line. The value of
4687  * @arg can be either a URI, an absolute path or a relative path resolved
4688  * relative to the current working directory.
4689  * This operation never fails, but the returned object might not support any
4690  * I/O operation if @arg points to a malformed path.
4691  *
4692  * Returns: a new #GFile. 
4693  **/
4694 GFile *
4695 g_file_new_for_commandline_arg (const char *arg)
4696 {
4697   GFile *file;
4698   char *filename;
4699   char *current_dir;
4700   
4701   g_return_val_if_fail (arg != NULL, NULL);
4702   
4703   if (g_path_is_absolute (arg))
4704     return g_file_new_for_path (arg);
4705
4706   if (has_valid_scheme (arg))
4707     return g_file_new_for_uri (arg);
4708     
4709   current_dir = g_get_current_dir ();
4710   filename = g_build_filename (current_dir, arg, NULL);
4711   g_free (current_dir);
4712   
4713   file = g_file_new_for_path (filename);
4714   g_free (filename);
4715   
4716   return file;
4717 }
4718
4719 /**
4720  * g_file_mount_enclosing_volume:
4721  * @location: input #GFile.
4722  * @flags: flags affecting the operation
4723  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
4724  * @cancellable: optional #GCancellable object, %NULL to ignore.
4725  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
4726  * @user_data: the data to pass to callback function
4727  * 
4728  * Starts a @mount_operation, mounting the volume that contains the file @location. 
4729  * 
4730  * When this operation has completed, @callback will be called with
4731  * @user_user data, and the operation can be finalized with 
4732  * g_file_mount_enclosing_volume_finish().
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 void
4739 g_file_mount_enclosing_volume (GFile               *location,
4740                                GMountMountFlags     flags,
4741                                GMountOperation     *mount_operation,
4742                                GCancellable        *cancellable,
4743                                GAsyncReadyCallback  callback,
4744                                gpointer             user_data)
4745 {
4746   GFileIface *iface;
4747
4748   g_return_if_fail (G_IS_FILE (location));
4749
4750   iface = G_FILE_GET_IFACE (location);
4751
4752   if (iface->mount_enclosing_volume == NULL)
4753     {
4754       g_simple_async_report_error_in_idle (G_OBJECT (location),
4755                                            callback, user_data,
4756                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
4757                                            _("volume doesn't implement mount"));
4758       
4759       return;
4760     }
4761   
4762   (* iface->mount_enclosing_volume) (location, flags, mount_operation, cancellable, callback, user_data);
4763
4764 }
4765
4766 /**
4767  * g_file_mount_enclosing_volume_finish:
4768  * @location: input #GFile.
4769  * @result: a #GAsyncResult.
4770  * @error: a #GError, or %NULL
4771  * 
4772  * Finishes a mount operation started by g_file_mount_enclosing_volume().
4773  * 
4774  * Returns: %TRUE if successful. If an error
4775  * has occurred, this function will return %FALSE and set @error
4776  * appropriately if present.
4777  **/
4778 gboolean
4779 g_file_mount_enclosing_volume_finish (GFile         *location,
4780                                       GAsyncResult  *result,
4781                                       GError       **error)
4782 {
4783   GFileIface *iface;
4784
4785   g_return_val_if_fail (G_IS_FILE (location), FALSE);
4786   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4787
4788   if (G_IS_SIMPLE_ASYNC_RESULT (result))
4789     {
4790       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
4791       if (g_simple_async_result_propagate_error (simple, error))
4792         return FALSE;
4793     }
4794   
4795   iface = G_FILE_GET_IFACE (location);
4796
4797   return (* iface->mount_enclosing_volume_finish) (location, result, error);
4798 }
4799
4800 /********************************************
4801  *   Utility functions                      *
4802  ********************************************/
4803
4804 /**
4805  * g_file_query_default_handler:
4806  * @file: a #GFile to open.
4807  * @cancellable: optional #GCancellable object, %NULL to ignore.
4808  * @error: a #GError, or %NULL
4809  *
4810  * Returns the #GAppInfo that is registered as the default
4811  * application to handle the file specified by @file.
4812  *
4813  * If @cancellable is not %NULL, then the operation can be cancelled by
4814  * triggering the cancellable object from another thread. If the operation
4815  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4816  *
4817  * Returns: a #GAppInfo if the handle was found, %NULL if there were errors.
4818  * When you are done with it, release it with g_object_unref()
4819  **/
4820 GAppInfo *
4821 g_file_query_default_handler (GFile                  *file,
4822                               GCancellable           *cancellable,
4823                               GError                **error)
4824 {
4825   char *uri_scheme;
4826   const char *content_type;
4827   GAppInfo *appinfo;
4828   GFileInfo *info;
4829   char *path;
4830   
4831   uri_scheme = g_file_get_uri_scheme (file);
4832   appinfo = g_app_info_get_default_for_uri_scheme (uri_scheme);
4833   g_free (uri_scheme);
4834
4835   if (appinfo != NULL)
4836     return appinfo;
4837
4838   info = g_file_query_info (file,
4839                             G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
4840                             0,
4841                             cancellable,
4842                             error);
4843   if (info == NULL)
4844     return NULL;
4845
4846   appinfo = NULL;
4847
4848   content_type = g_file_info_get_content_type (info);
4849   if (content_type)
4850     {
4851       /* Don't use is_native(), as we want to support fuse paths if availible */
4852       path = g_file_get_path (file);
4853       appinfo = g_app_info_get_default_for_type (content_type,
4854                                                  path == NULL);
4855       g_free (path);
4856     }
4857   
4858   g_object_unref (info);
4859
4860   if (appinfo != NULL)
4861     return appinfo;
4862
4863   g_set_error (error, G_IO_ERROR,
4864                G_IO_ERROR_NOT_SUPPORTED,
4865                _("No application is registered as handling this file"));
4866   return NULL;
4867   
4868 }
4869
4870
4871 #define GET_CONTENT_BLOCK_SIZE 8192
4872
4873 /**
4874  * g_file_load_contents:
4875  * @file: input #GFile.
4876  * @cancellable: optional #GCancellable object, %NULL to ignore.
4877  * @contents: a location to place the contents of the file.
4878  * @length: a location to place the length of the contents of the file.
4879  * @etag_out: a location to place the current entity tag for the file.
4880  * @error: a #GError, or %NULL
4881  *
4882  * Loads the content of the file into memory, returning the size of
4883  * the data. The data is always zero terminated, but this is not
4884  * included in the resultant @length.
4885  * 
4886  * If @cancellable is not %NULL, then the operation can be cancelled by
4887  * triggering the cancellable object from another thread. If the operation
4888  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4889  * 
4890  * Returns: %TRUE if the @file's contents were successfully loaded.
4891  * %FALSE if there were errors..
4892  **/
4893 gboolean
4894 g_file_load_contents (GFile         *file,
4895                       GCancellable  *cancellable,
4896                       char         **contents,
4897                       gsize         *length,
4898                       char         **etag_out,
4899                       GError       **error)
4900 {
4901   GFileInputStream *in;
4902   GByteArray *content;
4903   gsize pos;
4904   gssize res;
4905   GFileInfo *info;
4906
4907   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4908   g_return_val_if_fail (contents != NULL, FALSE);
4909
4910   in = g_file_read (file, cancellable, error);
4911   if (in == NULL)
4912     return FALSE;
4913
4914   content = g_byte_array_new ();
4915   pos = 0;
4916   
4917   g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
4918   while ((res = g_input_stream_read (G_INPUT_STREAM (in),
4919                                      content->data + pos,
4920                                      GET_CONTENT_BLOCK_SIZE,
4921                                      cancellable, error)) > 0)
4922     {
4923       pos += res;
4924       g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
4925     }
4926
4927   if (etag_out)
4928     {
4929       *etag_out = NULL;
4930       
4931       info = g_file_input_stream_query_info (in,
4932                                              G_FILE_ATTRIBUTE_ETAG_VALUE,
4933                                              cancellable,
4934                                              NULL);
4935       if (info)
4936         {
4937           *etag_out = g_strdup (g_file_info_get_etag (info));
4938           g_object_unref (info);
4939         }
4940     } 
4941
4942   /* Ignore errors on close */
4943   g_input_stream_close (G_INPUT_STREAM (in), cancellable, NULL);
4944   g_object_unref (in);
4945
4946   if (res < 0)
4947     {
4948       /* error is set already */
4949       g_byte_array_free (content, TRUE);
4950       return FALSE;
4951     }
4952
4953   if (length)
4954     *length = pos;
4955
4956   /* Zero terminate (we got an extra byte allocated for this */
4957   content->data[pos] = 0;
4958   
4959   *contents = (char *)g_byte_array_free (content, FALSE);
4960   
4961   return TRUE;
4962 }
4963
4964 typedef struct {
4965   GFile *file;
4966   GError *error;
4967   GCancellable *cancellable;
4968   GFileReadMoreCallback read_more_callback;
4969   GAsyncReadyCallback callback;
4970   gpointer user_data;
4971   GByteArray *content;
4972   gsize pos;
4973   char *etag;
4974 } LoadContentsData;
4975
4976
4977 static void
4978 load_contents_data_free (LoadContentsData *data)
4979 {
4980   if (data->error)
4981     g_error_free (data->error);
4982   if (data->cancellable)
4983     g_object_unref (data->cancellable);
4984   if (data->content)
4985     g_byte_array_free (data->content, TRUE);
4986   g_free (data->etag);
4987   g_object_unref (data->file);
4988   g_free (data);
4989 }
4990
4991 static void
4992 load_contents_close_callback (GObject      *obj,
4993                               GAsyncResult *close_res,
4994                               gpointer      user_data)
4995 {
4996   GInputStream *stream = G_INPUT_STREAM (obj);
4997   LoadContentsData *data = user_data;
4998   GSimpleAsyncResult *res;
4999
5000   /* Ignore errors here, we're only reading anyway */
5001   g_input_stream_close_finish (stream, close_res, NULL);
5002   g_object_unref (stream);
5003
5004   res = g_simple_async_result_new (G_OBJECT (data->file),
5005                                    data->callback,
5006                                    data->user_data,
5007                                    g_file_load_contents_async);
5008   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)load_contents_data_free);
5009   g_simple_async_result_complete (res);
5010   g_object_unref (res);
5011 }
5012
5013 static void
5014 load_contents_fstat_callback (GObject      *obj,
5015                               GAsyncResult *stat_res,
5016                               gpointer      user_data)
5017 {
5018   GInputStream *stream = G_INPUT_STREAM (obj);
5019   LoadContentsData *data = user_data;
5020   GFileInfo *info;
5021
5022   info = g_file_input_stream_query_info_finish (G_FILE_INPUT_STREAM (stream),
5023                                                    stat_res, NULL);
5024   if (info)
5025     {
5026       data->etag = g_strdup (g_file_info_get_etag (info));
5027       g_object_unref (info);
5028     }
5029
5030   g_input_stream_close_async (stream, 0,
5031                               data->cancellable,
5032                               load_contents_close_callback, data);
5033 }
5034
5035 static void
5036 load_contents_read_callback (GObject      *obj,
5037                              GAsyncResult *read_res,
5038                              gpointer      user_data)
5039 {
5040   GInputStream *stream = G_INPUT_STREAM (obj);
5041   LoadContentsData *data = user_data;
5042   GError *error = NULL;
5043   gssize read_size;
5044
5045   read_size = g_input_stream_read_finish (stream, read_res, &error);
5046
5047   if (read_size < 0) 
5048     {
5049       /* Error or EOF, close the file */
5050       data->error = error;
5051       g_input_stream_close_async (stream, 0,
5052                                   data->cancellable,
5053                                   load_contents_close_callback, data);
5054     }
5055   else if (read_size == 0)
5056     {
5057       g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
5058                                             G_FILE_ATTRIBUTE_ETAG_VALUE,
5059                                             0,
5060                                             data->cancellable,
5061                                             load_contents_fstat_callback,
5062                                             data);
5063     }
5064   else if (read_size > 0)
5065     {
5066       data->pos += read_size;
5067       
5068       g_byte_array_set_size (data->content,
5069                              data->pos + GET_CONTENT_BLOCK_SIZE);
5070
5071
5072       if (data->read_more_callback &&
5073           !data->read_more_callback ((char *)data->content->data, data->pos, data->user_data))
5074         g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
5075                                               G_FILE_ATTRIBUTE_ETAG_VALUE,
5076                                               0,
5077                                               data->cancellable,
5078                                               load_contents_fstat_callback,
5079                                               data);
5080       else 
5081         g_input_stream_read_async (stream,
5082                                    data->content->data + data->pos,
5083                                    GET_CONTENT_BLOCK_SIZE,
5084                                    0,
5085                                    data->cancellable,
5086                                    load_contents_read_callback,
5087                                    data);
5088     }
5089 }
5090
5091 static void
5092 load_contents_open_callback (GObject      *obj,
5093                              GAsyncResult *open_res,
5094                              gpointer      user_data)
5095 {
5096   GFile *file = G_FILE (obj);
5097   GFileInputStream *stream;
5098   LoadContentsData *data = user_data;
5099   GError *error = NULL;
5100   GSimpleAsyncResult *res;
5101
5102   stream = g_file_read_finish (file, open_res, &error);
5103
5104   if (stream)
5105     {
5106       g_byte_array_set_size (data->content,
5107                              data->pos + GET_CONTENT_BLOCK_SIZE);
5108       g_input_stream_read_async (G_INPUT_STREAM (stream),
5109                                  data->content->data + data->pos,
5110                                  GET_CONTENT_BLOCK_SIZE,
5111                                  0,
5112                                  data->cancellable,
5113                                  load_contents_read_callback,
5114                                  data);
5115       
5116     }
5117   else
5118     {
5119       res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
5120                                                   data->callback,
5121                                                   data->user_data,
5122                                                   error);
5123       g_simple_async_result_complete (res);
5124       g_error_free (error);
5125       load_contents_data_free (data);
5126       g_object_unref (res);
5127     }
5128 }
5129
5130 /**
5131  * g_file_load_partial_contents_async:
5132  * @file: input #GFile.
5133  * @cancellable: optional #GCancellable object, %NULL to ignore.
5134  * @read_more_callback: a #GFileReadMoreCallback to receive partial data and to specify whether further data should be read.
5135  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
5136  * @user_data: the data to pass to the callback functions.
5137  *
5138  * Reads the partial contents of a file. A #GFileReadMoreCallback should be 
5139  * used to stop reading from the file when appropriate, else this function
5140  * will behave exactly as g_file_load_contents_async(). This operation 
5141  * can be finished by g_file_load_partial_contents_finish().
5142  *
5143  * Users of this function should be aware that @user_data is passed to 
5144  * both the @read_more_callback and the @callback.
5145  *
5146  * If @cancellable is not %NULL, then the operation can be cancelled by
5147  * triggering the cancellable object from another thread. If the operation
5148  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5149  **/
5150 void
5151 g_file_load_partial_contents_async (GFile                 *file,
5152                                     GCancellable          *cancellable,
5153                                     GFileReadMoreCallback  read_more_callback,
5154                                     GAsyncReadyCallback    callback,
5155                                     gpointer               user_data)
5156 {
5157   LoadContentsData *data;
5158
5159   g_return_if_fail (G_IS_FILE (file));
5160
5161   data = g_new0 (LoadContentsData, 1);
5162
5163   if (cancellable)
5164     data->cancellable = g_object_ref (cancellable);
5165   data->read_more_callback = read_more_callback;
5166   data->callback = callback;
5167   data->user_data = user_data;
5168   data->content = g_byte_array_new ();
5169   data->file = g_object_ref (file);
5170
5171   g_file_read_async (file,
5172                      0,
5173                      cancellable,
5174                      load_contents_open_callback,
5175                      data);
5176 }
5177
5178 /**
5179  * g_file_load_partial_contents_finish:
5180  * @file: input #GFile.
5181  * @res: a #GAsyncResult. 
5182  * @contents: a location to place the contents of the file.
5183  * @length: a location to place the length of the contents of the file.
5184  * @etag_out: a location to place the current entity tag for the file.
5185  * @error: a #GError, or %NULL
5186  * 
5187  * Finishes an asynchronous partial load operation that was started
5188  * with g_file_load_partial_contents_async().
5189  *
5190  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
5191  * present, it will be set appropriately. 
5192  **/
5193 gboolean
5194 g_file_load_partial_contents_finish (GFile         *file,
5195                                      GAsyncResult  *res,
5196                                      char         **contents,
5197                                      gsize         *length,
5198                                      char         **etag_out,
5199                                      GError       **error)
5200 {
5201   GSimpleAsyncResult *simple;
5202   LoadContentsData *data;
5203
5204   g_return_val_if_fail (G_IS_FILE (file), FALSE);
5205   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
5206   g_return_val_if_fail (contents != NULL, FALSE);
5207
5208   simple = G_SIMPLE_ASYNC_RESULT (res);
5209
5210   if (g_simple_async_result_propagate_error (simple, error))
5211     return FALSE;
5212   
5213   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_load_contents_async);
5214   
5215   data = g_simple_async_result_get_op_res_gpointer (simple);
5216
5217   if (data->error)
5218     {
5219       g_propagate_error (error, data->error);
5220       data->error = NULL;
5221       *contents = NULL;
5222       if (length)
5223         *length = 0;
5224       return FALSE;
5225     }
5226
5227   if (length)
5228     *length = data->pos;
5229
5230   if (etag_out)
5231     {
5232       *etag_out = data->etag;
5233       data->etag = NULL;
5234     }
5235
5236   /* Zero terminate */
5237   g_byte_array_set_size (data->content, data->pos + 1);
5238   data->content->data[data->pos] = 0;
5239   
5240   *contents = (char *)g_byte_array_free (data->content, FALSE);
5241   data->content = NULL;
5242
5243   return TRUE;
5244 }
5245
5246 /**
5247  * g_file_load_contents_async:
5248  * @file: input #GFile.
5249  * @cancellable: optional #GCancellable object, %NULL to ignore.
5250  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
5251  * @user_data: the data to pass to callback function
5252  * 
5253  * Starts an asynchronous load of the @file's contents.
5254  *
5255  * For more details, see g_file_load_contents() which is
5256  * the synchronous version of this call.
5257  *
5258  * When the load operation has completed, @callback will be called 
5259  * with @user data. To finish the operation, call 
5260  * g_file_load_contents_finish() with the #GAsyncResult returned by 
5261  * the @callback.
5262  * 
5263  * If @cancellable is not %NULL, then the operation can be cancelled by
5264  * triggering the cancellable object from another thread. If the operation
5265  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5266  **/
5267 void
5268 g_file_load_contents_async (GFile               *file,
5269                            GCancellable        *cancellable,
5270                            GAsyncReadyCallback  callback,
5271                            gpointer             user_data)
5272 {
5273   g_file_load_partial_contents_async (file,
5274                                       cancellable,
5275                                       NULL,
5276                                       callback, user_data);
5277 }
5278
5279 /**
5280  * g_file_load_contents_finish:
5281  * @file: input #GFile.
5282  * @res: a #GAsyncResult. 
5283  * @contents: a location to place the contents of the file.
5284  * @length: a location to place the length of the contents of the file.
5285  * @etag_out: a location to place the current entity tag for the file.
5286  * @error: a #GError, or %NULL
5287  * 
5288  * Finishes an asynchronous load of the @file's contents. 
5289  * The contents are placed in @contents, and @length is set to the 
5290  * size of the @contents string. If @etag_out is present, it will be 
5291  * set to the new entity tag for the @file.
5292  * 
5293  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
5294  * present, it will be set appropriately. 
5295  **/
5296 gboolean
5297 g_file_load_contents_finish (GFile         *file,
5298                              GAsyncResult  *res,
5299                              char         **contents,
5300                              gsize         *length,
5301                              char         **etag_out,
5302                              GError       **error)
5303 {
5304   return g_file_load_partial_contents_finish (file,
5305                                               res,
5306                                               contents,
5307                                               length,
5308                                               etag_out,
5309                                               error);
5310 }
5311   
5312 /**
5313  * g_file_replace_contents:
5314  * @file: input #GFile.
5315  * @contents: a string containing the new contents for @file.
5316  * @length: the length of @contents in bytes.
5317  * @etag: the old <link linkend="gfile-etag">entity tag</link> 
5318  *     for the document.
5319  * @make_backup: %TRUE if a backup should be created.
5320  * @flags: a set of #GFileCreateFlags.
5321  * @new_etag: a location to a new <link linkend="gfile-etag">entity tag</link>
5322  *      for the document. This should be freed with g_free() when no longer 
5323  *      needed.
5324  * @cancellable: optional #GCancellable object, %NULL to ignore.
5325  * @error: a #GError, or %NULL
5326  *
5327  * Replaces the contents of @file with @contents of @length bytes.
5328  
5329  * If @etag is specified (not %NULL) any existing file must have that etag, or
5330  * the error %G_IO_ERROR_WRONG_ETAG will be returned.
5331  *
5332  * If @make_backup is %TRUE, this function will attempt to make a backup of @file.
5333  * 
5334  * If @cancellable is not %NULL, then the operation can be cancelled by
5335  * triggering the cancellable object from another thread. If the operation
5336  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5337  *
5338  * The returned @new_etag can be used to verify that the file hasn't changed the
5339  * next time it is saved over.
5340  * 
5341  * Returns: %TRUE if successful. If an error
5342  * has occurred, this function will return %FALSE and set @error
5343  * appropriately if present.
5344  **/
5345 gboolean
5346 g_file_replace_contents (GFile             *file,
5347                          const char        *contents,
5348                          gsize              length,
5349                          const char        *etag,
5350                          gboolean           make_backup,
5351                          GFileCreateFlags   flags,
5352                          char             **new_etag,
5353                          GCancellable      *cancellable,
5354                          GError           **error)
5355 {
5356   GFileOutputStream *out;
5357   gsize pos, remainder;
5358   gssize res;
5359
5360   g_return_val_if_fail (G_IS_FILE (file), FALSE);
5361   g_return_val_if_fail (contents != NULL, FALSE);
5362
5363   out = g_file_replace (file, etag, make_backup, flags, cancellable, error);
5364   if (out == NULL)
5365     return FALSE;
5366
5367   pos = 0;
5368   remainder = length;
5369   while (remainder > 0 &&
5370          (res = g_output_stream_write (G_OUTPUT_STREAM (out),
5371                                        contents + pos,
5372                                        MIN (remainder, GET_CONTENT_BLOCK_SIZE),
5373                                        cancellable,
5374                                        error)) > 0)
5375     {
5376       pos += res;
5377       remainder -= res;
5378     }
5379   
5380   if (remainder > 0 && res < 0)
5381     {
5382       /* Ignore errors on close */
5383       g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, NULL);
5384       
5385       /* error is set already */
5386       return FALSE;
5387     }
5388   
5389   if (!g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, error))
5390     return FALSE;
5391
5392   if (new_etag)
5393     *new_etag = g_file_output_stream_get_etag (out);
5394   
5395   return TRUE;
5396 }
5397
5398 typedef struct {
5399   GFile *file;
5400   GError *error;
5401   GCancellable *cancellable;
5402   GAsyncReadyCallback callback;
5403   gpointer user_data;
5404   const char *content;
5405   gsize length;
5406   gsize pos;
5407   char *etag;
5408 } ReplaceContentsData;
5409
5410 static void
5411 replace_contents_data_free (ReplaceContentsData *data)
5412 {
5413   if (data->error)
5414     g_error_free (data->error);
5415   if (data->cancellable)
5416     g_object_unref (data->cancellable);
5417   g_object_unref (data->file);
5418   g_free (data->etag);
5419   g_free (data);
5420 }
5421
5422 static void
5423 replace_contents_close_callback (GObject      *obj,
5424                                  GAsyncResult *close_res,
5425                                  gpointer      user_data)
5426 {
5427   GOutputStream *stream = G_OUTPUT_STREAM (obj);
5428   ReplaceContentsData *data = user_data;
5429   GSimpleAsyncResult *res;
5430
5431   /* Ignore errors here, we're only reading anyway */
5432   g_output_stream_close_finish (stream, close_res, NULL);
5433   g_object_unref (stream);
5434
5435   data->etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (stream));
5436   
5437   res = g_simple_async_result_new (G_OBJECT (data->file),
5438                                    data->callback,
5439                                    data->user_data,
5440                                    g_file_replace_contents_async);
5441   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_contents_data_free);
5442   g_simple_async_result_complete (res);
5443   g_object_unref (res);
5444 }
5445
5446 static void
5447 replace_contents_write_callback (GObject      *obj,
5448                                  GAsyncResult *read_res,
5449                                  gpointer      user_data)
5450 {
5451   GOutputStream *stream = G_OUTPUT_STREAM (obj);
5452   ReplaceContentsData *data = user_data;
5453   GError *error = NULL;
5454   gssize write_size;
5455   
5456   write_size = g_output_stream_write_finish (stream, read_res, &error);
5457
5458   if (write_size <= 0) 
5459     {
5460       /* Error or EOF, close the file */
5461       if (write_size < 0)
5462         data->error = error;
5463       g_output_stream_close_async (stream, 0,
5464                                    data->cancellable,
5465                                    replace_contents_close_callback, data);
5466     }
5467   else if (write_size > 0)
5468     {
5469       data->pos += write_size;
5470
5471       if (data->pos >= data->length)
5472         g_output_stream_close_async (stream, 0,
5473                                      data->cancellable,
5474                                      replace_contents_close_callback, data);
5475       else
5476         g_output_stream_write_async (stream,
5477                                      data->content + data->pos,
5478                                      data->length - data->pos,
5479                                      0,
5480                                      data->cancellable,
5481                                      replace_contents_write_callback,
5482                                      data);
5483     }
5484 }
5485
5486 static void
5487 replace_contents_open_callback (GObject      *obj,
5488                                 GAsyncResult *open_res,
5489                                 gpointer      user_data)
5490 {
5491   GFile *file = G_FILE (obj);
5492   GFileOutputStream *stream;
5493   ReplaceContentsData *data = user_data;
5494   GError *error = NULL;
5495   GSimpleAsyncResult *res;
5496
5497   stream = g_file_replace_finish (file, open_res, &error);
5498
5499   if (stream)
5500     {
5501       g_output_stream_write_async (G_OUTPUT_STREAM (stream),
5502                                    data->content + data->pos,
5503                                    data->length - data->pos,
5504                                    0,
5505                                    data->cancellable,
5506                                    replace_contents_write_callback,
5507                                    data);
5508       
5509     }
5510   else
5511     {
5512       res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
5513                                                   data->callback,
5514                                                   data->user_data,
5515                                                   error);
5516       g_simple_async_result_complete (res);
5517       g_error_free (error);
5518       replace_contents_data_free (data);
5519       g_object_unref (res);
5520     }
5521 }
5522
5523 /**
5524  * g_file_replace_contents_async:
5525  * @file: input #GFile.
5526  * @contents: string of contents to replace the file with.
5527  * @length: the length of @contents in bytes.
5528  * @etag: a new <link linkend="gfile-etag">entity tag</link> for the @file.
5529  * @make_backup: %TRUE if a backup should be created.
5530  * @flags: a set of #GFileCreateFlags.
5531  * @cancellable: optional #GCancellable object, %NULL to ignore.
5532  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
5533  * @user_data: the data to pass to callback function
5534  * 
5535  * Starts an asynchronous replacement of @file with the given 
5536  * @contents of @length bytes. @etag will replace the document's 
5537  * current entity tag.
5538  * 
5539  * When this operation has completed, @callback will be called with
5540  * @user_user data, and the operation can be finalized with 
5541  * g_file_replace_contents_finish().
5542  * 
5543  * If @cancellable is not %NULL, then the operation can be cancelled by
5544  * triggering the cancellable object from another thread. If the operation
5545  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5546  * 
5547  * If @make_backup is %TRUE, this function will attempt to 
5548  * make a backup of @file.
5549  **/
5550 void
5551 g_file_replace_contents_async  (GFile               *file,
5552                                 const char          *contents,
5553                                 gsize                length,
5554                                 const char          *etag,
5555                                 gboolean             make_backup,
5556                                 GFileCreateFlags     flags,
5557                                 GCancellable        *cancellable,
5558                                 GAsyncReadyCallback  callback,
5559                                 gpointer             user_data)
5560 {
5561   ReplaceContentsData *data;
5562
5563   g_return_if_fail (G_IS_FILE (file));
5564   g_return_if_fail (contents != NULL);
5565
5566   data = g_new0 (ReplaceContentsData, 1);
5567
5568   if (cancellable)
5569     data->cancellable = g_object_ref (cancellable);
5570   data->callback = callback;
5571   data->user_data = user_data;
5572   data->content = contents;
5573   data->length = length;
5574   data->pos = 0;
5575   data->file = g_object_ref (file);
5576
5577   g_file_replace_async (file,
5578                         etag,
5579                         make_backup,
5580                         flags,
5581                         0,
5582                         cancellable,
5583                         replace_contents_open_callback,
5584                         data);
5585 }
5586   
5587 /**
5588  * g_file_replace_contents_finish:
5589  * @file: input #GFile.
5590  * @res: a #GAsyncResult. 
5591  * @new_etag: a location of a new <link linkend="gfile-etag">entity tag</link> 
5592  *     for the document. This should be freed with g_free() when it is no 
5593  *     longer needed.
5594  * @error: a #GError, or %NULL 
5595  * 
5596  * Finishes an asynchronous replace of the given @file. See
5597  * g_file_replace_contents_async(). Sets @new_etag to the new entity 
5598  * tag for the document, if present.
5599  * 
5600  * Returns: %TRUE on success, %FALSE on failure.
5601  **/
5602 gboolean
5603 g_file_replace_contents_finish (GFile         *file,
5604                                 GAsyncResult  *res,
5605                                 char         **new_etag,
5606                                 GError       **error)
5607 {
5608   GSimpleAsyncResult *simple;
5609   ReplaceContentsData *data;
5610
5611   g_return_val_if_fail (G_IS_FILE (file), FALSE);
5612   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
5613
5614   simple = G_SIMPLE_ASYNC_RESULT (res);
5615
5616   if (g_simple_async_result_propagate_error (simple, error))
5617     return FALSE;
5618   
5619   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_replace_contents_async);
5620   
5621   data = g_simple_async_result_get_op_res_gpointer (simple);
5622
5623   if (data->error)
5624     {
5625       g_propagate_error (error, data->error);
5626       data->error = NULL;
5627       return FALSE;
5628     }
5629
5630
5631   if (new_etag)
5632     {
5633       *new_etag = data->etag;
5634       data->etag = NULL; /* Take ownership */
5635     }
5636   
5637   return TRUE;
5638 }
5639
5640 #define __G_FILE_C__
5641 #include "gioaliasdef.c"