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