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