*_async() functions: Several small corrections to the documentation,
[platform/upstream/glib.git] / gio / gfile.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include <config.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #ifdef HAVE_PWD_H
27 #include <pwd.h>
28 #endif
29 #include "gfile.h"
30 #include "gvfs.h"
31 #include "gioscheduler.h"
32 #include <glocalfile.h>
33 #include "gsimpleasyncresult.h"
34 #include "gfileattribute-priv.h"
35 #include "gpollfilemonitor.h"
36 #include "glibintl.h"
37
38 #include "gioalias.h"
39
40 /**
41  * SECTION:gfile
42  * @short_description: File and Directory Handling
43  * @include: gio.h
44  * @see_also: #GFileInfo, #GFileEnumerator
45  * 
46  * #GFile is a high level abstraction for manipulating files on a 
47  * virtual file system. #GFile<!-- -->s are lightweight, immutable 
48  * objects that do no I/O upon creation. It is necessary to understand that
49  * #GFile objects do not represent files, merely a handle to a file. All
50  * file I/O is implemented as streaming operations (see #GInputStream and 
51  * #GOutputStream).
52  * 
53  * To construct a #GFile, you can use: 
54  * g_file_new_for_path() if you have a path.
55  * g_file_new_for_uri() if you have a URI.
56  * g_file_new_for_commandline_arg() for a command line argument.
57  * 
58  * You can move through the filesystem with #GFile handles with
59  * g_file_get_parent() to get a handle to the parent directory.
60  * g_file_get_child() to get a handle to a child within a directory.
61  * g_file_resolve_relative_path() to resolve a relative path between
62  * two #GFile<!-- -->s.
63  * 
64  * Many #GFile operations have both synchronous and asynchronous versions 
65  * to suit your application. Asynchronous versions of synchronous functions 
66  * simply have _async() appended to their function names. The asynchronous 
67  * I/O functions call a #GAsyncReadyCallback which is then used to finalize 
68  * the operation, 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 "standard::*" means all attributes in the standard
696  * namespace. An example attribute query be "standard::*,owner::user".
697  * The standard attributes are availible as defines, like #G_FILE_ATTRIBUTE_STANDARD_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 "standard::*" means all attributes in the standard
832  * namespace. An example attribute query be "standard::*,owner::user".
833  * The standard attributes are availible as defines, like #G_FILE_ATTRIBUTE_STANDARD_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 (such as 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_query_info_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_FILESYSTEM_SIZE
973  * (the total size of the filesystem in bytes), #G_FILE_ATTRIBUTE_FILESYSTEM_FREE (number of
974  * bytes availible), and #G_FILE_ATTRIBUTE_FILESYSTEM_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, or NULL to ignore.
1509  * @make_backup: %TRUE if a backup should be created.
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_STANDARD_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_STANDARD_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_STANDARD_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_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_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_STANDARD_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  * 
2436  * For more details, see g_set_display_name() which is
2437  * the synchronous version of this call.
2438  *
2439  * When the operation is finished, @callback will be called. You can then call
2440  * g_file_set_display_name_finish() to get the result of the operation.
2441  **/
2442 void
2443 g_file_set_display_name_async (GFile               *file,
2444                                const char          *display_name,
2445                                int                  io_priority,
2446                                GCancellable        *cancellable,
2447                                GAsyncReadyCallback  callback,
2448                                gpointer             user_data)
2449 {
2450   GFileIface *iface;
2451   
2452   g_return_if_fail (G_IS_FILE (file));
2453   g_return_if_fail (display_name != NULL);
2454
2455   iface = G_FILE_GET_IFACE (file);
2456   (* iface->set_display_name_async) (file,
2457                                      display_name,
2458                                      io_priority,
2459                                      cancellable,
2460                                      callback,
2461                                      user_data);
2462 }
2463
2464 /**
2465  * g_file_set_display_name_finish:
2466  * @file: input #GFile.
2467  * @res: a #GAsyncResult. 
2468  * @error: a #GError, or %NULL
2469  * 
2470  * Finishes setting a display name started with 
2471  * g_file_set_display_name_async().
2472  * 
2473  * Returns: a #GFile or %NULL on error.
2474  **/
2475 GFile *
2476 g_file_set_display_name_finish (GFile         *file,
2477                                 GAsyncResult  *res,
2478                                 GError       **error)
2479 {
2480   GFileIface *iface;
2481   
2482   g_return_val_if_fail (G_IS_FILE (file), NULL);
2483   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2484
2485   if (G_IS_SIMPLE_ASYNC_RESULT (res))
2486     {
2487       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
2488       if (g_simple_async_result_propagate_error (simple, error))
2489         return NULL;
2490     }
2491   
2492   iface = G_FILE_GET_IFACE (file);
2493   return (* iface->set_display_name_finish) (file, res, error);
2494 }
2495
2496 /**
2497  * g_file_query_settable_attributes:
2498  * @file: input #GFile.
2499  * @cancellable: optional #GCancellable object, %NULL to ignore.
2500  * @error: a #GError, or %NULL
2501  * 
2502  * Obtain the list of settable attributes for the file.
2503  *
2504  * Returns the type and full attribute name of all the attributes 
2505  * that can be set on this file. This doesn't mean setting it will always 
2506  * succeed though, you might get an access failure, or some specific 
2507  * file may not support a specific attribute.
2508  *
2509  * If @cancellable is not %NULL, then the operation can be cancelled by
2510  * triggering the cancellable object from another thread. If the operation
2511  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2512  * 
2513  * Returns: a #GFileAttributeInfoList describing the settable attributes.
2514  * When you are done with it, release it with g_file_attribute_info_list_unref()
2515  **/
2516 GFileAttributeInfoList *
2517 g_file_query_settable_attributes (GFile         *file,
2518                                   GCancellable  *cancellable,
2519                                   GError       **error)
2520 {
2521   GFileIface *iface;
2522   GError *my_error;
2523   GFileAttributeInfoList *list;
2524
2525   g_return_val_if_fail (G_IS_FILE (file), NULL);
2526
2527   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2528     return NULL;
2529   
2530   iface = G_FILE_GET_IFACE (file);
2531
2532   if (iface->query_settable_attributes == NULL)
2533     return g_file_attribute_info_list_new ();
2534
2535   my_error = NULL;
2536   list = (* iface->query_settable_attributes) (file, cancellable, &my_error);
2537   
2538   if (list == NULL)
2539     {
2540       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
2541         {
2542           list = g_file_attribute_info_list_new ();
2543           g_error_free (my_error);
2544         }
2545       else
2546         g_propagate_error (error, my_error);
2547     }
2548   
2549   return list;
2550 }
2551
2552 /**
2553  * g_file_query_writable_namespaces:
2554  * @file: input #GFile.
2555  * @cancellable: optional #GCancellable object, %NULL to ignore.
2556  * @error: a #GError, or %NULL
2557  * 
2558  * Obtain the list of attribute namespaces where new attributes 
2559  * can be created by a user. An example of this is extended
2560  * attributes (in the "xattr" namespace).
2561  *
2562  * If @cancellable is not %NULL, then the operation can be cancelled by
2563  * triggering the cancellable object from another thread. If the operation
2564  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2565  * 
2566  * Returns: a #GFileAttributeInfoList describing the writable namespaces.
2567  * When you are done with it, release it with g_file_attribute_info_list_unref()
2568  **/
2569 GFileAttributeInfoList *
2570 g_file_query_writable_namespaces (GFile         *file,
2571                                   GCancellable  *cancellable,
2572                                   GError       **error)
2573 {
2574   GFileIface *iface;
2575   GError *my_error;
2576   GFileAttributeInfoList *list;
2577   
2578   g_return_val_if_fail (G_IS_FILE (file), NULL);
2579
2580   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2581     return NULL;
2582   
2583   iface = G_FILE_GET_IFACE (file);
2584
2585   if (iface->query_writable_namespaces == NULL)
2586     return g_file_attribute_info_list_new ();
2587
2588   my_error = NULL;
2589   list = (* iface->query_writable_namespaces) (file, cancellable, &my_error);
2590   
2591   if (list == NULL)
2592     {
2593       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
2594         {
2595           list = g_file_attribute_info_list_new ();
2596           g_error_free (my_error);
2597         }
2598       else
2599         g_propagate_error (error, my_error);
2600     }
2601   
2602   return list;
2603 }
2604
2605 /**
2606  * g_file_set_attribute:
2607  * @file: input #GFile.
2608  * @attribute: a string containing the attribute's name.
2609  * @type: The type of the attribute
2610  * @value_p: a pointer to the value (or the pointer itself if the type is a pointer type)
2611  * @flags: a set of #GFileQueryInfoFlags.
2612  * @cancellable: optional #GCancellable object, %NULL to ignore.
2613  * @error: a #GError, or %NULL
2614  * 
2615  * Sets an attribute in the file with attribute name @attribute to @value.
2616  * 
2617  * If @cancellable is not %NULL, then the operation can be cancelled by
2618  * triggering the cancellable object from another thread. If the operation
2619  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2620  * 
2621  * Returns: %TRUE if the attribute was set, %FALSE otherwise.
2622  **/
2623 gboolean
2624 g_file_set_attribute (GFile                      *file,
2625                       const char                 *attribute,
2626                       GFileAttributeType          type,
2627                       gpointer                    value_p,
2628                       GFileQueryInfoFlags         flags,
2629                       GCancellable               *cancellable,
2630                       GError                    **error)
2631 {
2632   GFileIface *iface;
2633   
2634   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2635   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
2636
2637   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2638     return FALSE;
2639   
2640   iface = G_FILE_GET_IFACE (file);
2641
2642   if (iface->set_attribute == NULL)
2643     {
2644       g_set_error (error, G_IO_ERROR,
2645                    G_IO_ERROR_NOT_SUPPORTED,
2646                    _("Operation not supported"));
2647       return FALSE;
2648     }
2649
2650   return (* iface->set_attribute) (file, attribute, type, value_p, flags, cancellable, error);
2651 }
2652
2653 /**
2654  * g_file_set_attributes_from_info:
2655  * @file: input #GFile.
2656  * @info: a #GFileInfo.
2657  * @flags: #GFileQueryInfoFlags
2658  * @cancellable: optional #GCancellable object, %NULL to ignore.
2659  * @error: a #GError, or %NULL 
2660  * 
2661  * Tries to set all attributes in the #GFileInfo on the target values, 
2662  * not stopping on the first error.
2663  * 
2664  * If there is any error during this operation then @error will be set to
2665  * the first error. Error on particular fields are flagged by setting 
2666  * the "status" field in the attribute value to 
2667  * %G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING, which means you can also detect
2668  * further errors.
2669  *
2670  * If @cancellable is not %NULL, then the operation can be cancelled by
2671  * triggering the cancellable object from another thread. If the operation
2672  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2673  * 
2674  * Returns: %TRUE if there was any error, %FALSE otherwise.
2675  **/
2676 gboolean
2677 g_file_set_attributes_from_info (GFile                *file,
2678                                  GFileInfo            *info,
2679                                  GFileQueryInfoFlags   flags,
2680                                  GCancellable         *cancellable,
2681                                  GError              **error)
2682 {
2683   GFileIface *iface;
2684
2685   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2686   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
2687
2688   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2689     return FALSE;
2690   
2691   g_file_info_clear_status (info);
2692   
2693   iface = G_FILE_GET_IFACE (file);
2694
2695   return (* iface->set_attributes_from_info) (file, 
2696                                               info, 
2697                                               flags, 
2698                                               cancellable, 
2699                                               error);
2700 }
2701
2702
2703 static gboolean
2704 g_file_real_set_attributes_from_info (GFile                *file,
2705                                       GFileInfo            *info,
2706                                       GFileQueryInfoFlags   flags,
2707                                       GCancellable         *cancellable,
2708                                       GError              **error)
2709 {
2710   char **attributes;
2711   int i;
2712   gboolean res;
2713   GFileAttributeValue *value;
2714   
2715   res = TRUE;
2716   
2717   attributes = g_file_info_list_attributes (info, NULL);
2718
2719   for (i = 0; attributes[i] != NULL; i++)
2720     {
2721       value = _g_file_info_get_attribute_value (info, attributes[i]);
2722
2723       if (value->status != G_FILE_ATTRIBUTE_STATUS_UNSET)
2724         continue;
2725
2726       if (!g_file_set_attribute (file, attributes[i],
2727                                  value->type, _g_file_attribute_value_peek_as_pointer (value),
2728                                  flags, cancellable, error))
2729         {
2730           value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING;
2731           res = FALSE;
2732           /* Don't set error multiple times */
2733           error = NULL;
2734         }
2735       else
2736         value->status = G_FILE_ATTRIBUTE_STATUS_SET;
2737     }
2738   
2739   g_strfreev (attributes);
2740   
2741   return res;
2742 }
2743
2744 /**
2745  * g_file_set_attributes_async:
2746  * @file: input #GFile.
2747  * @info: a #GFileInfo.
2748  * @flags: a #GFileQueryInfoFlags.
2749  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
2750  *     of the request. 
2751  * @cancellable: optional #GCancellable object, %NULL to ignore.
2752  * @callback: a #GAsyncReadyCallback. 
2753  * @user_data: a #gpointer.
2754  *
2755  * Asynchronously sets the attributes of @file with @info.
2756  * 
2757  * For more details, see g_file_set_attributes_from_info() which is
2758  * the synchronous version of this call.
2759  *
2760  * When the operation is finished, @callback will be called. You can then call
2761  * g_file_set_attributes_finish() to get the result of the operation.
2762  **/
2763 void
2764 g_file_set_attributes_async (GFile               *file,
2765                              GFileInfo           *info,
2766                              GFileQueryInfoFlags  flags,
2767                              int                  io_priority,
2768                              GCancellable        *cancellable,
2769                              GAsyncReadyCallback  callback,
2770                              gpointer             user_data)
2771 {
2772   GFileIface *iface;
2773   
2774   g_return_if_fail (G_IS_FILE (file));
2775   g_return_if_fail (G_IS_FILE_INFO (info));
2776
2777   iface = G_FILE_GET_IFACE (file);
2778   (* iface->set_attributes_async) (file, 
2779                                    info, 
2780                                    flags, 
2781                                    io_priority, 
2782                                    cancellable, 
2783                                    callback, 
2784                                    user_data);
2785 }
2786
2787 /**
2788  * g_file_set_attributes_finish:
2789  * @file: input #GFile.
2790  * @result: a #GAsyncResult.
2791  * @info: a #GFileInfo.
2792  * @error: a #GError, or %NULL
2793  * 
2794  * Finishes setting an attribute started in g_file_set_attributes_async().
2795  * 
2796  * Returns: %TRUE if the attributes were set correctly, %FALSE otherwise.
2797  **/
2798 gboolean
2799 g_file_set_attributes_finish (GFile         *file,
2800                               GAsyncResult  *result,
2801                               GFileInfo    **info,
2802                               GError       **error)
2803 {
2804   GFileIface *iface;
2805   
2806   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2807   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
2808
2809   /* No standard handling of errors here, as we must set info even
2810    * on errors 
2811    */
2812   iface = G_FILE_GET_IFACE (file);
2813   return (* iface->set_attributes_finish) (file, result, info, error);
2814 }
2815
2816 /**
2817  * g_file_set_attribute_string:
2818  * @file: input #GFile.
2819  * @attribute: a string containing the attribute's name.
2820  * @value: a string containing the attribute's value.
2821  * @flags: #GFileQueryInfoFlags.
2822  * @cancellable: optional #GCancellable object, %NULL to ignore.
2823  * @error: a #GError, or %NULL
2824  * 
2825  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_STRING to @value. 
2826  * If @attribute is of a different type, this operation will fail.
2827  * 
2828  * If @cancellable is not %NULL, then the operation can be cancelled by
2829  * triggering the cancellable object from another thread. If the operation
2830  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2831  * 
2832  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
2833  **/
2834 gboolean
2835 g_file_set_attribute_string (GFile                *file,
2836                              const char           *attribute,
2837                              const char           *value,
2838                              GFileQueryInfoFlags   flags,
2839                              GCancellable         *cancellable,
2840                              GError              **error)
2841 {
2842   return g_file_set_attribute (file, attribute,
2843                                G_FILE_ATTRIBUTE_TYPE_STRING, (gpointer)value,
2844                                flags, cancellable, error);
2845 }
2846
2847 /**
2848  * g_file_set_attribute_byte_string:
2849  * @file: input #GFile.
2850  * @attribute: a string containing the attribute's name.
2851  * @value: a string containing the attribute's new value.
2852  * @flags: a #GFileQueryInfoFlags.
2853  * @cancellable: optional #GCancellable object, %NULL to ignore.
2854  * @error: a #GError, or %NULL
2855  * 
2856  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING to @value. 
2857  * If @attribute is of a different type, this operation will fail, 
2858  * returning %FALSE. 
2859  * 
2860  * If @cancellable is not %NULL, then the operation can be cancelled by
2861  * triggering the cancellable object from another thread. If the operation
2862  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2863  * 
2864  * Returns: %TRUE if the @attribute was successfully set to @value 
2865  * in the @file, %FALSE otherwise.
2866  **/
2867 gboolean
2868 g_file_set_attribute_byte_string  (GFile                *file,
2869                                    const char           *attribute,
2870                                    const char           *value,
2871                                    GFileQueryInfoFlags   flags,
2872                                    GCancellable         *cancellable,
2873                                    GError              **error)
2874 {
2875   return g_file_set_attribute (file, attribute,
2876                                G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, (gpointer)value,
2877                                flags, cancellable, error);
2878 }
2879
2880 /**
2881  * g_file_set_attribute_uint32:
2882  * @file: input #GFile.
2883  * @attribute: a string containing the attribute's name.
2884  * @value: a #guint32 containing the attribute's new value.
2885  * @flags: a #GFileQueryInfoFlags.
2886  * @cancellable: optional #GCancellable object, %NULL to ignore.
2887  * @error: a #GError, or %NULL
2888  * 
2889  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT32 to @value. 
2890  * If @attribute is of a different type, this operation will fail.
2891  * 
2892  * If @cancellable is not %NULL, then the operation can be cancelled by
2893  * triggering the cancellable object from another thread. If the operation
2894  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2895  * 
2896  * Returns: %TRUE if the @attribute was successfully set to @value 
2897  * in the @file, %FALSE otherwise.
2898  **/
2899 gboolean
2900 g_file_set_attribute_uint32 (GFile                *file,
2901                              const char           *attribute,
2902                              guint32               value,
2903                              GFileQueryInfoFlags   flags,
2904                              GCancellable         *cancellable,
2905                              GError              **error)
2906 {
2907   return g_file_set_attribute (file, attribute,
2908                                G_FILE_ATTRIBUTE_TYPE_UINT32, &value,
2909                                flags, cancellable, error);
2910 }
2911
2912 /**
2913  * g_file_set_attribute_int32:
2914  * @file: input #GFile.
2915  * @attribute: a string containing the attribute's name.
2916  * @value: a #gint32 containing the attribute's new value.
2917  * @flags: a #GFileQueryInfoFlags.
2918  * @cancellable: optional #GCancellable object, %NULL to ignore.
2919  * @error: a #GError, or %NULL
2920  * 
2921  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT32 to @value. 
2922  * If @attribute is of a different type, this operation will fail.
2923  * 
2924  * If @cancellable is not %NULL, then the operation can be cancelled by
2925  * triggering the cancellable object from another thread. If the operation
2926  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2927  * 
2928  * Returns: %TRUE if the @attribute was successfully set to @value 
2929  * in the @file, %FALSE otherwise. 
2930  **/
2931 gboolean
2932 g_file_set_attribute_int32 (GFile                *file,
2933                             const char           *attribute,
2934                             gint32                value,
2935                             GFileQueryInfoFlags   flags,
2936                             GCancellable         *cancellable,
2937                             GError              **error)
2938 {
2939   return g_file_set_attribute (file, attribute,
2940                                G_FILE_ATTRIBUTE_TYPE_INT32, &value,
2941                                flags, cancellable, error);
2942 }
2943
2944 /**
2945  * g_file_set_attribute_uint64:
2946  * @file: input #GFile. 
2947  * @attribute: a string containing the attribute's name.
2948  * @value: a #guint64 containing the attribute's new value.
2949  * @flags: a #GFileQueryInfoFlags.
2950  * @cancellable: optional #GCancellable object, %NULL to ignore.
2951  * @error: a #GError, or %NULL
2952  * 
2953  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT64 to @value. 
2954  * If @attribute is of a different type, this operation will fail.
2955  * 
2956  * If @cancellable is not %NULL, then the operation can be cancelled by
2957  * triggering the cancellable object from another thread. If the operation
2958  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2959  * 
2960  * Returns: %TRUE if the @attribute was successfully set to @value 
2961  * in the @file, %FALSE otherwise.
2962  **/
2963 gboolean
2964 g_file_set_attribute_uint64 (GFile                *file,
2965                              const char           *attribute,
2966                              guint64               value,
2967                              GFileQueryInfoFlags   flags,
2968                              GCancellable         *cancellable,
2969                              GError              **error)
2970  {
2971   return g_file_set_attribute (file, attribute,
2972                                G_FILE_ATTRIBUTE_TYPE_UINT64, &value,
2973                                flags, cancellable, error);
2974 }
2975
2976 /**
2977  * g_file_set_attribute_int64:
2978  * @file: input #GFile.
2979  * @attribute: a string containing the attribute's name.
2980  * @value: a #guint64 containing the attribute's new value.
2981  * @flags: a #GFileQueryInfoFlags.
2982  * @cancellable: optional #GCancellable object, %NULL to ignore.
2983  * @error: a #GError, or %NULL
2984  * 
2985  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT64 to @value. 
2986  * If @attribute is of a different type, this operation will fail.
2987  * 
2988  * If @cancellable is not %NULL, then the operation can be cancelled by
2989  * triggering the cancellable object from another thread. If the operation
2990  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2991  * 
2992  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
2993  **/
2994 gboolean
2995 g_file_set_attribute_int64 (GFile                *file,
2996                             const char           *attribute,
2997                             gint64                value,
2998                             GFileQueryInfoFlags   flags,
2999                             GCancellable         *cancellable,
3000                             GError              **error)
3001 {
3002   return g_file_set_attribute (file, attribute,
3003                                G_FILE_ATTRIBUTE_TYPE_INT64, &value,
3004                                flags, cancellable, error);
3005 }
3006
3007 /**
3008  * g_file_mount_mountable:
3009  * @file: input #GFile.
3010  * @mount_operation: a #GMountOperation, or %NULL to avoid user interaction.
3011  * @cancellable: optional #GCancellable object, %NULL to ignore.
3012  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
3013  * @user_data: the data to pass to callback function
3014  * 
3015  * Mounts a file of type G_FILE_TYPE_MOUNTABLE.
3016  * Using @mount_operation, you can request callbacks when, for instance, 
3017  * passwords are needed during authentication.
3018  *
3019  * If @cancellable is not %NULL, then the operation can be cancelled by
3020  * triggering the cancellable object from another thread. If the operation
3021  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3022  *
3023  * When the operation is finished, @callback will be called. You can then call
3024  * g_file_mount_mountable_finish() to get the result of the operation.
3025  **/
3026 void
3027 g_file_mount_mountable (GFile               *file,
3028                         GMountOperation     *mount_operation,
3029                         GCancellable        *cancellable,
3030                         GAsyncReadyCallback  callback,
3031                         gpointer             user_data)
3032 {
3033   GFileIface *iface;
3034
3035   g_return_if_fail (G_IS_FILE (file));
3036
3037   iface = G_FILE_GET_IFACE (file);
3038
3039   if (iface->mount_mountable == NULL)
3040     g_simple_async_report_error_in_idle (G_OBJECT (file),
3041                                          callback,
3042                                          user_data,
3043                                          G_IO_ERROR,
3044                                          G_IO_ERROR_NOT_SUPPORTED,
3045                                          _("Operation not supported"));
3046   
3047   (* iface->mount_mountable) (file,
3048                               mount_operation,
3049                               cancellable,
3050                               callback,
3051                               user_data);
3052 }
3053
3054 /**
3055  * g_file_mount_mountable_finish:
3056  * @file: input #GFile.
3057  * @result: a #GAsyncResult.
3058  * @error: a #GError, or %NULL
3059  *
3060  * Finishes a mount operation. See g_file_mount_mountable() for details.
3061  * 
3062  * Finish an asynchronous mount operation that was started 
3063  * with g_file_mount_mountable().
3064  *
3065  * Returns: a #GFile or %NULL on error.
3066  **/
3067 GFile *
3068 g_file_mount_mountable_finish (GFile         *file,
3069                                GAsyncResult  *result,
3070                                GError       **error)
3071 {
3072   GFileIface *iface;
3073
3074   g_return_val_if_fail (G_IS_FILE (file), NULL);
3075   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
3076
3077   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3078     {
3079       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3080       if (g_simple_async_result_propagate_error (simple, error))
3081         return NULL;
3082     }
3083   
3084   iface = G_FILE_GET_IFACE (file);
3085   return (* iface->mount_mountable_finish) (file, result, error);
3086 }
3087
3088 /**
3089  * g_file_unmount_mountable:
3090  * @file: input #GFile.
3091  * @flags: flags affecting the operation
3092  * @cancellable: optional #GCancellable object, %NULL to ignore.
3093  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
3094  * @user_data: the data to pass to callback function
3095  *
3096  * Unmounts a file of type G_FILE_TYPE_MOUNTABLE.
3097  *
3098  * If @cancellable is not %NULL, then the operation can be cancelled by
3099  * triggering the cancellable object from another thread. If the operation
3100  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3101  *
3102  * When the operation is finished, @callback will be called. You can then call
3103  * g_file_unmount_mountable_finish() to get the result of the operation.
3104  **/
3105 void
3106 g_file_unmount_mountable (GFile               *file,
3107                           GMountUnmountFlags   flags,
3108                           GCancellable        *cancellable,
3109                           GAsyncReadyCallback  callback,
3110                           gpointer             user_data)
3111 {
3112   GFileIface *iface;
3113   
3114   g_return_if_fail (G_IS_FILE (file));
3115
3116   iface = G_FILE_GET_IFACE (file);
3117   
3118   if (iface->unmount_mountable == NULL)
3119     g_simple_async_report_error_in_idle (G_OBJECT (file),
3120                                          callback,
3121                                          user_data,
3122                                          G_IO_ERROR,
3123                                          G_IO_ERROR_NOT_SUPPORTED,
3124                                          _("Operation not supported"));
3125   
3126   (* iface->unmount_mountable) (file,
3127                                 flags,
3128                                 cancellable,
3129                                 callback,
3130                                 user_data);
3131 }
3132
3133 /**
3134  * g_file_unmount_mountable_finish:
3135  * @file: input #GFile.
3136  * @result: a #GAsyncResult.
3137  * @error: a #GError, or %NULL
3138  *
3139  * Finishes an unmount operation, see g_file_unmount_mountable() for details.
3140  * 
3141  * Finish an asynchronous unmount operation that was started 
3142  * with g_file_unmount_mountable().
3143  *
3144  * Returns: %TRUE if the operation finished successfully. %FALSE
3145  * otherwise.
3146  **/
3147 gboolean
3148 g_file_unmount_mountable_finish (GFile         *file,
3149                                  GAsyncResult  *result,
3150                                  GError       **error)
3151 {
3152   GFileIface *iface;
3153   
3154   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3155   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3156
3157   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3158     {
3159       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3160       if (g_simple_async_result_propagate_error (simple, error))
3161         return FALSE;
3162     }
3163   
3164   iface = G_FILE_GET_IFACE (file);
3165   return (* iface->unmount_mountable_finish) (file, result, error);
3166 }
3167
3168 /**
3169  * g_file_eject_mountable:
3170  * @file: input #GFile.
3171  * @flags: flags affecting the operation
3172  * @cancellable: optional #GCancellable object, %NULL to ignore.
3173  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
3174  * @user_data: the data to pass to callback function
3175  * 
3176  * Starts an asynchronous eject on a mountable.  
3177  * When this operation has completed, @callback will be called with
3178  * @user_user data, and the operation can be finalized with 
3179  * g_file_eject_mountable_finish().
3180  * 
3181  * If @cancellable is not %NULL, then the operation can be cancelled by
3182  * triggering the cancellable object from another thread. If the operation
3183  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3184  **/
3185 void
3186 g_file_eject_mountable (GFile               *file,
3187                         GMountUnmountFlags   flags,
3188                         GCancellable        *cancellable,
3189                         GAsyncReadyCallback  callback,
3190                         gpointer             user_data)
3191 {
3192   GFileIface *iface;
3193
3194   g_return_if_fail (G_IS_FILE (file));
3195
3196   iface = G_FILE_GET_IFACE (file);
3197   
3198   if (iface->eject_mountable == NULL)
3199     g_simple_async_report_error_in_idle (G_OBJECT (file),
3200                                          callback,
3201                                          user_data,
3202                                          G_IO_ERROR,
3203                                          G_IO_ERROR_NOT_SUPPORTED,
3204                                          _("Operation not supported"));
3205   
3206   (* iface->eject_mountable) (file,
3207                               flags,
3208                               cancellable,
3209                               callback,
3210                               user_data);
3211 }
3212
3213 /**
3214  * g_file_eject_mountable_finish:
3215  * @file: input #GFile.
3216  * @result: a #GAsyncResult.
3217  * @error: a #GError, or %NULL
3218  * 
3219  * Finishes an asynchronous eject operation started by 
3220  * g_file_eject_mountable().
3221  * 
3222  * Returns: %TRUE if the @file was ejected successfully. %FALSE 
3223  * otherwise.
3224  **/
3225 gboolean
3226 g_file_eject_mountable_finish (GFile         *file,
3227                                GAsyncResult  *result,
3228                                GError       **error)
3229 {
3230   GFileIface *iface;
3231   
3232   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3233   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3234
3235   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3236     {
3237       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3238       if (g_simple_async_result_propagate_error (simple, error))
3239         return FALSE;
3240     }
3241   
3242   iface = G_FILE_GET_IFACE (file);
3243   return (* iface->eject_mountable_finish) (file, result, error);
3244 }
3245
3246 /**
3247  * g_file_monitor_directory:
3248  * @file: input #GFile.
3249  * @flags: a set of #GFileMonitorFlags.
3250  * @cancellable: optional #GCancellable object, %NULL to ignore.
3251  * 
3252  * Obtains a directory monitor for the given file.
3253  * This may fail if directory monitoring is not supported.
3254  *
3255  * If @cancellable is not %NULL, then the operation can be cancelled by
3256  * triggering the cancellable object from another thread. If the operation
3257  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3258  * 
3259  * Returns: a #GFileMonitor for the given @file, 
3260  * or %NULL on error.
3261  **/
3262 GFileMonitor*
3263 g_file_monitor_directory (GFile             *file,
3264                           GFileMonitorFlags  flags,
3265                           GCancellable      *cancellable)
3266 {
3267   GFileIface *iface;
3268
3269   g_return_val_if_fail (G_IS_FILE (file), NULL);
3270
3271   iface = G_FILE_GET_IFACE (file);
3272
3273   if (iface->monitor_dir == NULL)
3274     return NULL;
3275
3276   return (* iface->monitor_dir) (file, flags, cancellable);
3277 }
3278
3279 /**
3280  * g_file_monitor_file:
3281  * @file: input #GFile.
3282  * @flags: a set of #GFileMonitorFlags.
3283  * @cancellable: optional #GCancellable object, %NULL to ignore.
3284  * 
3285  * Obtains a file monitor for the given file. If no file notification
3286  * mechanism exists, then regular polling of the file is used.
3287  *
3288  * If @cancellable is not %NULL, then the operation can be cancelled by
3289  * triggering the cancellable object from another thread. If the operation
3290  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3291  * 
3292  * Returns: a #GFileMonitor for the given @file.
3293  **/
3294 GFileMonitor*
3295 g_file_monitor_file (GFile             *file,
3296                      GFileMonitorFlags  flags,
3297                      GCancellable      *cancellable)
3298 {
3299   GFileIface *iface;
3300   GFileMonitor *monitor;
3301   
3302   g_return_val_if_fail (G_IS_FILE (file), NULL);
3303
3304   iface = G_FILE_GET_IFACE (file);
3305
3306   monitor = NULL;
3307   
3308   if (iface->monitor_file)
3309     monitor = (* iface->monitor_file) (file, flags, cancellable);
3310
3311 /* Fallback to polling */
3312   if (monitor == NULL)
3313     monitor = _g_poll_file_monitor_new (file);
3314
3315   return monitor;
3316 }
3317
3318 /********************************************
3319  *   Default implementation of async ops    *
3320  ********************************************/
3321
3322 typedef struct {
3323   char *attributes;
3324   GFileQueryInfoFlags flags;
3325   GFileInfo *info;
3326 } QueryInfoAsyncData;
3327
3328 static void
3329 query_info_data_free (QueryInfoAsyncData *data)
3330 {
3331   if (data->info)
3332     g_object_unref (data->info);
3333   g_free (data->attributes);
3334   g_free (data);
3335 }
3336
3337 static void
3338 query_info_async_thread (GSimpleAsyncResult *res,
3339                          GObject            *object,
3340                          GCancellable       *cancellable)
3341 {
3342   GError *error = NULL;
3343   QueryInfoAsyncData *data;
3344   GFileInfo *info;
3345   
3346   data = g_simple_async_result_get_op_res_gpointer (res);
3347   
3348   info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error);
3349
3350   if (info == NULL)
3351     {
3352       g_simple_async_result_set_from_error (res, error);
3353       g_error_free (error);
3354     }
3355   else
3356     data->info = info;
3357 }
3358
3359 static void
3360 g_file_real_query_info_async (GFile               *file,
3361                               const char          *attributes,
3362                               GFileQueryInfoFlags  flags,
3363                               int                  io_priority,
3364                               GCancellable        *cancellable,
3365                               GAsyncReadyCallback  callback,
3366                               gpointer             user_data)
3367 {
3368   GSimpleAsyncResult *res;
3369   QueryInfoAsyncData *data;
3370
3371   data = g_new0 (QueryInfoAsyncData, 1);
3372   data->attributes = g_strdup (attributes);
3373   data->flags = flags;
3374   
3375   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_info_async);
3376   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_info_data_free);
3377   
3378   g_simple_async_result_run_in_thread (res, query_info_async_thread, io_priority, cancellable);
3379   g_object_unref (res);
3380 }
3381
3382 static GFileInfo *
3383 g_file_real_query_info_finish (GFile         *file,
3384                                GAsyncResult  *res,
3385                                GError       **error)
3386 {
3387   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3388   QueryInfoAsyncData *data;
3389
3390   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_info_async);
3391
3392   data = g_simple_async_result_get_op_res_gpointer (simple);
3393   if (data->info)
3394     return g_object_ref (data->info);
3395   
3396   return NULL;
3397 }
3398
3399 typedef struct {
3400   char *attributes;
3401   GFileQueryInfoFlags flags;
3402   GFileEnumerator *enumerator;
3403 } EnumerateChildrenAsyncData;
3404
3405 static void
3406 enumerate_children_data_free (EnumerateChildrenAsyncData *data)
3407 {
3408   if (data->enumerator)
3409     g_object_unref (data->enumerator);
3410   g_free (data->attributes);
3411   g_free (data);
3412 }
3413
3414 static void
3415 enumerate_children_async_thread (GSimpleAsyncResult *res,
3416                                  GObject            *object,
3417                                  GCancellable       *cancellable)
3418 {
3419   GError *error = NULL;
3420   EnumerateChildrenAsyncData *data;
3421   GFileEnumerator *enumerator;
3422   
3423   data = g_simple_async_result_get_op_res_gpointer (res);
3424   
3425   enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error);
3426
3427   if (enumerator == NULL)
3428     {
3429       g_simple_async_result_set_from_error (res, error);
3430       g_error_free (error);
3431     }
3432   else
3433     data->enumerator = enumerator;
3434 }
3435
3436 static void
3437 g_file_real_enumerate_children_async (GFile               *file,
3438                                       const char          *attributes,
3439                                       GFileQueryInfoFlags  flags,
3440                                       int                  io_priority,
3441                                       GCancellable        *cancellable,
3442                                       GAsyncReadyCallback  callback,
3443                                       gpointer             user_data)
3444 {
3445   GSimpleAsyncResult *res;
3446   EnumerateChildrenAsyncData *data;
3447
3448   data = g_new0 (EnumerateChildrenAsyncData, 1);
3449   data->attributes = g_strdup (attributes);
3450   data->flags = flags;
3451   
3452   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_enumerate_children_async);
3453   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)enumerate_children_data_free);
3454   
3455   g_simple_async_result_run_in_thread (res, enumerate_children_async_thread, io_priority, cancellable);
3456   g_object_unref (res);
3457 }
3458
3459 static GFileEnumerator *
3460 g_file_real_enumerate_children_finish (GFile         *file,
3461                                        GAsyncResult  *res,
3462                                        GError       **error)
3463 {
3464   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3465   EnumerateChildrenAsyncData *data;
3466
3467   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_enumerate_children_async);
3468
3469   data = g_simple_async_result_get_op_res_gpointer (simple);
3470   if (data->enumerator)
3471     return g_object_ref (data->enumerator);
3472   
3473   return NULL;
3474 }
3475
3476 static void
3477 open_read_async_thread (GSimpleAsyncResult *res,
3478                         GObject            *object,
3479                         GCancellable       *cancellable)
3480 {
3481   GFileIface *iface;
3482   GFileInputStream *stream;
3483   GError *error = NULL;
3484
3485   iface = G_FILE_GET_IFACE (object);
3486
3487   stream = iface->read_fn (G_FILE (object), cancellable, &error);
3488
3489   if (stream == NULL)
3490     {
3491       g_simple_async_result_set_from_error (res, error);
3492       g_error_free (error);
3493     }
3494   else
3495     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
3496 }
3497
3498 static void
3499 g_file_real_read_async (GFile               *file,
3500                         int                  io_priority,
3501                         GCancellable        *cancellable,
3502                         GAsyncReadyCallback  callback,
3503                         gpointer             user_data)
3504 {
3505   GSimpleAsyncResult *res;
3506   
3507   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_read_async);
3508   
3509   g_simple_async_result_run_in_thread (res, open_read_async_thread, io_priority, cancellable);
3510   g_object_unref (res);
3511 }
3512
3513 static GFileInputStream *
3514 g_file_real_read_finish (GFile         *file,
3515                          GAsyncResult  *res,
3516                          GError       **error)
3517 {
3518   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3519   gpointer op;
3520
3521   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_read_async);
3522
3523   op = g_simple_async_result_get_op_res_gpointer (simple);
3524   if (op)
3525     return g_object_ref (op);
3526   
3527   return NULL;
3528 }
3529
3530 static void
3531 append_to_async_thread (GSimpleAsyncResult *res,
3532                         GObject            *object,
3533                         GCancellable       *cancellable)
3534 {
3535   GFileIface *iface;
3536   GFileCreateFlags *data;
3537   GFileOutputStream *stream;
3538   GError *error = NULL;
3539
3540   iface = G_FILE_GET_IFACE (object);
3541
3542   data = g_simple_async_result_get_op_res_gpointer (res);
3543
3544   stream = iface->append_to (G_FILE (object), *data, cancellable, &error);
3545
3546   if (stream == NULL)
3547     {
3548       g_simple_async_result_set_from_error (res, error);
3549       g_error_free (error);
3550     }
3551   else
3552     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
3553 }
3554
3555 static void
3556 g_file_real_append_to_async (GFile               *file,
3557                              GFileCreateFlags     flags,
3558                              int                  io_priority,
3559                              GCancellable        *cancellable,
3560                              GAsyncReadyCallback  callback,
3561                              gpointer             user_data)
3562 {
3563   GFileCreateFlags *data;
3564   GSimpleAsyncResult *res;
3565
3566   data = g_new0 (GFileCreateFlags, 1);
3567   *data = flags;
3568
3569   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_append_to_async);
3570   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
3571
3572   g_simple_async_result_run_in_thread (res, append_to_async_thread, io_priority, cancellable);
3573   g_object_unref (res);
3574 }
3575
3576 static GFileOutputStream *
3577 g_file_real_append_to_finish (GFile         *file,
3578                               GAsyncResult  *res,
3579                               GError       **error)
3580 {
3581   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3582   gpointer op;
3583
3584   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_append_to_async);
3585
3586   op = g_simple_async_result_get_op_res_gpointer (simple);
3587   if (op)
3588     return g_object_ref (op);
3589   
3590   return NULL;
3591 }
3592
3593 static void
3594 create_async_thread (GSimpleAsyncResult *res,
3595                      GObject            *object,
3596                      GCancellable       *cancellable)
3597 {
3598   GFileIface *iface;
3599   GFileCreateFlags *data;
3600   GFileOutputStream *stream;
3601   GError *error = NULL;
3602
3603   iface = G_FILE_GET_IFACE (object);
3604
3605   data = g_simple_async_result_get_op_res_gpointer (res);
3606
3607   stream = iface->create (G_FILE (object), *data, cancellable, &error);
3608
3609   if (stream == NULL)
3610     {
3611       g_simple_async_result_set_from_error (res, error);
3612       g_error_free (error);
3613     }
3614   else
3615     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
3616 }
3617
3618 static void
3619 g_file_real_create_async (GFile               *file,
3620                           GFileCreateFlags     flags,
3621                           int                  io_priority,
3622                           GCancellable        *cancellable,
3623                           GAsyncReadyCallback  callback,
3624                           gpointer             user_data)
3625 {
3626   GFileCreateFlags *data;
3627   GSimpleAsyncResult *res;
3628
3629   data = g_new0 (GFileCreateFlags, 1);
3630   *data = flags;
3631
3632   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_create_async);
3633   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
3634
3635   g_simple_async_result_run_in_thread (res, create_async_thread, io_priority, cancellable);
3636   g_object_unref (res);
3637 }
3638
3639 static GFileOutputStream *
3640 g_file_real_create_finish (GFile         *file,
3641                            GAsyncResult  *res,
3642                            GError       **error)
3643 {
3644   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3645   gpointer op;
3646
3647   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_create_async);
3648
3649   op = g_simple_async_result_get_op_res_gpointer (simple);
3650   if (op)
3651     return g_object_ref (op);
3652   
3653   return NULL;
3654 }
3655
3656 typedef struct {
3657   GFileOutputStream *stream;
3658   char *etag;
3659   gboolean make_backup;
3660   GFileCreateFlags flags;
3661 } ReplaceAsyncData;
3662
3663 static void
3664 replace_async_data_free (ReplaceAsyncData *data)
3665 {
3666   if (data->stream)
3667     g_object_unref (data->stream);
3668   g_free (data->etag);
3669   g_free (data);
3670 }
3671
3672 static void
3673 replace_async_thread (GSimpleAsyncResult *res,
3674                       GObject            *object,
3675                       GCancellable       *cancellable)
3676 {
3677   GFileIface *iface;
3678   GFileOutputStream *stream;
3679   GError *error = NULL;
3680   ReplaceAsyncData *data;
3681
3682   iface = G_FILE_GET_IFACE (object);
3683   
3684   data = g_simple_async_result_get_op_res_gpointer (res);
3685
3686   stream = iface->replace (G_FILE (object),
3687                            data->etag,
3688                            data->make_backup,
3689                            data->flags,
3690                            cancellable,
3691                            &error);
3692
3693   if (stream == NULL)
3694     {
3695       g_simple_async_result_set_from_error (res, error);
3696       g_error_free (error);
3697     }
3698   else
3699     data->stream = stream;
3700 }
3701
3702 static void
3703 g_file_real_replace_async (GFile               *file,
3704                            const char          *etag,
3705                            gboolean             make_backup,
3706                            GFileCreateFlags     flags,
3707                            int                  io_priority,
3708                            GCancellable        *cancellable,
3709                            GAsyncReadyCallback  callback,
3710                            gpointer             user_data)
3711 {
3712   GSimpleAsyncResult *res;
3713   ReplaceAsyncData *data;
3714
3715   data = g_new0 (ReplaceAsyncData, 1);
3716   data->etag = g_strdup (etag);
3717   data->make_backup = make_backup;
3718   data->flags = flags;
3719
3720   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_replace_async);
3721   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_async_data_free);
3722
3723   g_simple_async_result_run_in_thread (res, replace_async_thread, io_priority, cancellable);
3724   g_object_unref (res);
3725 }
3726
3727 static GFileOutputStream *
3728 g_file_real_replace_finish (GFile         *file,
3729                             GAsyncResult  *res,
3730                             GError       **error)
3731 {
3732   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3733   ReplaceAsyncData *data;
3734
3735   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_replace_async);
3736
3737   data = g_simple_async_result_get_op_res_gpointer (simple);
3738   if (data->stream)
3739     return g_object_ref (data->stream);
3740   
3741   return NULL;
3742 }
3743
3744 typedef struct {
3745   char *name;
3746   GFile *file;
3747 } SetDisplayNameAsyncData;
3748
3749 static void
3750 set_display_name_data_free (SetDisplayNameAsyncData *data)
3751 {
3752   g_free (data->name);
3753   if (data->file)
3754     g_object_unref (data->file);
3755   g_free (data);
3756 }
3757
3758 static void
3759 set_display_name_async_thread (GSimpleAsyncResult *res,
3760                                GObject            *object,
3761                                GCancellable       *cancellable)
3762 {
3763   GError *error = NULL;
3764   SetDisplayNameAsyncData *data;
3765   GFile *file;
3766   
3767   data = g_simple_async_result_get_op_res_gpointer (res);
3768   
3769   file = g_file_set_display_name (G_FILE (object), data->name, cancellable, &error);
3770
3771   if (file == NULL)
3772     {
3773       g_simple_async_result_set_from_error (res, error);
3774       g_error_free (error);
3775     }
3776   else
3777     data->file = file;
3778 }
3779
3780 static void
3781 g_file_real_set_display_name_async (GFile               *file,  
3782                                     const char          *display_name,
3783                                     int                  io_priority,
3784                                     GCancellable        *cancellable,
3785                                     GAsyncReadyCallback  callback,
3786                                     gpointer             user_data)
3787 {
3788   GSimpleAsyncResult *res;
3789   SetDisplayNameAsyncData *data;
3790
3791   data = g_new0 (SetDisplayNameAsyncData, 1);
3792   data->name = g_strdup (display_name);
3793   
3794   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_display_name_async);
3795   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_display_name_data_free);
3796   
3797   g_simple_async_result_run_in_thread (res, set_display_name_async_thread, io_priority, cancellable);
3798   g_object_unref (res);
3799 }
3800
3801 static GFile *
3802 g_file_real_set_display_name_finish (GFile         *file,
3803                                      GAsyncResult  *res,
3804                                      GError       **error)
3805 {
3806   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3807   SetDisplayNameAsyncData *data;
3808
3809   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_display_name_async);
3810
3811   data = g_simple_async_result_get_op_res_gpointer (simple);
3812   if (data->file)
3813     return g_object_ref (data->file);
3814   
3815   return NULL;
3816 }
3817
3818 typedef struct {
3819   GFileQueryInfoFlags flags;
3820   GFileInfo *info;
3821   gboolean res;
3822   GError *error;
3823 } SetInfoAsyncData;
3824
3825 static void
3826 set_info_data_free (SetInfoAsyncData *data)
3827 {
3828   if (data->info)
3829     g_object_unref (data->info);
3830   if (data->error)
3831     g_error_free (data->error);
3832   g_free (data);
3833 }
3834
3835 static void
3836 set_info_async_thread (GSimpleAsyncResult *res,
3837                        GObject            *object,
3838                        GCancellable       *cancellable)
3839 {
3840   SetInfoAsyncData *data;
3841   
3842   data = g_simple_async_result_get_op_res_gpointer (res);
3843   
3844   data->error = NULL;
3845   data->res = g_file_set_attributes_from_info (G_FILE (object),
3846                                                data->info,
3847                                                data->flags,
3848                                                cancellable,
3849                                                &data->error);
3850 }
3851
3852 static void
3853 g_file_real_set_attributes_async (GFile               *file,
3854                                   GFileInfo           *info,
3855                                   GFileQueryInfoFlags  flags,
3856                                   int                  io_priority,
3857                                   GCancellable        *cancellable,
3858                                   GAsyncReadyCallback  callback,
3859                                   gpointer             user_data)
3860 {
3861   GSimpleAsyncResult *res;
3862   SetInfoAsyncData *data;
3863
3864   data = g_new0 (SetInfoAsyncData, 1);
3865   data->info = g_file_info_dup (info);
3866   data->flags = flags;
3867   
3868   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_attributes_async);
3869   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_info_data_free);
3870   
3871   g_simple_async_result_run_in_thread (res, set_info_async_thread, io_priority, cancellable);
3872   g_object_unref (res);
3873 }
3874
3875 static gboolean
3876 g_file_real_set_attributes_finish (GFile         *file,
3877                                    GAsyncResult  *res,
3878                                    GFileInfo    **info,
3879                                    GError       **error)
3880 {
3881   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3882   SetInfoAsyncData *data;
3883   
3884   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_attributes_async);
3885
3886   data = g_simple_async_result_get_op_res_gpointer (simple);
3887
3888   if (info) 
3889     *info = g_object_ref (data->info);
3890
3891   if (error != NULL && data->error) 
3892     *error = g_error_copy (data->error);
3893   
3894   return data->res;
3895 }
3896
3897 /********************************************
3898  *   Default VFS operations                 *
3899  ********************************************/
3900
3901 /**
3902  * g_file_new_for_path:
3903  * @path: a string containing a relative or absolute path.
3904  * 
3905  * Constructs a #GFile for a given path. This operation never
3906  * fails, but the returned object might not support any I/O
3907  * operation if @path is malformed.
3908  * 
3909  * Returns: a new #GFile for the given @path. 
3910  **/
3911 GFile *
3912 g_file_new_for_path (const char *path)
3913 {
3914   g_return_val_if_fail (path != NULL, NULL);
3915
3916   return g_vfs_get_file_for_path (g_vfs_get_default (), path);
3917 }
3918  
3919 /**
3920  * g_file_new_for_uri:
3921  * @uri: a string containing a URI.
3922  * 
3923  * Constructs a #GFile for a given URI. This operation never 
3924  * fails, but the returned object might not support any I/O 
3925  * operation if @uri is malformed or if the uri type is 
3926  * not supported.
3927  * 
3928  * Returns: a #GFile for the given @uri.
3929  **/ 
3930 GFile *
3931 g_file_new_for_uri (const char *uri)
3932 {
3933   g_return_val_if_fail (uri != NULL, NULL);
3934
3935   return g_vfs_get_file_for_uri (g_vfs_get_default (), uri);
3936 }
3937   
3938 /**
3939  * g_file_parse_name:
3940  * @parse_name: a file name or path to be parsed.
3941  * 
3942  * Constructs a #GFile with the given @parse_name (i.e. something given by g_file_get_parse_name()).
3943  * This operation never fails, but the returned object might not support any I/O
3944  * operation if the @parse_name cannot be parsed.
3945  * 
3946  * Returns: a new #GFile.
3947  **/
3948 GFile *
3949 g_file_parse_name (const char *parse_name)
3950 {
3951   g_return_val_if_fail (parse_name != NULL, NULL);
3952
3953   return g_vfs_parse_name (g_vfs_get_default (), parse_name);
3954 }
3955
3956 static gboolean
3957 is_valid_scheme_character (char c)
3958 {
3959   return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.';
3960 }
3961
3962 static gboolean
3963 has_valid_scheme (const char *uri)
3964 {
3965   const char *p;
3966   
3967   p = uri;
3968   
3969   if (!is_valid_scheme_character (*p))
3970     return FALSE;
3971
3972   do {
3973     p++;
3974   } while (is_valid_scheme_character (*p));
3975
3976   return *p == ':';
3977 }
3978
3979 /**
3980  * g_file_new_for_commandline_arg:
3981  * @arg: a command line string.
3982  * 
3983  * Creates a #GFile with the given argument from the command line. The value of
3984  * @arg can be either a URI, an absolute path or a relative path resolved
3985  * relative to the current working directory.
3986  * This operation never fails, but the returned object might not support any
3987  * I/O operation if @arg points to a malformed path.
3988  *
3989  * Returns: a new #GFile. 
3990  **/
3991 GFile *
3992 g_file_new_for_commandline_arg (const char *arg)
3993 {
3994   GFile *file;
3995   char *filename;
3996   char *current_dir;
3997   
3998   g_return_val_if_fail (arg != NULL, NULL);
3999   
4000   if (g_path_is_absolute (arg))
4001     return g_file_new_for_path (arg);
4002
4003   if (has_valid_scheme (arg))
4004     return g_file_new_for_uri (arg);
4005     
4006   current_dir = g_get_current_dir ();
4007   filename = g_build_filename (current_dir, arg, NULL);
4008   g_free (current_dir);
4009   
4010   file = g_file_new_for_path (filename);
4011   g_free (filename);
4012   
4013   return file;
4014 }
4015
4016 /**
4017  * g_file_mount_enclosing_volume:
4018  * @location: input #GFile.
4019  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
4020  * @cancellable: optional #GCancellable object, %NULL to ignore.
4021  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
4022  * @user_data: the data to pass to callback function
4023  * 
4024  * Starts a @mount_operation, mounting the volume that contains the file @location. 
4025  * 
4026  * When this operation has completed, @callback will be called with
4027  * @user_user data, and the operation can be finalized with 
4028  * g_file_mount_enclosing_volume_finish().
4029  * 
4030  * If @cancellable is not %NULL, then the operation can be cancelled by
4031  * triggering the cancellable object from another thread. If the operation
4032  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4033  **/
4034 void
4035 g_file_mount_enclosing_volume (GFile               *location,
4036                                GMountOperation     *mount_operation,
4037                                GCancellable        *cancellable,
4038                                GAsyncReadyCallback  callback,
4039                                gpointer             user_data)
4040 {
4041   GFileIface *iface;
4042
4043   g_return_if_fail (G_IS_FILE (location));
4044
4045   iface = G_FILE_GET_IFACE (location);
4046
4047   if (iface->mount_enclosing_volume == NULL)
4048     {
4049       g_simple_async_report_error_in_idle (G_OBJECT (location),
4050                                            callback, user_data,
4051                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
4052                                            _("volume doesn't implement mount"));
4053       
4054       return;
4055     }
4056   
4057   (* iface->mount_enclosing_volume) (location, mount_operation, cancellable, callback, user_data);
4058
4059 }
4060
4061 /**
4062  * g_file_mount_enclosing_volume_finish:
4063  * @location: input #GFile.
4064  * @result: a #GAsyncResult.
4065  * @error: a #GError, or %NULL
4066  * 
4067  * Finishes a mount operation started by g_file_mount_enclosing_volume().
4068  * 
4069  * Returns: %TRUE if successful. If an error
4070  * has occured, this function will return %FALSE and set @error
4071  * appropriately if present.
4072  **/
4073 gboolean
4074 g_file_mount_enclosing_volume_finish (GFile         *location,
4075                                       GAsyncResult  *result,
4076                                       GError       **error)
4077 {
4078   GFileIface *iface;
4079
4080   g_return_val_if_fail (G_IS_FILE (location), FALSE);
4081   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4082
4083   if (G_IS_SIMPLE_ASYNC_RESULT (result))
4084     {
4085       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
4086       if (g_simple_async_result_propagate_error (simple, error))
4087         return FALSE;
4088     }
4089   
4090   iface = G_FILE_GET_IFACE (location);
4091
4092   return (* iface->mount_enclosing_volume_finish) (location, result, error);
4093 }
4094
4095 /********************************************
4096  *   Utility functions                      *
4097  ********************************************/
4098
4099 #define GET_CONTENT_BLOCK_SIZE 8192
4100
4101 /**
4102  * g_file_load_contents:
4103  * @file: input #GFile.
4104  * @cancellable: optional #GCancellable object, %NULL to ignore.
4105  * @contents: a location to place the contents of the file.
4106  * @length: a location to place the length of the contents of the file.
4107  * @etag_out: a location to place the current entity tag for the file.
4108  * @error: a #GError, or %NULL
4109  *
4110  * Loads the content of the file into memory, returning the size of
4111  * the data. The data is always zero terminated, but this is not
4112  * included in the resultant @length.
4113  * 
4114  * If @cancellable is not %NULL, then the operation can be cancelled by
4115  * triggering the cancellable object from another thread. If the operation
4116  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4117  * 
4118  * Returns: %TRUE if the @file's contents were successfully loaded.
4119  * %FALSE if there were errors..
4120  **/
4121 gboolean
4122 g_file_load_contents (GFile         *file,
4123                       GCancellable  *cancellable,
4124                       char         **contents,
4125                       gsize         *length,
4126                       char         **etag_out,
4127                       GError       **error)
4128 {
4129   GFileInputStream *in;
4130   GByteArray *content;
4131   gsize pos;
4132   gssize res;
4133   GFileInfo *info;
4134
4135   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4136   g_return_val_if_fail (contents != NULL, FALSE);
4137
4138   in = g_file_read (file, cancellable, error);
4139   if (in == NULL)
4140     return FALSE;
4141
4142   content = g_byte_array_new ();
4143   pos = 0;
4144   
4145   g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
4146   while ((res = g_input_stream_read (G_INPUT_STREAM (in),
4147                                      content->data + pos,
4148                                      GET_CONTENT_BLOCK_SIZE,
4149                                      cancellable, error)) > 0)
4150     {
4151       pos += res;
4152       g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
4153     }
4154
4155   if (etag_out)
4156     {
4157       *etag_out = NULL;
4158       
4159       info = g_file_input_stream_query_info (in,
4160                                              G_FILE_ATTRIBUTE_ETAG_VALUE,
4161                                              cancellable,
4162                                              NULL);
4163       if (info)
4164         {
4165           *etag_out = g_strdup (g_file_info_get_etag (info));
4166           g_object_unref (info);
4167         }
4168     } 
4169
4170   /* Ignore errors on close */
4171   g_input_stream_close (G_INPUT_STREAM (in), cancellable, NULL);
4172   g_object_unref (in);
4173
4174   if (res < 0)
4175     {
4176       /* error is set already */
4177       g_byte_array_free (content, TRUE);
4178       return FALSE;
4179     }
4180
4181   if (length)
4182     *length = pos;
4183
4184   /* Zero terminate (we got an extra byte allocated for this */
4185   content->data[pos] = 0;
4186   
4187   *contents = (char *)g_byte_array_free (content, FALSE);
4188   
4189   return TRUE;
4190 }
4191
4192 typedef struct {
4193   GFile *file;
4194   GError *error;
4195   GCancellable *cancellable;
4196   GFileReadMoreCallback read_more_callback;
4197   GAsyncReadyCallback callback;
4198   gpointer user_data;
4199   GByteArray *content;
4200   gsize pos;
4201   char *etag;
4202 } LoadContentsData;
4203
4204
4205 static void
4206 load_contents_data_free (LoadContentsData *data)
4207 {
4208   if (data->error)
4209     g_error_free (data->error);
4210   if (data->cancellable)
4211     g_object_unref (data->cancellable);
4212   if (data->content)
4213     g_byte_array_free (data->content, TRUE);
4214   g_free (data->etag);
4215   g_object_unref (data->file);
4216   g_free (data);
4217 }
4218
4219 static void
4220 load_contents_close_callback (GObject      *obj,
4221                               GAsyncResult *close_res,
4222                               gpointer      user_data)
4223 {
4224   GInputStream *stream = G_INPUT_STREAM (obj);
4225   LoadContentsData *data = user_data;
4226   GSimpleAsyncResult *res;
4227
4228   /* Ignore errors here, we're only reading anyway */
4229   g_input_stream_close_finish (stream, close_res, NULL);
4230   g_object_unref (stream);
4231
4232   res = g_simple_async_result_new (G_OBJECT (data->file),
4233                                    data->callback,
4234                                    data->user_data,
4235                                    g_file_load_contents_async);
4236   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)load_contents_data_free);
4237   g_simple_async_result_complete (res);
4238   g_object_unref (res);
4239 }
4240
4241 static void
4242 load_contents_fstat_callback (GObject      *obj,
4243                               GAsyncResult *stat_res,
4244                               gpointer      user_data)
4245 {
4246   GInputStream *stream = G_INPUT_STREAM (obj);
4247   LoadContentsData *data = user_data;
4248   GFileInfo *info;
4249
4250   info = g_file_input_stream_query_info_finish (G_FILE_INPUT_STREAM (stream),
4251                                                    stat_res, NULL);
4252   if (info)
4253     {
4254       data->etag = g_strdup (g_file_info_get_etag (info));
4255       g_object_unref (info);
4256     }
4257
4258   g_input_stream_close_async (stream, 0,
4259                               data->cancellable,
4260                               load_contents_close_callback, data);
4261 }
4262
4263 static void
4264 load_contents_read_callback (GObject      *obj,
4265                              GAsyncResult *read_res,
4266                              gpointer      user_data)
4267 {
4268   GInputStream *stream = G_INPUT_STREAM (obj);
4269   LoadContentsData *data = user_data;
4270   GError *error = NULL;
4271   gssize read_size;
4272
4273   read_size = g_input_stream_read_finish (stream, read_res, &error);
4274
4275   if (read_size < 0) 
4276     {
4277       /* Error or EOF, close the file */
4278       data->error = error;
4279       g_input_stream_close_async (stream, 0,
4280                                   data->cancellable,
4281                                   load_contents_close_callback, data);
4282     }
4283   else if (read_size == 0)
4284     {
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     }
4292   else if (read_size > 0)
4293     {
4294       data->pos += read_size;
4295       
4296       g_byte_array_set_size (data->content,
4297                              data->pos + GET_CONTENT_BLOCK_SIZE);
4298
4299
4300       if (data->read_more_callback &&
4301           !data->read_more_callback ((char *)data->content->data, data->pos, data->user_data))
4302         g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
4303                                               G_FILE_ATTRIBUTE_ETAG_VALUE,
4304                                               0,
4305                                               data->cancellable,
4306                                               load_contents_fstat_callback,
4307                                               data);
4308       else 
4309         g_input_stream_read_async (stream,
4310                                    data->content->data + data->pos,
4311                                    GET_CONTENT_BLOCK_SIZE,
4312                                    0,
4313                                    data->cancellable,
4314                                    load_contents_read_callback,
4315                                    data);
4316     }
4317 }
4318
4319 static void
4320 load_contents_open_callback (GObject      *obj,
4321                              GAsyncResult *open_res,
4322                              gpointer      user_data)
4323 {
4324   GFile *file = G_FILE (obj);
4325   GFileInputStream *stream;
4326   LoadContentsData *data = user_data;
4327   GError *error = NULL;
4328   GSimpleAsyncResult *res;
4329
4330   stream = g_file_read_finish (file, open_res, &error);
4331
4332   if (stream)
4333     {
4334       g_byte_array_set_size (data->content,
4335                              data->pos + GET_CONTENT_BLOCK_SIZE);
4336       g_input_stream_read_async (G_INPUT_STREAM (stream),
4337                                  data->content->data + data->pos,
4338                                  GET_CONTENT_BLOCK_SIZE,
4339                                  0,
4340                                  data->cancellable,
4341                                  load_contents_read_callback,
4342                                  data);
4343       
4344     }
4345   else
4346     {
4347       res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
4348                                                   data->callback,
4349                                                   data->user_data,
4350                                                   error);
4351       g_simple_async_result_complete (res);
4352       g_error_free (error);
4353       load_contents_data_free (data);
4354       g_object_unref (res);
4355     }
4356 }
4357
4358 /**
4359  * g_file_load_partial_contents_async:
4360  * @file: input #GFile.
4361  * @cancellable: optional #GCancellable object, %NULL to ignore.
4362  * @read_more_callback: a #GFileReadMoreCallback to receive partial data and to specify whether further data should be read.
4363  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
4364  * @user_data: the data to pass to the callback functions.
4365  *
4366  * Reads the partial contents of a file. A #GFileReadMoreCallback should be 
4367  * used to stop reading from the file when appropriate, else this function
4368  * will behave exactly as g_file_load_contents_async(). This operation 
4369  * can be finished by g_file_load_partial_contents_finish().
4370  *
4371  * Users of this function should be aware that @user_data is passed to 
4372  * both the @read_more_callback and the @callback.
4373  *
4374  * If @cancellable is not %NULL, then the operation can be cancelled by
4375  * triggering the cancellable object from another thread. If the operation
4376  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4377  **/
4378 void
4379 g_file_load_partial_contents_async (GFile                 *file,
4380                                     GCancellable          *cancellable,
4381                                     GFileReadMoreCallback  read_more_callback,
4382                                     GAsyncReadyCallback    callback,
4383                                     gpointer               user_data)
4384 {
4385   LoadContentsData *data;
4386
4387   g_return_if_fail (G_IS_FILE (file));
4388
4389   data = g_new0 (LoadContentsData, 1);
4390
4391   if (cancellable)
4392     data->cancellable = g_object_ref (cancellable);
4393   data->read_more_callback = read_more_callback;
4394   data->callback = callback;
4395   data->user_data = user_data;
4396   data->content = g_byte_array_new ();
4397   data->file = g_object_ref (file);
4398
4399   g_file_read_async (file,
4400                      0,
4401                      cancellable,
4402                      load_contents_open_callback,
4403                      data);
4404 }
4405
4406 /**
4407  * g_file_load_partial_contents_finish:
4408  * @file: input #GFile.
4409  * @res: a #GAsyncResult. 
4410  * @contents: a location to place the contents of the file.
4411  * @length: a location to place the length of the contents of the file.
4412  * @etag_out: a location to place the current entity tag for the file.
4413  * @error: a #GError, or %NULL
4414  * 
4415  * Finishes an asynchronous partial load operation that was started
4416  * with g_file_load_partial_contents_async().
4417  *
4418  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
4419  * present, it will be set appropriately. 
4420  **/
4421 gboolean
4422 g_file_load_partial_contents_finish (GFile         *file,
4423                                      GAsyncResult  *res,
4424                                      char         **contents,
4425                                      gsize         *length,
4426                                      char         **etag_out,
4427                                      GError       **error)
4428 {
4429   GSimpleAsyncResult *simple;
4430   LoadContentsData *data;
4431
4432   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4433   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
4434   g_return_val_if_fail (contents != NULL, FALSE);
4435
4436   simple = G_SIMPLE_ASYNC_RESULT (res);
4437
4438   if (g_simple_async_result_propagate_error (simple, error))
4439     return FALSE;
4440   
4441   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_load_contents_async);
4442   
4443   data = g_simple_async_result_get_op_res_gpointer (simple);
4444
4445   if (data->error)
4446     {
4447       g_propagate_error (error, data->error);
4448       data->error = NULL;
4449       *contents = NULL;
4450       if (length)
4451         *length = 0;
4452       return FALSE;
4453     }
4454
4455   if (length)
4456     *length = data->pos;
4457
4458   if (etag_out)
4459     {
4460       *etag_out = data->etag;
4461       data->etag = NULL;
4462     }
4463
4464   /* Zero terminate */
4465   g_byte_array_set_size (data->content, data->pos + 1);
4466   data->content->data[data->pos] = 0;
4467   
4468   *contents = (char *)g_byte_array_free (data->content, FALSE);
4469   data->content = NULL;
4470
4471   return TRUE;
4472 }
4473
4474 /**
4475  * g_file_load_contents_async:
4476  * @file: input #GFile.
4477  * @cancellable: optional #GCancellable object, %NULL to ignore.
4478  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
4479  * @user_data: the data to pass to callback function
4480  * 
4481  * Starts an asynchronous load of the @file's contents.
4482  *
4483  * For more details, see g_file_load_contents() which is
4484  * the synchronous version of this call.
4485  *
4486  * When the load operation has completed, @callback will be called 
4487  * with @userdata. To finish the operation, call 
4488  * g_file_load_contents_finish() with the #GAsyncResult returned by 
4489  * the @callback.
4490  * 
4491  * If @cancellable is not %NULL, then the operation can be cancelled by
4492  * triggering the cancellable object from another thread. If the operation
4493  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4494  **/
4495 void
4496 g_file_load_contents_async (GFile               *file,
4497                            GCancellable        *cancellable,
4498                            GAsyncReadyCallback  callback,
4499                            gpointer             user_data)
4500 {
4501   g_file_load_partial_contents_async (file,
4502                                       cancellable,
4503                                       NULL,
4504                                       callback, user_data);
4505 }
4506
4507 /**
4508  * g_file_load_contents_finish:
4509  * @file: input #GFile.
4510  * @res: a #GAsyncResult. 
4511  * @contents: a location to place the contents of the file.
4512  * @length: a location to place the length of the contents of the file.
4513  * @etag_out: a location to place the current entity tag for the file.
4514  * @error: a #GError, or %NULL
4515  * 
4516  * Finishes an asynchronous load of the @file's contents. 
4517  * The contents are placed in @contents, and @length is set to the 
4518  * size of the @contents string. If @etag_out is present, it will be 
4519  * set to the new entity tag for the @file.
4520  * 
4521  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
4522  * present, it will be set appropriately. 
4523  **/
4524 gboolean
4525 g_file_load_contents_finish (GFile         *file,
4526                              GAsyncResult  *res,
4527                              char         **contents,
4528                              gsize         *length,
4529                              char         **etag_out,
4530                              GError       **error)
4531 {
4532   return g_file_load_partial_contents_finish (file,
4533                                               res,
4534                                               contents,
4535                                               length,
4536                                               etag_out,
4537                                               error);
4538 }
4539   
4540 /**
4541  * g_file_replace_contents:
4542  * @file: input #GFile.
4543  * @contents: a string containing the new contents for @file.
4544  * @length: the length of @contents in bytes.
4545  * @etag: the old <link linkend="gfile-etag">entity tag</link> 
4546  *     for the document.
4547  * @make_backup: %TRUE if a backup should be created.
4548  * @flags: a set of #GFileCreateFlags.
4549  * @new_etag: a location to a new <link linkend="gfile-etag">entity tag</link>
4550  *      for the document.
4551  * @cancellable: optional #GCancellable object, %NULL to ignore.
4552  * @error: a #GError, or %NULL
4553  *
4554  * Replaces the contents of @file with @contents of @length bytes.
4555  
4556  * If @etag is specified (not %NULL) any existing file must have that etag, or
4557  * the error %G_IO_ERROR_WRONG_ETAG will be returned.
4558  *
4559  * If @make_backup is %TRUE, this function will attempt to make a backup of @file.
4560  * 
4561  * If @cancellable is not %NULL, then the operation can be cancelled by
4562  * triggering the cancellable object from another thread. If the operation
4563  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4564  *
4565  * The returned @new_etag can be used to verify that the file hasn't changed the
4566  * next time it is saved over.
4567  * 
4568  * Returns: %TRUE if successful. If an error
4569  * has occured, this function will return %FALSE and set @error
4570  * appropriately if present.
4571  **/
4572 gboolean
4573 g_file_replace_contents (GFile             *file,
4574                          const char        *contents,
4575                          gsize              length,
4576                          const char        *etag,
4577                          gboolean           make_backup,
4578                          GFileCreateFlags   flags,
4579                          char             **new_etag,
4580                          GCancellable      *cancellable,
4581                          GError           **error)
4582 {
4583   GFileOutputStream *out;
4584   gsize pos, remainder;
4585   gssize res;
4586
4587   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4588   g_return_val_if_fail (contents != NULL, FALSE);
4589
4590   out = g_file_replace (file, etag, make_backup, flags, cancellable, error);
4591   if (out == NULL)
4592     return FALSE;
4593
4594   pos = 0;
4595   remainder = length;
4596   while (remainder > 0 &&
4597          (res = g_output_stream_write (G_OUTPUT_STREAM (out),
4598                                        contents + pos,
4599                                        MIN (remainder, GET_CONTENT_BLOCK_SIZE),
4600                                        cancellable,
4601                                        error)) > 0)
4602     {
4603       pos += res;
4604       remainder -= res;
4605     }
4606   
4607   if (remainder > 0 && res < 0)
4608     {
4609       /* Ignore errors on close */
4610       g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, NULL);
4611       
4612       /* error is set already */
4613       return FALSE;
4614     }
4615   
4616   if (!g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, error))
4617     return FALSE;
4618
4619   if (new_etag)
4620     *new_etag = g_file_output_stream_get_etag (out);
4621   
4622   return TRUE;
4623 }
4624
4625 typedef struct {
4626   GFile *file;
4627   GError *error;
4628   GCancellable *cancellable;
4629   GAsyncReadyCallback callback;
4630   gpointer user_data;
4631   const char *content;
4632   gsize length;
4633   gsize pos;
4634   char *etag;
4635 } ReplaceContentsData;
4636
4637 static void
4638 replace_contents_data_free (ReplaceContentsData *data)
4639 {
4640   if (data->error)
4641     g_error_free (data->error);
4642   if (data->cancellable)
4643     g_object_unref (data->cancellable);
4644   g_object_unref (data->file);
4645   g_free (data->etag);
4646   g_free (data);
4647 }
4648
4649 static void
4650 replace_contents_close_callback (GObject      *obj,
4651                                  GAsyncResult *close_res,
4652                                  gpointer      user_data)
4653 {
4654   GOutputStream *stream = G_OUTPUT_STREAM (obj);
4655   ReplaceContentsData *data = user_data;
4656   GSimpleAsyncResult *res;
4657
4658   /* Ignore errors here, we're only reading anyway */
4659   g_output_stream_close_finish (stream, close_res, NULL);
4660   g_object_unref (stream);
4661
4662   data->etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (stream));
4663   
4664   res = g_simple_async_result_new (G_OBJECT (data->file),
4665                                    data->callback,
4666                                    data->user_data,
4667                                    g_file_replace_contents_async);
4668   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_contents_data_free);
4669   g_simple_async_result_complete (res);
4670   g_object_unref (res);
4671 }
4672
4673 static void
4674 replace_contents_write_callback (GObject      *obj,
4675                                  GAsyncResult *read_res,
4676                                  gpointer      user_data)
4677 {
4678   GOutputStream *stream = G_OUTPUT_STREAM (obj);
4679   ReplaceContentsData *data = user_data;
4680   GError *error = NULL;
4681   gssize write_size;
4682   
4683   write_size = g_output_stream_write_finish (stream, read_res, &error);
4684
4685   if (write_size <= 0) 
4686     {
4687       /* Error or EOF, close the file */
4688       if (write_size < 0)
4689         data->error = error;
4690       g_output_stream_close_async (stream, 0,
4691                                    data->cancellable,
4692                                    replace_contents_close_callback, data);
4693     }
4694   else if (write_size > 0)
4695     {
4696       data->pos += write_size;
4697
4698       if (data->pos >= data->length)
4699         g_output_stream_close_async (stream, 0,
4700                                      data->cancellable,
4701                                      replace_contents_close_callback, data);
4702       else
4703         g_output_stream_write_async (stream,
4704                                      data->content + data->pos,
4705                                      data->length - data->pos,
4706                                      0,
4707                                      data->cancellable,
4708                                      replace_contents_write_callback,
4709                                      data);
4710     }
4711 }
4712
4713 static void
4714 replace_contents_open_callback (GObject      *obj,
4715                                 GAsyncResult *open_res,
4716                                 gpointer      user_data)
4717 {
4718   GFile *file = G_FILE (obj);
4719   GFileOutputStream *stream;
4720   ReplaceContentsData *data = user_data;
4721   GError *error = NULL;
4722   GSimpleAsyncResult *res;
4723
4724   stream = g_file_replace_finish (file, open_res, &error);
4725
4726   if (stream)
4727     {
4728       g_output_stream_write_async (G_OUTPUT_STREAM (stream),
4729                                    data->content + data->pos,
4730                                    data->length - data->pos,
4731                                    0,
4732                                    data->cancellable,
4733                                    replace_contents_write_callback,
4734                                    data);
4735       
4736     }
4737   else
4738     {
4739       res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
4740                                                   data->callback,
4741                                                   data->user_data,
4742                                                   error);
4743       g_simple_async_result_complete (res);
4744       g_error_free (error);
4745       replace_contents_data_free (data);
4746       g_object_unref (res);
4747     }
4748 }
4749
4750 /**
4751  * g_file_replace_contents_async:
4752  * @file: input #GFile.
4753  * @contents: string of contents to replace the file with.
4754  * @length: the length of @contents in bytes.
4755  * @etag: a new <link linkend="gfile-etag">entity tag</link> for the @file.
4756  * @make_backup: %TRUE if a backup should be created.
4757  * @flags: a set of #GFileCreateFlags.
4758  * @cancellable: optional #GCancellable object, %NULL to ignore.
4759  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
4760  * @user_data: the data to pass to callback function
4761  * 
4762  * Starts an asynchronous replacement of @file with the given 
4763  * @contents of @length bytes. @etag will replace the document's 
4764  * current entity tag.
4765  * 
4766  * When this operation has completed, @callback will be called with
4767  * @user_user data, and the operation can be finalized with 
4768  * g_file_replace_contents_finish().
4769  * 
4770  * If @cancellable is not %NULL, then the operation can be cancelled by
4771  * triggering the cancellable object from another thread. If the operation
4772  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4773  * 
4774  * If @make_backup is %TRUE, this function will attempt to 
4775  * make a backup of @file.
4776  **/
4777 void
4778 g_file_replace_contents_async  (GFile               *file,
4779                                 const char          *contents,
4780                                 gsize                length,
4781                                 const char          *etag,
4782                                 gboolean             make_backup,
4783                                 GFileCreateFlags     flags,
4784                                 GCancellable        *cancellable,
4785                                 GAsyncReadyCallback  callback,
4786                                 gpointer             user_data)
4787 {
4788   ReplaceContentsData *data;
4789
4790   g_return_if_fail (G_IS_FILE (file));
4791   g_return_if_fail (contents != NULL);
4792
4793   data = g_new0 (ReplaceContentsData, 1);
4794
4795   if (cancellable)
4796     data->cancellable = g_object_ref (cancellable);
4797   data->callback = callback;
4798   data->user_data = user_data;
4799   data->content = contents;
4800   data->length = length;
4801   data->pos = 0;
4802   data->file = g_object_ref (file);
4803
4804   g_file_replace_async (file,
4805                         etag,
4806                         make_backup,
4807                         flags,
4808                         0,
4809                         cancellable,
4810                         replace_contents_open_callback,
4811                         data);
4812 }
4813   
4814 /**
4815  * g_file_replace_contents_finish:
4816  * @file: input #GFile.
4817  * @res: a #GAsyncResult. 
4818  * @new_etag: a location of a new <link linkend="gfile-etag">entity tag</link> 
4819  *     for the document.
4820  * @error: a #GError, or %NULL 
4821  * 
4822  * Finishes an asynchronous replace of the given @file. See
4823  * g_file_replace_contents_async(). Sets @new_etag to the new entity 
4824  * tag for the document, if present.
4825  * 
4826  * Returns: %TRUE on success, %FALSE on failure.
4827  **/
4828 gboolean
4829 g_file_replace_contents_finish (GFile         *file,
4830                                 GAsyncResult  *res,
4831                                 char         **new_etag,
4832                                 GError       **error)
4833 {
4834   GSimpleAsyncResult *simple;
4835   ReplaceContentsData *data;
4836
4837   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4838   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
4839
4840   simple = G_SIMPLE_ASYNC_RESULT (res);
4841
4842   if (g_simple_async_result_propagate_error (simple, error))
4843     return FALSE;
4844   
4845   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_replace_contents_async);
4846   
4847   data = g_simple_async_result_get_op_res_gpointer (simple);
4848
4849   if (data->error)
4850     {
4851       g_propagate_error (error, data->error);
4852       data->error = NULL;
4853       return FALSE;
4854     }
4855
4856
4857   if (new_etag)
4858     {
4859       *new_etag = data->etag;
4860       data->etag = NULL; /* Take ownership */
4861     }
4862   
4863   return TRUE;
4864 }
4865
4866 #define __G_FILE_C__
4867 #include "gioaliasdef.c"