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