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