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