clarify docs for g_file_delete().
[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. If the @file is a directory, it will only be deleted if it 
2711  * is empty.
2712  * 
2713  * If @cancellable is not %NULL, then the operation can be cancelled by
2714  * triggering the cancellable object from another thread. If the operation
2715  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2716  * 
2717  * Returns: %TRUE if the file was deleted. %FALSE otherwise.
2718  **/
2719 gboolean
2720 g_file_delete (GFile         *file,
2721                GCancellable  *cancellable,
2722                GError       **error)
2723 {
2724   GFileIface *iface;
2725   
2726   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2727
2728   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2729     return FALSE;
2730   
2731   iface = G_FILE_GET_IFACE (file);
2732
2733   if (iface->delete_file == NULL)
2734     {
2735       g_set_error (error, G_IO_ERROR,
2736                    G_IO_ERROR_NOT_SUPPORTED,
2737                    _("Operation not supported"));
2738       return FALSE;
2739     }
2740   
2741   return (* iface->delete_file) (file, cancellable, error);
2742 }
2743
2744 /**
2745  * g_file_trash:
2746  * @file: #GFile to send to trash.
2747  * @cancellable: optional #GCancellable object, %NULL to ignore.
2748  * @error: a #GError, or %NULL
2749  *
2750  * Sends @file to the "Trashcan", if possible. This is similar to
2751  * deleting it, but the user can recover it before emptying the trashcan.
2752  * Not all file systems support trashing, so this call can return the
2753  * %G_IO_ERROR_NOT_SUPPORTED error.
2754  *
2755  *
2756  * If @cancellable is not %NULL, then the operation can be cancelled by
2757  * triggering the cancellable object from another thread. If the operation
2758  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2759  * 
2760  * Returns: %TRUE on successful trash, %FALSE otherwise.
2761  **/
2762 gboolean
2763 g_file_trash (GFile         *file,
2764               GCancellable  *cancellable,
2765               GError       **error)
2766 {
2767   GFileIface *iface;
2768   
2769   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2770
2771   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2772     return FALSE;
2773   
2774   iface = G_FILE_GET_IFACE (file);
2775
2776   if (iface->trash == NULL)
2777     {
2778       g_set_error (error,
2779                    G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
2780                    _("Trash not supported"));
2781       return FALSE;
2782     }
2783   
2784   return (* iface->trash) (file, cancellable, error);
2785 }
2786
2787 /**
2788  * g_file_set_display_name:
2789  * @file: input #GFile.
2790  * @display_name: a string.
2791  * @cancellable: optional #GCancellable object, %NULL to ignore.
2792  * @error: a #GError, or %NULL
2793  * 
2794  * Renames @file to the specified display name.
2795  *
2796  * The display name is converted from UTF8 to the correct encoding for the target
2797  * filesystem if possible and the @file is renamed to this.
2798  * 
2799  * If you want to implement a rename operation in the user interface the edit name
2800  * (#G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME) should be used as the initial value in the rename
2801  * widget, and then the result after editing should be passed to g_file_set_display_name().
2802  *
2803  * On success the resulting converted filename is returned.
2804  * 
2805  * If @cancellable is not %NULL, then the operation can be cancelled by
2806  * triggering the cancellable object from another thread. If the operation
2807  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2808  * 
2809  * Returns: a #GFile specifying what @file was renamed to, or %NULL if there was an error.
2810  **/
2811 GFile *
2812 g_file_set_display_name (GFile         *file,
2813                          const char    *display_name,
2814                          GCancellable  *cancellable,
2815                          GError       **error)
2816 {
2817   GFileIface *iface;
2818   
2819   g_return_val_if_fail (G_IS_FILE (file), NULL);
2820   g_return_val_if_fail (display_name != NULL, NULL);
2821
2822   if (strchr (display_name, G_DIR_SEPARATOR) != NULL)
2823     {
2824       g_set_error (error,
2825                    G_IO_ERROR,
2826                    G_IO_ERROR_INVALID_ARGUMENT,
2827                    _("File names cannot contain '%c'"), G_DIR_SEPARATOR);
2828       return NULL;
2829     }
2830   
2831   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2832     return NULL;
2833   
2834   iface = G_FILE_GET_IFACE (file);
2835
2836   return (* iface->set_display_name) (file, display_name, cancellable, error);
2837 }
2838
2839 /**
2840  * g_file_set_display_name_async:
2841  * @file: input #GFile.
2842  * @display_name: a string.
2843  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
2844  *     of the request. 
2845  * @cancellable: optional #GCancellable object, %NULL to ignore.
2846  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
2847  * @user_data: the data to pass to callback function
2848  * 
2849  * Asynchronously sets the display name for a given #GFile.
2850  * 
2851  * For more details, see g_set_display_name() which is
2852  * the synchronous version of this call.
2853  *
2854  * When the operation is finished, @callback will be called. You can then call
2855  * g_file_set_display_name_finish() to get the result of the operation.
2856  **/
2857 void
2858 g_file_set_display_name_async (GFile               *file,
2859                                const char          *display_name,
2860                                int                  io_priority,
2861                                GCancellable        *cancellable,
2862                                GAsyncReadyCallback  callback,
2863                                gpointer             user_data)
2864 {
2865   GFileIface *iface;
2866   
2867   g_return_if_fail (G_IS_FILE (file));
2868   g_return_if_fail (display_name != NULL);
2869
2870   iface = G_FILE_GET_IFACE (file);
2871   (* iface->set_display_name_async) (file,
2872                                      display_name,
2873                                      io_priority,
2874                                      cancellable,
2875                                      callback,
2876                                      user_data);
2877 }
2878
2879 /**
2880  * g_file_set_display_name_finish:
2881  * @file: input #GFile.
2882  * @res: a #GAsyncResult. 
2883  * @error: a #GError, or %NULL
2884  * 
2885  * Finishes setting a display name started with 
2886  * g_file_set_display_name_async().
2887  * 
2888  * Returns: a #GFile or %NULL on error.
2889  **/
2890 GFile *
2891 g_file_set_display_name_finish (GFile         *file,
2892                                 GAsyncResult  *res,
2893                                 GError       **error)
2894 {
2895   GFileIface *iface;
2896   
2897   g_return_val_if_fail (G_IS_FILE (file), NULL);
2898   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2899
2900   if (G_IS_SIMPLE_ASYNC_RESULT (res))
2901     {
2902       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
2903       if (g_simple_async_result_propagate_error (simple, error))
2904         return NULL;
2905     }
2906   
2907   iface = G_FILE_GET_IFACE (file);
2908   return (* iface->set_display_name_finish) (file, res, error);
2909 }
2910
2911 /**
2912  * g_file_query_settable_attributes:
2913  * @file: input #GFile.
2914  * @cancellable: optional #GCancellable object, %NULL to ignore.
2915  * @error: a #GError, or %NULL
2916  * 
2917  * Obtain the list of settable attributes for the file.
2918  *
2919  * Returns the type and full attribute name of all the attributes 
2920  * that can be set on this file. This doesn't mean setting it will always 
2921  * succeed though, you might get an access failure, or some specific 
2922  * file may not support a specific attribute.
2923  *
2924  * If @cancellable is not %NULL, then the operation can be cancelled by
2925  * triggering the cancellable object from another thread. If the operation
2926  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2927  * 
2928  * Returns: a #GFileAttributeInfoList describing the settable attributes.
2929  * When you are done with it, release it with g_file_attribute_info_list_unref()
2930  **/
2931 GFileAttributeInfoList *
2932 g_file_query_settable_attributes (GFile         *file,
2933                                   GCancellable  *cancellable,
2934                                   GError       **error)
2935 {
2936   GFileIface *iface;
2937   GError *my_error;
2938   GFileAttributeInfoList *list;
2939
2940   g_return_val_if_fail (G_IS_FILE (file), NULL);
2941
2942   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2943     return NULL;
2944   
2945   iface = G_FILE_GET_IFACE (file);
2946
2947   if (iface->query_settable_attributes == NULL)
2948     return g_file_attribute_info_list_new ();
2949
2950   my_error = NULL;
2951   list = (* iface->query_settable_attributes) (file, cancellable, &my_error);
2952   
2953   if (list == NULL)
2954     {
2955       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
2956         {
2957           list = g_file_attribute_info_list_new ();
2958           g_error_free (my_error);
2959         }
2960       else
2961         g_propagate_error (error, my_error);
2962     }
2963   
2964   return list;
2965 }
2966
2967 /**
2968  * g_file_query_writable_namespaces:
2969  * @file: input #GFile.
2970  * @cancellable: optional #GCancellable object, %NULL to ignore.
2971  * @error: a #GError, or %NULL
2972  * 
2973  * Obtain the list of attribute namespaces where new attributes 
2974  * can be created by a user. An example of this is extended
2975  * attributes (in the "xattr" namespace).
2976  *
2977  * If @cancellable is not %NULL, then the operation can be cancelled by
2978  * triggering the cancellable object from another thread. If the operation
2979  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2980  * 
2981  * Returns: a #GFileAttributeInfoList describing the writable namespaces.
2982  * When you are done with it, release it with g_file_attribute_info_list_unref()
2983  **/
2984 GFileAttributeInfoList *
2985 g_file_query_writable_namespaces (GFile         *file,
2986                                   GCancellable  *cancellable,
2987                                   GError       **error)
2988 {
2989   GFileIface *iface;
2990   GError *my_error;
2991   GFileAttributeInfoList *list;
2992   
2993   g_return_val_if_fail (G_IS_FILE (file), NULL);
2994
2995   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2996     return NULL;
2997   
2998   iface = G_FILE_GET_IFACE (file);
2999
3000   if (iface->query_writable_namespaces == NULL)
3001     return g_file_attribute_info_list_new ();
3002
3003   my_error = NULL;
3004   list = (* iface->query_writable_namespaces) (file, cancellable, &my_error);
3005   
3006   if (list == NULL)
3007     {
3008       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
3009         {
3010           list = g_file_attribute_info_list_new ();
3011           g_error_free (my_error);
3012         }
3013       else
3014         g_propagate_error (error, my_error);
3015     }
3016   
3017   return list;
3018 }
3019
3020 /**
3021  * g_file_set_attribute:
3022  * @file: input #GFile.
3023  * @attribute: a string containing the attribute's name.
3024  * @type: The type of the attribute
3025  * @value_p: a pointer to the value (or the pointer itself if the type is a pointer type)
3026  * @flags: a set of #GFileQueryInfoFlags.
3027  * @cancellable: optional #GCancellable object, %NULL to ignore.
3028  * @error: a #GError, or %NULL
3029  * 
3030  * Sets an attribute in the file with attribute name @attribute to @value.
3031  * 
3032  * If @cancellable is not %NULL, then the operation can be cancelled by
3033  * triggering the cancellable object from another thread. If the operation
3034  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3035  * 
3036  * Returns: %TRUE if the attribute was set, %FALSE otherwise.
3037  **/
3038 gboolean
3039 g_file_set_attribute (GFile                      *file,
3040                       const char                 *attribute,
3041                       GFileAttributeType          type,
3042                       gpointer                    value_p,
3043                       GFileQueryInfoFlags         flags,
3044                       GCancellable               *cancellable,
3045                       GError                    **error)
3046 {
3047   GFileIface *iface;
3048   
3049   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3050   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
3051
3052   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3053     return FALSE;
3054   
3055   iface = G_FILE_GET_IFACE (file);
3056
3057   if (iface->set_attribute == NULL)
3058     {
3059       g_set_error (error, G_IO_ERROR,
3060                    G_IO_ERROR_NOT_SUPPORTED,
3061                    _("Operation not supported"));
3062       return FALSE;
3063     }
3064
3065   return (* iface->set_attribute) (file, attribute, type, value_p, flags, cancellable, error);
3066 }
3067
3068 /**
3069  * g_file_set_attributes_from_info:
3070  * @file: input #GFile.
3071  * @info: a #GFileInfo.
3072  * @flags: #GFileQueryInfoFlags
3073  * @cancellable: optional #GCancellable object, %NULL to ignore.
3074  * @error: a #GError, or %NULL 
3075  * 
3076  * Tries to set all attributes in the #GFileInfo on the target values, 
3077  * not stopping on the first error.
3078  * 
3079  * If there is any error during this operation then @error will be set to
3080  * the first error. Error on particular fields are flagged by setting 
3081  * the "status" field in the attribute value to 
3082  * %G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING, which means you can also detect
3083  * further errors.
3084  *
3085  * If @cancellable is not %NULL, then the operation can be cancelled by
3086  * triggering the cancellable object from another thread. If the operation
3087  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3088  * 
3089  * Returns: %TRUE if there was any error, %FALSE otherwise.
3090  **/
3091 gboolean
3092 g_file_set_attributes_from_info (GFile                *file,
3093                                  GFileInfo            *info,
3094                                  GFileQueryInfoFlags   flags,
3095                                  GCancellable         *cancellable,
3096                                  GError              **error)
3097 {
3098   GFileIface *iface;
3099
3100   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3101   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
3102
3103   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3104     return FALSE;
3105   
3106   g_file_info_clear_status (info);
3107   
3108   iface = G_FILE_GET_IFACE (file);
3109
3110   return (* iface->set_attributes_from_info) (file, 
3111                                               info, 
3112                                               flags, 
3113                                               cancellable, 
3114                                               error);
3115 }
3116
3117
3118 static gboolean
3119 g_file_real_set_attributes_from_info (GFile                *file,
3120                                       GFileInfo            *info,
3121                                       GFileQueryInfoFlags   flags,
3122                                       GCancellable         *cancellable,
3123                                       GError              **error)
3124 {
3125   char **attributes;
3126   int i;
3127   gboolean res;
3128   GFileAttributeValue *value;
3129   
3130   res = TRUE;
3131   
3132   attributes = g_file_info_list_attributes (info, NULL);
3133
3134   for (i = 0; attributes[i] != NULL; i++)
3135     {
3136       value = _g_file_info_get_attribute_value (info, attributes[i]);
3137
3138       if (value->status != G_FILE_ATTRIBUTE_STATUS_UNSET)
3139         continue;
3140
3141       if (!g_file_set_attribute (file, attributes[i],
3142                                  value->type, _g_file_attribute_value_peek_as_pointer (value),
3143                                  flags, cancellable, error))
3144         {
3145           value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING;
3146           res = FALSE;
3147           /* Don't set error multiple times */
3148           error = NULL;
3149         }
3150       else
3151         value->status = G_FILE_ATTRIBUTE_STATUS_SET;
3152     }
3153   
3154   g_strfreev (attributes);
3155   
3156   return res;
3157 }
3158
3159 /**
3160  * g_file_set_attributes_async:
3161  * @file: input #GFile.
3162  * @info: a #GFileInfo.
3163  * @flags: a #GFileQueryInfoFlags.
3164  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
3165  *     of the request. 
3166  * @cancellable: optional #GCancellable object, %NULL to ignore.
3167  * @callback: a #GAsyncReadyCallback. 
3168  * @user_data: a #gpointer.
3169  *
3170  * Asynchronously sets the attributes of @file with @info.
3171  * 
3172  * For more details, see g_file_set_attributes_from_info() which is
3173  * the synchronous version of this call.
3174  *
3175  * When the operation is finished, @callback will be called. You can then call
3176  * g_file_set_attributes_finish() to get the result of the operation.
3177  **/
3178 void
3179 g_file_set_attributes_async (GFile               *file,
3180                              GFileInfo           *info,
3181                              GFileQueryInfoFlags  flags,
3182                              int                  io_priority,
3183                              GCancellable        *cancellable,
3184                              GAsyncReadyCallback  callback,
3185                              gpointer             user_data)
3186 {
3187   GFileIface *iface;
3188   
3189   g_return_if_fail (G_IS_FILE (file));
3190   g_return_if_fail (G_IS_FILE_INFO (info));
3191
3192   iface = G_FILE_GET_IFACE (file);
3193   (* iface->set_attributes_async) (file, 
3194                                    info, 
3195                                    flags, 
3196                                    io_priority, 
3197                                    cancellable, 
3198                                    callback, 
3199                                    user_data);
3200 }
3201
3202 /**
3203  * g_file_set_attributes_finish:
3204  * @file: input #GFile.
3205  * @result: a #GAsyncResult.
3206  * @info: a #GFileInfo.
3207  * @error: a #GError, or %NULL
3208  * 
3209  * Finishes setting an attribute started in g_file_set_attributes_async().
3210  * 
3211  * Returns: %TRUE if the attributes were set correctly, %FALSE otherwise.
3212  **/
3213 gboolean
3214 g_file_set_attributes_finish (GFile         *file,
3215                               GAsyncResult  *result,
3216                               GFileInfo    **info,
3217                               GError       **error)
3218 {
3219   GFileIface *iface;
3220   
3221   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3222   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3223
3224   /* No standard handling of errors here, as we must set info even
3225    * on errors 
3226    */
3227   iface = G_FILE_GET_IFACE (file);
3228   return (* iface->set_attributes_finish) (file, result, info, error);
3229 }
3230
3231 /**
3232  * g_file_set_attribute_string:
3233  * @file: input #GFile.
3234  * @attribute: a string containing the attribute's name.
3235  * @value: a string containing the attribute's value.
3236  * @flags: #GFileQueryInfoFlags.
3237  * @cancellable: optional #GCancellable object, %NULL to ignore.
3238  * @error: a #GError, or %NULL
3239  * 
3240  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_STRING to @value. 
3241  * If @attribute is of a different type, this operation will fail.
3242  * 
3243  * If @cancellable is not %NULL, then the operation can be cancelled by
3244  * triggering the cancellable object from another thread. If the operation
3245  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3246  * 
3247  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
3248  **/
3249 gboolean
3250 g_file_set_attribute_string (GFile                *file,
3251                              const char           *attribute,
3252                              const char           *value,
3253                              GFileQueryInfoFlags   flags,
3254                              GCancellable         *cancellable,
3255                              GError              **error)
3256 {
3257   return g_file_set_attribute (file, attribute,
3258                                G_FILE_ATTRIBUTE_TYPE_STRING, (gpointer)value,
3259                                flags, cancellable, error);
3260 }
3261
3262 /**
3263  * g_file_set_attribute_byte_string:
3264  * @file: input #GFile.
3265  * @attribute: a string containing the attribute's name.
3266  * @value: a string containing the attribute's new value.
3267  * @flags: a #GFileQueryInfoFlags.
3268  * @cancellable: optional #GCancellable object, %NULL to ignore.
3269  * @error: a #GError, or %NULL
3270  * 
3271  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING to @value. 
3272  * If @attribute is of a different type, this operation will fail, 
3273  * returning %FALSE. 
3274  * 
3275  * If @cancellable is not %NULL, then the operation can be cancelled by
3276  * triggering the cancellable object from another thread. If the operation
3277  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3278  * 
3279  * Returns: %TRUE if the @attribute was successfully set to @value 
3280  * in the @file, %FALSE otherwise.
3281  **/
3282 gboolean
3283 g_file_set_attribute_byte_string  (GFile                *file,
3284                                    const char           *attribute,
3285                                    const char           *value,
3286                                    GFileQueryInfoFlags   flags,
3287                                    GCancellable         *cancellable,
3288                                    GError              **error)
3289 {
3290   return g_file_set_attribute (file, attribute,
3291                                G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, (gpointer)value,
3292                                flags, cancellable, error);
3293 }
3294
3295 /**
3296  * g_file_set_attribute_uint32:
3297  * @file: input #GFile.
3298  * @attribute: a string containing the attribute's name.
3299  * @value: a #guint32 containing the attribute's new value.
3300  * @flags: a #GFileQueryInfoFlags.
3301  * @cancellable: optional #GCancellable object, %NULL to ignore.
3302  * @error: a #GError, or %NULL
3303  * 
3304  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT32 to @value. 
3305  * If @attribute is of a different type, this operation will fail.
3306  * 
3307  * If @cancellable is not %NULL, then the operation can be cancelled by
3308  * triggering the cancellable object from another thread. If the operation
3309  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3310  * 
3311  * Returns: %TRUE if the @attribute was successfully set to @value 
3312  * in the @file, %FALSE otherwise.
3313  **/
3314 gboolean
3315 g_file_set_attribute_uint32 (GFile                *file,
3316                              const char           *attribute,
3317                              guint32               value,
3318                              GFileQueryInfoFlags   flags,
3319                              GCancellable         *cancellable,
3320                              GError              **error)
3321 {
3322   return g_file_set_attribute (file, attribute,
3323                                G_FILE_ATTRIBUTE_TYPE_UINT32, &value,
3324                                flags, cancellable, error);
3325 }
3326
3327 /**
3328  * g_file_set_attribute_int32:
3329  * @file: input #GFile.
3330  * @attribute: a string containing the attribute's name.
3331  * @value: a #gint32 containing the attribute's new value.
3332  * @flags: a #GFileQueryInfoFlags.
3333  * @cancellable: optional #GCancellable object, %NULL to ignore.
3334  * @error: a #GError, or %NULL
3335  * 
3336  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT32 to @value. 
3337  * If @attribute is of a different type, this operation will fail.
3338  * 
3339  * If @cancellable is not %NULL, then the operation can be cancelled by
3340  * triggering the cancellable object from another thread. If the operation
3341  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3342  * 
3343  * Returns: %TRUE if the @attribute was successfully set to @value 
3344  * in the @file, %FALSE otherwise. 
3345  **/
3346 gboolean
3347 g_file_set_attribute_int32 (GFile                *file,
3348                             const char           *attribute,
3349                             gint32                value,
3350                             GFileQueryInfoFlags   flags,
3351                             GCancellable         *cancellable,
3352                             GError              **error)
3353 {
3354   return g_file_set_attribute (file, attribute,
3355                                G_FILE_ATTRIBUTE_TYPE_INT32, &value,
3356                                flags, cancellable, error);
3357 }
3358
3359 /**
3360  * g_file_set_attribute_uint64:
3361  * @file: input #GFile. 
3362  * @attribute: a string containing the attribute's name.
3363  * @value: a #guint64 containing the attribute's new value.
3364  * @flags: a #GFileQueryInfoFlags.
3365  * @cancellable: optional #GCancellable object, %NULL to ignore.
3366  * @error: a #GError, or %NULL
3367  * 
3368  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT64 to @value. 
3369  * If @attribute is of a different type, this operation will fail.
3370  * 
3371  * If @cancellable is not %NULL, then the operation can be cancelled by
3372  * triggering the cancellable object from another thread. If the operation
3373  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3374  * 
3375  * Returns: %TRUE if the @attribute was successfully set to @value 
3376  * in the @file, %FALSE otherwise.
3377  **/
3378 gboolean
3379 g_file_set_attribute_uint64 (GFile                *file,
3380                              const char           *attribute,
3381                              guint64               value,
3382                              GFileQueryInfoFlags   flags,
3383                              GCancellable         *cancellable,
3384                              GError              **error)
3385  {
3386   return g_file_set_attribute (file, attribute,
3387                                G_FILE_ATTRIBUTE_TYPE_UINT64, &value,
3388                                flags, cancellable, error);
3389 }
3390
3391 /**
3392  * g_file_set_attribute_int64:
3393  * @file: input #GFile.
3394  * @attribute: a string containing the attribute's name.
3395  * @value: a #guint64 containing the attribute's new value.
3396  * @flags: a #GFileQueryInfoFlags.
3397  * @cancellable: optional #GCancellable object, %NULL to ignore.
3398  * @error: a #GError, or %NULL
3399  * 
3400  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT64 to @value. 
3401  * If @attribute is of a different type, this operation will fail.
3402  * 
3403  * If @cancellable is not %NULL, then the operation can be cancelled by
3404  * triggering the cancellable object from another thread. If the operation
3405  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3406  * 
3407  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
3408  **/
3409 gboolean
3410 g_file_set_attribute_int64 (GFile                *file,
3411                             const char           *attribute,
3412                             gint64                value,
3413                             GFileQueryInfoFlags   flags,
3414                             GCancellable         *cancellable,
3415                             GError              **error)
3416 {
3417   return g_file_set_attribute (file, attribute,
3418                                G_FILE_ATTRIBUTE_TYPE_INT64, &value,
3419                                flags, cancellable, error);
3420 }
3421
3422 /**
3423  * g_file_mount_mountable:
3424  * @file: input #GFile.
3425  * @flags: flags affecting the operation
3426  * @mount_operation: a #GMountOperation, or %NULL to avoid user interaction.
3427  * @cancellable: optional #GCancellable object, %NULL to ignore.
3428  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
3429  * @user_data: the data to pass to callback function
3430  * 
3431  * Mounts a file of type G_FILE_TYPE_MOUNTABLE.
3432  * Using @mount_operation, you can request callbacks when, for instance, 
3433  * passwords are needed during authentication.
3434  *
3435  * If @cancellable is not %NULL, then the operation can be cancelled by
3436  * triggering the cancellable object from another thread. If the operation
3437  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3438  *
3439  * When the operation is finished, @callback will be called. You can then call
3440  * g_file_mount_mountable_finish() to get the result of the operation.
3441  **/
3442 void
3443 g_file_mount_mountable (GFile               *file,
3444                         GMountMountFlags     flags,
3445                         GMountOperation     *mount_operation,
3446                         GCancellable        *cancellable,
3447                         GAsyncReadyCallback  callback,
3448                         gpointer             user_data)
3449 {
3450   GFileIface *iface;
3451
3452   g_return_if_fail (G_IS_FILE (file));
3453
3454   iface = G_FILE_GET_IFACE (file);
3455
3456   if (iface->mount_mountable == NULL) 
3457     {
3458       g_simple_async_report_error_in_idle (G_OBJECT (file),
3459                                            callback,
3460                                            user_data,
3461                                            G_IO_ERROR,
3462                                            G_IO_ERROR_NOT_SUPPORTED,
3463                                            _("Operation not supported"));
3464       return;
3465     }
3466   
3467   (* iface->mount_mountable) (file,
3468                               flags,
3469                               mount_operation,
3470                               cancellable,
3471                               callback,
3472                               user_data);
3473 }
3474
3475 /**
3476  * g_file_mount_mountable_finish:
3477  * @file: input #GFile.
3478  * @result: a #GAsyncResult.
3479  * @error: a #GError, or %NULL
3480  *
3481  * Finishes a mount operation. See g_file_mount_mountable() for details.
3482  * 
3483  * Finish an asynchronous mount operation that was started 
3484  * with g_file_mount_mountable().
3485  *
3486  * Returns: a #GFile or %NULL on error.
3487  **/
3488 GFile *
3489 g_file_mount_mountable_finish (GFile         *file,
3490                                GAsyncResult  *result,
3491                                GError       **error)
3492 {
3493   GFileIface *iface;
3494
3495   g_return_val_if_fail (G_IS_FILE (file), NULL);
3496   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
3497
3498   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3499     {
3500       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3501       if (g_simple_async_result_propagate_error (simple, error))
3502         return NULL;
3503     }
3504   
3505   iface = G_FILE_GET_IFACE (file);
3506   return (* iface->mount_mountable_finish) (file, result, error);
3507 }
3508
3509 /**
3510  * g_file_unmount_mountable:
3511  * @file: input #GFile.
3512  * @flags: flags affecting the operation
3513  * @cancellable: optional #GCancellable object, %NULL to ignore.
3514  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
3515  * @user_data: the data to pass to callback function
3516  *
3517  * Unmounts a file of type G_FILE_TYPE_MOUNTABLE.
3518  *
3519  * If @cancellable is not %NULL, then the operation can be cancelled by
3520  * triggering the cancellable object from another thread. If the operation
3521  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3522  *
3523  * When the operation is finished, @callback will be called. You can then call
3524  * g_file_unmount_mountable_finish() to get the result of the operation.
3525  **/
3526 void
3527 g_file_unmount_mountable (GFile               *file,
3528                           GMountUnmountFlags   flags,
3529                           GCancellable        *cancellable,
3530                           GAsyncReadyCallback  callback,
3531                           gpointer             user_data)
3532 {
3533   GFileIface *iface;
3534   
3535   g_return_if_fail (G_IS_FILE (file));
3536
3537   iface = G_FILE_GET_IFACE (file);
3538   
3539   if (iface->unmount_mountable == NULL)
3540     {
3541       g_simple_async_report_error_in_idle (G_OBJECT (file),
3542                                            callback,
3543                                            user_data,
3544                                            G_IO_ERROR,
3545                                            G_IO_ERROR_NOT_SUPPORTED,
3546                                            _("Operation not supported"));
3547       return;
3548     }
3549   
3550   (* iface->unmount_mountable) (file,
3551                                 flags,
3552                                 cancellable,
3553                                 callback,
3554                                 user_data);
3555 }
3556
3557 /**
3558  * g_file_unmount_mountable_finish:
3559  * @file: input #GFile.
3560  * @result: a #GAsyncResult.
3561  * @error: a #GError, or %NULL
3562  *
3563  * Finishes an unmount operation, see g_file_unmount_mountable() for details.
3564  * 
3565  * Finish an asynchronous unmount operation that was started 
3566  * with g_file_unmount_mountable().
3567  *
3568  * Returns: %TRUE if the operation finished successfully. %FALSE
3569  * otherwise.
3570  **/
3571 gboolean
3572 g_file_unmount_mountable_finish (GFile         *file,
3573                                  GAsyncResult  *result,
3574                                  GError       **error)
3575 {
3576   GFileIface *iface;
3577   
3578   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3579   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3580
3581   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3582     {
3583       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3584       if (g_simple_async_result_propagate_error (simple, error))
3585         return FALSE;
3586     }
3587   
3588   iface = G_FILE_GET_IFACE (file);
3589   return (* iface->unmount_mountable_finish) (file, result, error);
3590 }
3591
3592 /**
3593  * g_file_eject_mountable:
3594  * @file: input #GFile.
3595  * @flags: flags affecting the operation
3596  * @cancellable: optional #GCancellable object, %NULL to ignore.
3597  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
3598  * @user_data: the data to pass to callback function
3599  * 
3600  * Starts an asynchronous eject on a mountable.  
3601  * When this operation has completed, @callback will be called with
3602  * @user_user data, and the operation can be finalized with 
3603  * g_file_eject_mountable_finish().
3604  * 
3605  * If @cancellable is not %NULL, then the operation can be cancelled by
3606  * triggering the cancellable object from another thread. If the operation
3607  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3608  **/
3609 void
3610 g_file_eject_mountable (GFile               *file,
3611                         GMountUnmountFlags   flags,
3612                         GCancellable        *cancellable,
3613                         GAsyncReadyCallback  callback,
3614                         gpointer             user_data)
3615 {
3616   GFileIface *iface;
3617
3618   g_return_if_fail (G_IS_FILE (file));
3619
3620   iface = G_FILE_GET_IFACE (file);
3621   
3622   if (iface->eject_mountable == NULL) 
3623     {
3624       g_simple_async_report_error_in_idle (G_OBJECT (file),
3625                                            callback,
3626                                            user_data,
3627                                            G_IO_ERROR,
3628                                            G_IO_ERROR_NOT_SUPPORTED,
3629                                            _("Operation not supported"));
3630       return;
3631     }
3632   
3633   (* iface->eject_mountable) (file,
3634                               flags,
3635                               cancellable,
3636                               callback,
3637                               user_data);
3638 }
3639
3640 /**
3641  * g_file_eject_mountable_finish:
3642  * @file: input #GFile.
3643  * @result: a #GAsyncResult.
3644  * @error: a #GError, or %NULL
3645  * 
3646  * Finishes an asynchronous eject operation started by 
3647  * g_file_eject_mountable().
3648  * 
3649  * Returns: %TRUE if the @file was ejected successfully. %FALSE 
3650  * otherwise.
3651  **/
3652 gboolean
3653 g_file_eject_mountable_finish (GFile         *file,
3654                                GAsyncResult  *result,
3655                                GError       **error)
3656 {
3657   GFileIface *iface;
3658   
3659   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3660   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3661
3662   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3663     {
3664       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3665       if (g_simple_async_result_propagate_error (simple, error))
3666         return FALSE;
3667     }
3668   
3669   iface = G_FILE_GET_IFACE (file);
3670   return (* iface->eject_mountable_finish) (file, result, error);
3671 }
3672
3673 /**
3674  * g_file_monitor_directory:
3675  * @file: input #GFile.
3676  * @flags: a set of #GFileMonitorFlags.
3677  * @cancellable: optional #GCancellable object, %NULL to ignore.
3678  * @error: a #GError, or %NULL.
3679  * 
3680  * Obtains a directory monitor for the given file.
3681  * This may fail if directory monitoring is not supported.
3682  *
3683  * If @cancellable is not %NULL, then the operation can be cancelled by
3684  * triggering the cancellable object from another thread. If the operation
3685  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3686  * 
3687  * Returns: a #GFileMonitor for the given @file, 
3688  * or %NULL on error.
3689  **/
3690 GFileMonitor*
3691 g_file_monitor_directory (GFile             *file,
3692                           GFileMonitorFlags  flags,
3693                           GCancellable      *cancellable,
3694                           GError           **error)
3695 {
3696   GFileIface *iface;
3697
3698   g_return_val_if_fail (G_IS_FILE (file), NULL);
3699
3700   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3701     return NULL;
3702
3703   iface = G_FILE_GET_IFACE (file);
3704
3705   if (iface->monitor_dir == NULL)
3706     {
3707       g_set_error (error, G_IO_ERROR,
3708                    G_IO_ERROR_NOT_SUPPORTED,
3709                    _("Operation not supported"));
3710       return NULL;
3711     }
3712
3713   return (* iface->monitor_dir) (file, flags, cancellable, error);
3714 }
3715
3716 /**
3717  * g_file_monitor_file:
3718  * @file: input #GFile.
3719  * @flags: a set of #GFileMonitorFlags.
3720  * @cancellable: optional #GCancellable object, %NULL to ignore.
3721  * @error: a #GError, or %NULL.
3722  * 
3723  * Obtains a file monitor for the given file. If no file notification
3724  * mechanism exists, then regular polling of the file is used.
3725  *
3726  * If @cancellable is not %NULL, then the operation can be cancelled by
3727  * triggering the cancellable object from another thread. If the operation
3728  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3729  * 
3730  * Returns: a #GFileMonitor for the given @file.
3731  **/
3732 GFileMonitor*
3733 g_file_monitor_file (GFile             *file,
3734                      GFileMonitorFlags  flags,
3735                      GCancellable      *cancellable,
3736                      GError           **error)
3737 {
3738   GFileIface *iface;
3739   GFileMonitor *monitor;
3740   
3741   g_return_val_if_fail (G_IS_FILE (file), NULL);
3742
3743   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3744     return NULL;
3745
3746   iface = G_FILE_GET_IFACE (file);
3747
3748   monitor = NULL;
3749   
3750   if (iface->monitor_file)
3751     monitor = (* iface->monitor_file) (file, flags, cancellable, NULL);
3752
3753 /* Fallback to polling */
3754   if (monitor == NULL)
3755     monitor = _g_poll_file_monitor_new (file);
3756
3757   return monitor;
3758 }
3759
3760 /********************************************
3761  *   Default implementation of async ops    *
3762  ********************************************/
3763
3764 typedef struct {
3765   char *attributes;
3766   GFileQueryInfoFlags flags;
3767   GFileInfo *info;
3768 } QueryInfoAsyncData;
3769
3770 static void
3771 query_info_data_free (QueryInfoAsyncData *data)
3772 {
3773   if (data->info)
3774     g_object_unref (data->info);
3775   g_free (data->attributes);
3776   g_free (data);
3777 }
3778
3779 static void
3780 query_info_async_thread (GSimpleAsyncResult *res,
3781                          GObject            *object,
3782                          GCancellable       *cancellable)
3783 {
3784   GError *error = NULL;
3785   QueryInfoAsyncData *data;
3786   GFileInfo *info;
3787   
3788   data = g_simple_async_result_get_op_res_gpointer (res);
3789   
3790   info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error);
3791
3792   if (info == NULL)
3793     {
3794       g_simple_async_result_set_from_error (res, error);
3795       g_error_free (error);
3796     }
3797   else
3798     data->info = info;
3799 }
3800
3801 static void
3802 g_file_real_query_info_async (GFile               *file,
3803                               const char          *attributes,
3804                               GFileQueryInfoFlags  flags,
3805                               int                  io_priority,
3806                               GCancellable        *cancellable,
3807                               GAsyncReadyCallback  callback,
3808                               gpointer             user_data)
3809 {
3810   GSimpleAsyncResult *res;
3811   QueryInfoAsyncData *data;
3812
3813   data = g_new0 (QueryInfoAsyncData, 1);
3814   data->attributes = g_strdup (attributes);
3815   data->flags = flags;
3816   
3817   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_info_async);
3818   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_info_data_free);
3819   
3820   g_simple_async_result_run_in_thread (res, query_info_async_thread, io_priority, cancellable);
3821   g_object_unref (res);
3822 }
3823
3824 static GFileInfo *
3825 g_file_real_query_info_finish (GFile         *file,
3826                                GAsyncResult  *res,
3827                                GError       **error)
3828 {
3829   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3830   QueryInfoAsyncData *data;
3831
3832   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_info_async);
3833
3834   data = g_simple_async_result_get_op_res_gpointer (simple);
3835   if (data->info)
3836     return g_object_ref (data->info);
3837   
3838   return NULL;
3839 }
3840
3841 typedef struct {
3842   char *attributes;
3843   GFileInfo *info;
3844 } QueryFilesystemInfoAsyncData;
3845
3846 static void
3847 query_filesystem_info_data_free (QueryFilesystemInfoAsyncData *data)
3848 {
3849   if (data->info)
3850     g_object_unref (data->info);
3851   g_free (data->attributes);
3852   g_free (data);
3853 }
3854
3855 static void
3856 query_filesystem_info_async_thread (GSimpleAsyncResult *res,
3857                                     GObject            *object,
3858                                     GCancellable       *cancellable)
3859 {
3860   GError *error = NULL;
3861   QueryFilesystemInfoAsyncData *data;
3862   GFileInfo *info;
3863   
3864   data = g_simple_async_result_get_op_res_gpointer (res);
3865   
3866   info = g_file_query_filesystem_info (G_FILE (object), data->attributes, cancellable, &error);
3867
3868   if (info == NULL)
3869     {
3870       g_simple_async_result_set_from_error (res, error);
3871       g_error_free (error);
3872     }
3873   else
3874     data->info = info;
3875 }
3876
3877 static void
3878 g_file_real_query_filesystem_info_async (GFile               *file,
3879                                          const char          *attributes,
3880                                          int                  io_priority,
3881                                          GCancellable        *cancellable,
3882                                          GAsyncReadyCallback  callback,
3883                                          gpointer             user_data)
3884 {
3885   GSimpleAsyncResult *res;
3886   QueryFilesystemInfoAsyncData *data;
3887
3888   data = g_new0 (QueryFilesystemInfoAsyncData, 1);
3889   data->attributes = g_strdup (attributes);
3890   
3891   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_filesystem_info_async);
3892   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_filesystem_info_data_free);
3893   
3894   g_simple_async_result_run_in_thread (res, query_filesystem_info_async_thread, io_priority, cancellable);
3895   g_object_unref (res);
3896 }
3897
3898 static GFileInfo *
3899 g_file_real_query_filesystem_info_finish (GFile         *file,
3900                                           GAsyncResult  *res,
3901                                           GError       **error)
3902 {
3903   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3904   QueryFilesystemInfoAsyncData *data;
3905
3906   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_filesystem_info_async);
3907
3908   data = g_simple_async_result_get_op_res_gpointer (simple);
3909   if (data->info)
3910     return g_object_ref (data->info);
3911   
3912   return NULL;
3913 }
3914
3915 typedef struct {
3916   char *attributes;
3917   GFileQueryInfoFlags flags;
3918   GFileEnumerator *enumerator;
3919 } EnumerateChildrenAsyncData;
3920
3921 static void
3922 enumerate_children_data_free (EnumerateChildrenAsyncData *data)
3923 {
3924   if (data->enumerator)
3925     g_object_unref (data->enumerator);
3926   g_free (data->attributes);
3927   g_free (data);
3928 }
3929
3930 static void
3931 enumerate_children_async_thread (GSimpleAsyncResult *res,
3932                                  GObject            *object,
3933                                  GCancellable       *cancellable)
3934 {
3935   GError *error = NULL;
3936   EnumerateChildrenAsyncData *data;
3937   GFileEnumerator *enumerator;
3938   
3939   data = g_simple_async_result_get_op_res_gpointer (res);
3940   
3941   enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error);
3942
3943   if (enumerator == NULL)
3944     {
3945       g_simple_async_result_set_from_error (res, error);
3946       g_error_free (error);
3947     }
3948   else
3949     data->enumerator = enumerator;
3950 }
3951
3952 static void
3953 g_file_real_enumerate_children_async (GFile               *file,
3954                                       const char          *attributes,
3955                                       GFileQueryInfoFlags  flags,
3956                                       int                  io_priority,
3957                                       GCancellable        *cancellable,
3958                                       GAsyncReadyCallback  callback,
3959                                       gpointer             user_data)
3960 {
3961   GSimpleAsyncResult *res;
3962   EnumerateChildrenAsyncData *data;
3963
3964   data = g_new0 (EnumerateChildrenAsyncData, 1);
3965   data->attributes = g_strdup (attributes);
3966   data->flags = flags;
3967   
3968   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_enumerate_children_async);
3969   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)enumerate_children_data_free);
3970   
3971   g_simple_async_result_run_in_thread (res, enumerate_children_async_thread, io_priority, cancellable);
3972   g_object_unref (res);
3973 }
3974
3975 static GFileEnumerator *
3976 g_file_real_enumerate_children_finish (GFile         *file,
3977                                        GAsyncResult  *res,
3978                                        GError       **error)
3979 {
3980   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3981   EnumerateChildrenAsyncData *data;
3982
3983   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_enumerate_children_async);
3984
3985   data = g_simple_async_result_get_op_res_gpointer (simple);
3986   if (data->enumerator)
3987     return g_object_ref (data->enumerator);
3988   
3989   return NULL;
3990 }
3991
3992 static void
3993 open_read_async_thread (GSimpleAsyncResult *res,
3994                         GObject            *object,
3995                         GCancellable       *cancellable)
3996 {
3997   GFileIface *iface;
3998   GFileInputStream *stream;
3999   GError *error = NULL;
4000
4001   iface = G_FILE_GET_IFACE (object);
4002
4003   stream = iface->read_fn (G_FILE (object), cancellable, &error);
4004
4005   if (stream == NULL)
4006     {
4007       g_simple_async_result_set_from_error (res, error);
4008       g_error_free (error);
4009     }
4010   else
4011     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
4012 }
4013
4014 static void
4015 g_file_real_read_async (GFile               *file,
4016                         int                  io_priority,
4017                         GCancellable        *cancellable,
4018                         GAsyncReadyCallback  callback,
4019                         gpointer             user_data)
4020 {
4021   GSimpleAsyncResult *res;
4022   
4023   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_read_async);
4024   
4025   g_simple_async_result_run_in_thread (res, open_read_async_thread, io_priority, cancellable);
4026   g_object_unref (res);
4027 }
4028
4029 static GFileInputStream *
4030 g_file_real_read_finish (GFile         *file,
4031                          GAsyncResult  *res,
4032                          GError       **error)
4033 {
4034   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4035   gpointer op;
4036
4037   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_read_async);
4038
4039   op = g_simple_async_result_get_op_res_gpointer (simple);
4040   if (op)
4041     return g_object_ref (op);
4042   
4043   return NULL;
4044 }
4045
4046 static void
4047 append_to_async_thread (GSimpleAsyncResult *res,
4048                         GObject            *object,
4049                         GCancellable       *cancellable)
4050 {
4051   GFileIface *iface;
4052   GFileCreateFlags *data;
4053   GFileOutputStream *stream;
4054   GError *error = NULL;
4055
4056   iface = G_FILE_GET_IFACE (object);
4057
4058   data = g_simple_async_result_get_op_res_gpointer (res);
4059
4060   stream = iface->append_to (G_FILE (object), *data, cancellable, &error);
4061
4062   if (stream == NULL)
4063     {
4064       g_simple_async_result_set_from_error (res, error);
4065       g_error_free (error);
4066     }
4067   else
4068     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
4069 }
4070
4071 static void
4072 g_file_real_append_to_async (GFile               *file,
4073                              GFileCreateFlags     flags,
4074                              int                  io_priority,
4075                              GCancellable        *cancellable,
4076                              GAsyncReadyCallback  callback,
4077                              gpointer             user_data)
4078 {
4079   GFileCreateFlags *data;
4080   GSimpleAsyncResult *res;
4081
4082   data = g_new0 (GFileCreateFlags, 1);
4083   *data = flags;
4084
4085   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_append_to_async);
4086   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
4087
4088   g_simple_async_result_run_in_thread (res, append_to_async_thread, io_priority, cancellable);
4089   g_object_unref (res);
4090 }
4091
4092 static GFileOutputStream *
4093 g_file_real_append_to_finish (GFile         *file,
4094                               GAsyncResult  *res,
4095                               GError       **error)
4096 {
4097   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4098   gpointer op;
4099
4100   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_append_to_async);
4101
4102   op = g_simple_async_result_get_op_res_gpointer (simple);
4103   if (op)
4104     return g_object_ref (op);
4105   
4106   return NULL;
4107 }
4108
4109 static void
4110 create_async_thread (GSimpleAsyncResult *res,
4111                      GObject            *object,
4112                      GCancellable       *cancellable)
4113 {
4114   GFileIface *iface;
4115   GFileCreateFlags *data;
4116   GFileOutputStream *stream;
4117   GError *error = NULL;
4118
4119   iface = G_FILE_GET_IFACE (object);
4120
4121   data = g_simple_async_result_get_op_res_gpointer (res);
4122
4123   stream = iface->create (G_FILE (object), *data, cancellable, &error);
4124
4125   if (stream == NULL)
4126     {
4127       g_simple_async_result_set_from_error (res, error);
4128       g_error_free (error);
4129     }
4130   else
4131     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
4132 }
4133
4134 static void
4135 g_file_real_create_async (GFile               *file,
4136                           GFileCreateFlags     flags,
4137                           int                  io_priority,
4138                           GCancellable        *cancellable,
4139                           GAsyncReadyCallback  callback,
4140                           gpointer             user_data)
4141 {
4142   GFileCreateFlags *data;
4143   GSimpleAsyncResult *res;
4144
4145   data = g_new0 (GFileCreateFlags, 1);
4146   *data = flags;
4147
4148   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_create_async);
4149   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
4150
4151   g_simple_async_result_run_in_thread (res, create_async_thread, io_priority, cancellable);
4152   g_object_unref (res);
4153 }
4154
4155 static GFileOutputStream *
4156 g_file_real_create_finish (GFile         *file,
4157                            GAsyncResult  *res,
4158                            GError       **error)
4159 {
4160   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4161   gpointer op;
4162
4163   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_create_async);
4164
4165   op = g_simple_async_result_get_op_res_gpointer (simple);
4166   if (op)
4167     return g_object_ref (op);
4168   
4169   return NULL;
4170 }
4171
4172 typedef struct {
4173   GFileOutputStream *stream;
4174   char *etag;
4175   gboolean make_backup;
4176   GFileCreateFlags flags;
4177 } ReplaceAsyncData;
4178
4179 static void
4180 replace_async_data_free (ReplaceAsyncData *data)
4181 {
4182   if (data->stream)
4183     g_object_unref (data->stream);
4184   g_free (data->etag);
4185   g_free (data);
4186 }
4187
4188 static void
4189 replace_async_thread (GSimpleAsyncResult *res,
4190                       GObject            *object,
4191                       GCancellable       *cancellable)
4192 {
4193   GFileIface *iface;
4194   GFileOutputStream *stream;
4195   GError *error = NULL;
4196   ReplaceAsyncData *data;
4197
4198   iface = G_FILE_GET_IFACE (object);
4199   
4200   data = g_simple_async_result_get_op_res_gpointer (res);
4201
4202   stream = iface->replace (G_FILE (object),
4203                            data->etag,
4204                            data->make_backup,
4205                            data->flags,
4206                            cancellable,
4207                            &error);
4208
4209   if (stream == NULL)
4210     {
4211       g_simple_async_result_set_from_error (res, error);
4212       g_error_free (error);
4213     }
4214   else
4215     data->stream = stream;
4216 }
4217
4218 static void
4219 g_file_real_replace_async (GFile               *file,
4220                            const char          *etag,
4221                            gboolean             make_backup,
4222                            GFileCreateFlags     flags,
4223                            int                  io_priority,
4224                            GCancellable        *cancellable,
4225                            GAsyncReadyCallback  callback,
4226                            gpointer             user_data)
4227 {
4228   GSimpleAsyncResult *res;
4229   ReplaceAsyncData *data;
4230
4231   data = g_new0 (ReplaceAsyncData, 1);
4232   data->etag = g_strdup (etag);
4233   data->make_backup = make_backup;
4234   data->flags = flags;
4235
4236   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_replace_async);
4237   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_async_data_free);
4238
4239   g_simple_async_result_run_in_thread (res, replace_async_thread, io_priority, cancellable);
4240   g_object_unref (res);
4241 }
4242
4243 static GFileOutputStream *
4244 g_file_real_replace_finish (GFile         *file,
4245                             GAsyncResult  *res,
4246                             GError       **error)
4247 {
4248   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4249   ReplaceAsyncData *data;
4250
4251   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_replace_async);
4252
4253   data = g_simple_async_result_get_op_res_gpointer (simple);
4254   if (data->stream)
4255     return g_object_ref (data->stream);
4256   
4257   return NULL;
4258 }
4259
4260 typedef struct {
4261   char *name;
4262   GFile *file;
4263 } SetDisplayNameAsyncData;
4264
4265 static void
4266 set_display_name_data_free (SetDisplayNameAsyncData *data)
4267 {
4268   g_free (data->name);
4269   if (data->file)
4270     g_object_unref (data->file);
4271   g_free (data);
4272 }
4273
4274 static void
4275 set_display_name_async_thread (GSimpleAsyncResult *res,
4276                                GObject            *object,
4277                                GCancellable       *cancellable)
4278 {
4279   GError *error = NULL;
4280   SetDisplayNameAsyncData *data;
4281   GFile *file;
4282   
4283   data = g_simple_async_result_get_op_res_gpointer (res);
4284   
4285   file = g_file_set_display_name (G_FILE (object), data->name, cancellable, &error);
4286
4287   if (file == NULL)
4288     {
4289       g_simple_async_result_set_from_error (res, error);
4290       g_error_free (error);
4291     }
4292   else
4293     data->file = file;
4294 }
4295
4296 static void
4297 g_file_real_set_display_name_async (GFile               *file,  
4298                                     const char          *display_name,
4299                                     int                  io_priority,
4300                                     GCancellable        *cancellable,
4301                                     GAsyncReadyCallback  callback,
4302                                     gpointer             user_data)
4303 {
4304   GSimpleAsyncResult *res;
4305   SetDisplayNameAsyncData *data;
4306
4307   data = g_new0 (SetDisplayNameAsyncData, 1);
4308   data->name = g_strdup (display_name);
4309   
4310   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_display_name_async);
4311   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_display_name_data_free);
4312   
4313   g_simple_async_result_run_in_thread (res, set_display_name_async_thread, io_priority, cancellable);
4314   g_object_unref (res);
4315 }
4316
4317 static GFile *
4318 g_file_real_set_display_name_finish (GFile         *file,
4319                                      GAsyncResult  *res,
4320                                      GError       **error)
4321 {
4322   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4323   SetDisplayNameAsyncData *data;
4324
4325   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_display_name_async);
4326
4327   data = g_simple_async_result_get_op_res_gpointer (simple);
4328   if (data->file)
4329     return g_object_ref (data->file);
4330   
4331   return NULL;
4332 }
4333
4334 typedef struct {
4335   GFileQueryInfoFlags flags;
4336   GFileInfo *info;
4337   gboolean res;
4338   GError *error;
4339 } SetInfoAsyncData;
4340
4341 static void
4342 set_info_data_free (SetInfoAsyncData *data)
4343 {
4344   if (data->info)
4345     g_object_unref (data->info);
4346   if (data->error)
4347     g_error_free (data->error);
4348   g_free (data);
4349 }
4350
4351 static void
4352 set_info_async_thread (GSimpleAsyncResult *res,
4353                        GObject            *object,
4354                        GCancellable       *cancellable)
4355 {
4356   SetInfoAsyncData *data;
4357   
4358   data = g_simple_async_result_get_op_res_gpointer (res);
4359   
4360   data->error = NULL;
4361   data->res = g_file_set_attributes_from_info (G_FILE (object),
4362                                                data->info,
4363                                                data->flags,
4364                                                cancellable,
4365                                                &data->error);
4366 }
4367
4368 static void
4369 g_file_real_set_attributes_async (GFile               *file,
4370                                   GFileInfo           *info,
4371                                   GFileQueryInfoFlags  flags,
4372                                   int                  io_priority,
4373                                   GCancellable        *cancellable,
4374                                   GAsyncReadyCallback  callback,
4375                                   gpointer             user_data)
4376 {
4377   GSimpleAsyncResult *res;
4378   SetInfoAsyncData *data;
4379
4380   data = g_new0 (SetInfoAsyncData, 1);
4381   data->info = g_file_info_dup (info);
4382   data->flags = flags;
4383   
4384   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_attributes_async);
4385   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_info_data_free);
4386   
4387   g_simple_async_result_run_in_thread (res, set_info_async_thread, io_priority, cancellable);
4388   g_object_unref (res);
4389 }
4390
4391 static gboolean
4392 g_file_real_set_attributes_finish (GFile         *file,
4393                                    GAsyncResult  *res,
4394                                    GFileInfo    **info,
4395                                    GError       **error)
4396 {
4397   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4398   SetInfoAsyncData *data;
4399   
4400   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_attributes_async);
4401
4402   data = g_simple_async_result_get_op_res_gpointer (simple);
4403
4404   if (info) 
4405     *info = g_object_ref (data->info);
4406
4407   if (error != NULL && data->error) 
4408     *error = g_error_copy (data->error);
4409   
4410   return data->res;
4411 }
4412
4413 static void
4414 find_enclosing_mount_async_thread (GSimpleAsyncResult *res,
4415                                     GObject            *object,
4416                                     GCancellable       *cancellable)
4417 {
4418   GError *error = NULL;
4419   GMount *mount;
4420   
4421   mount = g_file_find_enclosing_mount (G_FILE (object), cancellable, &error);
4422
4423   if (mount == NULL)
4424     {
4425       g_simple_async_result_set_from_error (res, error);
4426       g_error_free (error);
4427     }
4428   else
4429     g_simple_async_result_set_op_res_gpointer (res, mount, (GDestroyNotify)g_object_unref);
4430 }
4431
4432 static void
4433 g_file_real_find_enclosing_mount_async (GFile               *file,
4434                                         int                  io_priority,
4435                                         GCancellable        *cancellable,
4436                                         GAsyncReadyCallback  callback,
4437                                         gpointer             user_data)
4438 {
4439   GSimpleAsyncResult *res;
4440   
4441   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_find_enclosing_mount_async);
4442   
4443   g_simple_async_result_run_in_thread (res, find_enclosing_mount_async_thread, io_priority, cancellable);
4444   g_object_unref (res);
4445 }
4446
4447 static GMount *
4448 g_file_real_find_enclosing_mount_finish (GFile         *file,
4449                                           GAsyncResult  *res,
4450                                           GError       **error)
4451 {
4452   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4453   GMount *mount;
4454
4455   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_find_enclosing_mount_async);
4456
4457   mount = g_simple_async_result_get_op_res_gpointer (simple);
4458   return g_object_ref (mount);
4459 }
4460
4461
4462 typedef struct {
4463   GFile *source;
4464   GFile *destination;
4465   GFileCopyFlags flags;
4466   GFileProgressCallback progress_cb;
4467   gpointer progress_cb_data;
4468   GIOSchedulerJob *job;
4469 } CopyAsyncData;
4470
4471 static void
4472 copy_async_data_free (CopyAsyncData *data)
4473 {
4474   g_object_unref (data->source);
4475   g_object_unref (data->destination);
4476   g_free (data);
4477 }
4478
4479 typedef struct {
4480   CopyAsyncData *data;
4481   goffset current_num_bytes;
4482   goffset total_num_bytes;
4483 } ProgressData;
4484
4485 static gboolean
4486 copy_async_progress_in_main (gpointer user_data)
4487 {
4488   ProgressData *progress = user_data;
4489   CopyAsyncData *data = progress->data;
4490
4491   data->progress_cb (progress->current_num_bytes,
4492                      progress->total_num_bytes,
4493                      data->progress_cb_data);
4494
4495   return FALSE;
4496 }
4497
4498 static gboolean
4499 mainloop_barrier (gpointer user_data)
4500 {
4501   /* Does nothing, but ensures all queued idles before
4502      this are run */
4503   return FALSE;
4504 }
4505
4506
4507 static void
4508 copy_async_progress_callback (goffset  current_num_bytes,
4509                               goffset  total_num_bytes,
4510                               gpointer user_data)
4511 {
4512   CopyAsyncData *data = user_data;
4513   ProgressData *progress;
4514
4515   progress = g_new (ProgressData, 1);
4516   progress->data = data;
4517   progress->current_num_bytes = current_num_bytes;
4518   progress->total_num_bytes = total_num_bytes;
4519   
4520   g_io_scheduler_job_send_to_mainloop_async (data->job,
4521                                              copy_async_progress_in_main,
4522                                              progress,
4523                                              g_free);
4524 }
4525
4526 static gboolean
4527 copy_async_thread (GIOSchedulerJob *job,
4528                    GCancellable    *cancellable,
4529                    gpointer         user_data)
4530 {
4531   GSimpleAsyncResult *res;
4532   CopyAsyncData *data;
4533   gboolean result;
4534   GError *error;
4535
4536   res = user_data;
4537   data = g_simple_async_result_get_op_res_gpointer (res);
4538
4539   error = NULL;
4540   data->job = job;
4541   result = g_file_copy (data->source,
4542                         data->destination,
4543                         data->flags,
4544                         cancellable,
4545                         (data->progress_cb != NULL) ? copy_async_progress_callback : NULL,
4546                         data,
4547                         &error);
4548
4549   /* Ensure all progress callbacks are done running in main thread */
4550   if (data->progress_cb != NULL)
4551     g_io_scheduler_job_send_to_mainloop (job,
4552                                          mainloop_barrier,
4553                                          NULL, NULL);
4554   
4555   if (!result)
4556     {
4557       g_simple_async_result_set_from_error (res, error);
4558       g_error_free (error);
4559     }
4560
4561   g_simple_async_result_complete_in_idle (res);
4562
4563   return FALSE;
4564 }
4565
4566 static void
4567 g_file_real_copy_async (GFile                  *source,
4568                         GFile                  *destination,
4569                         GFileCopyFlags          flags,
4570                         int                     io_priority,
4571                         GCancellable           *cancellable,
4572                         GFileProgressCallback   progress_callback,
4573                         gpointer                progress_callback_data,
4574                         GAsyncReadyCallback     callback,
4575                         gpointer                user_data)
4576 {
4577   GSimpleAsyncResult *res;
4578   CopyAsyncData *data;
4579
4580   data = g_new0 (CopyAsyncData, 1);
4581   data->source = g_object_ref (source);
4582   data->destination = g_object_ref (destination);
4583   data->flags = flags;
4584   data->progress_cb = progress_callback;
4585   data->progress_cb_data = progress_callback_data;
4586
4587   res = g_simple_async_result_new (G_OBJECT (source), callback, user_data, g_file_real_copy_async);
4588   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)copy_async_data_free);
4589
4590   g_io_scheduler_push_job (copy_async_thread, res, g_object_unref, io_priority, cancellable);
4591 }
4592
4593 static gboolean
4594 g_file_real_copy_finish (GFile        *file,
4595                          GAsyncResult *res,
4596                          GError      **error)
4597 {
4598   /* Error handled in g_file_copy_finish() */
4599   return TRUE;
4600 }
4601
4602
4603 /********************************************
4604  *   Default VFS operations                 *
4605  ********************************************/
4606
4607 /**
4608  * g_file_new_for_path:
4609  * @path: a string containing a relative or absolute path.
4610  * 
4611  * Constructs a #GFile for a given path. This operation never
4612  * fails, but the returned object might not support any I/O
4613  * operation if @path is malformed.
4614  * 
4615  * Returns: a new #GFile for the given @path. 
4616  **/
4617 GFile *
4618 g_file_new_for_path (const char *path)
4619 {
4620   g_return_val_if_fail (path != NULL, NULL);
4621
4622   return g_vfs_get_file_for_path (g_vfs_get_default (), path);
4623 }
4624  
4625 /**
4626  * g_file_new_for_uri:
4627  * @uri: a string containing a URI.
4628  * 
4629  * Constructs a #GFile for a given URI. This operation never 
4630  * fails, but the returned object might not support any I/O 
4631  * operation if @uri is malformed or if the uri type is 
4632  * not supported.
4633  * 
4634  * Returns: a #GFile for the given @uri.
4635  **/ 
4636 GFile *
4637 g_file_new_for_uri (const char *uri)
4638 {
4639   g_return_val_if_fail (uri != NULL, NULL);
4640
4641   return g_vfs_get_file_for_uri (g_vfs_get_default (), uri);
4642 }
4643   
4644 /**
4645  * g_file_parse_name:
4646  * @parse_name: a file name or path to be parsed.
4647  * 
4648  * Constructs a #GFile with the given @parse_name (i.e. something given by g_file_get_parse_name()).
4649  * This operation never fails, but the returned object might not support any I/O
4650  * operation if the @parse_name cannot be parsed.
4651  * 
4652  * Returns: a new #GFile.
4653  **/
4654 GFile *
4655 g_file_parse_name (const char *parse_name)
4656 {
4657   g_return_val_if_fail (parse_name != NULL, NULL);
4658
4659   return g_vfs_parse_name (g_vfs_get_default (), parse_name);
4660 }
4661
4662 static gboolean
4663 is_valid_scheme_character (char c)
4664 {
4665   return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.';
4666 }
4667
4668 static gboolean
4669 has_valid_scheme (const char *uri)
4670 {
4671   const char *p;
4672   
4673   p = uri;
4674   
4675   if (!is_valid_scheme_character (*p))
4676     return FALSE;
4677
4678   do {
4679     p++;
4680   } while (is_valid_scheme_character (*p));
4681
4682   return *p == ':';
4683 }
4684
4685 /**
4686  * g_file_new_for_commandline_arg:
4687  * @arg: a command line string.
4688  * 
4689  * Creates a #GFile with the given argument from the command line. The value of
4690  * @arg can be either a URI, an absolute path or a relative path resolved
4691  * relative to the current working directory.
4692  * This operation never fails, but the returned object might not support any
4693  * I/O operation if @arg points to a malformed path.
4694  *
4695  * Returns: a new #GFile. 
4696  **/
4697 GFile *
4698 g_file_new_for_commandline_arg (const char *arg)
4699 {
4700   GFile *file;
4701   char *filename;
4702   char *current_dir;
4703   
4704   g_return_val_if_fail (arg != NULL, NULL);
4705   
4706   if (g_path_is_absolute (arg))
4707     return g_file_new_for_path (arg);
4708
4709   if (has_valid_scheme (arg))
4710     return g_file_new_for_uri (arg);
4711     
4712   current_dir = g_get_current_dir ();
4713   filename = g_build_filename (current_dir, arg, NULL);
4714   g_free (current_dir);
4715   
4716   file = g_file_new_for_path (filename);
4717   g_free (filename);
4718   
4719   return file;
4720 }
4721
4722 /**
4723  * g_file_mount_enclosing_volume:
4724  * @location: input #GFile.
4725  * @flags: flags affecting the operation
4726  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
4727  * @cancellable: optional #GCancellable object, %NULL to ignore.
4728  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
4729  * @user_data: the data to pass to callback function
4730  * 
4731  * Starts a @mount_operation, mounting the volume that contains the file @location. 
4732  * 
4733  * When this operation has completed, @callback will be called with
4734  * @user_user data, and the operation can be finalized with 
4735  * g_file_mount_enclosing_volume_finish().
4736  * 
4737  * If @cancellable is not %NULL, then the operation can be cancelled by
4738  * triggering the cancellable object from another thread. If the operation
4739  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4740  **/
4741 void
4742 g_file_mount_enclosing_volume (GFile               *location,
4743                                GMountMountFlags     flags,
4744                                GMountOperation     *mount_operation,
4745                                GCancellable        *cancellable,
4746                                GAsyncReadyCallback  callback,
4747                                gpointer             user_data)
4748 {
4749   GFileIface *iface;
4750
4751   g_return_if_fail (G_IS_FILE (location));
4752
4753   iface = G_FILE_GET_IFACE (location);
4754
4755   if (iface->mount_enclosing_volume == NULL)
4756     {
4757       g_simple_async_report_error_in_idle (G_OBJECT (location),
4758                                            callback, user_data,
4759                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
4760                                            _("volume doesn't implement mount"));
4761       
4762       return;
4763     }
4764   
4765   (* iface->mount_enclosing_volume) (location, flags, mount_operation, cancellable, callback, user_data);
4766
4767 }
4768
4769 /**
4770  * g_file_mount_enclosing_volume_finish:
4771  * @location: input #GFile.
4772  * @result: a #GAsyncResult.
4773  * @error: a #GError, or %NULL
4774  * 
4775  * Finishes a mount operation started by g_file_mount_enclosing_volume().
4776  * 
4777  * Returns: %TRUE if successful. If an error
4778  * has occurred, this function will return %FALSE and set @error
4779  * appropriately if present.
4780  **/
4781 gboolean
4782 g_file_mount_enclosing_volume_finish (GFile         *location,
4783                                       GAsyncResult  *result,
4784                                       GError       **error)
4785 {
4786   GFileIface *iface;
4787
4788   g_return_val_if_fail (G_IS_FILE (location), FALSE);
4789   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4790
4791   if (G_IS_SIMPLE_ASYNC_RESULT (result))
4792     {
4793       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
4794       if (g_simple_async_result_propagate_error (simple, error))
4795         return FALSE;
4796     }
4797   
4798   iface = G_FILE_GET_IFACE (location);
4799
4800   return (* iface->mount_enclosing_volume_finish) (location, result, error);
4801 }
4802
4803 /********************************************
4804  *   Utility functions                      *
4805  ********************************************/
4806
4807 /**
4808  * g_file_query_default_handler:
4809  * @file: a #GFile to open.
4810  * @cancellable: optional #GCancellable object, %NULL to ignore.
4811  * @error: a #GError, or %NULL
4812  *
4813  * Returns the #GAppInfo that is registered as the default
4814  * application to handle the file specified by @file.
4815  *
4816  * If @cancellable is not %NULL, then the operation can be cancelled by
4817  * triggering the cancellable object from another thread. If the operation
4818  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4819  *
4820  * Returns: a #GAppInfo if the handle was found, %NULL if there were errors.
4821  * When you are done with it, release it with g_object_unref()
4822  **/
4823 GAppInfo *
4824 g_file_query_default_handler (GFile                  *file,
4825                               GCancellable           *cancellable,
4826                               GError                **error)
4827 {
4828   char *uri_scheme;
4829   const char *content_type;
4830   GAppInfo *appinfo;
4831   GFileInfo *info;
4832   char *path;
4833   
4834   uri_scheme = g_file_get_uri_scheme (file);
4835   appinfo = g_app_info_get_default_for_uri_scheme (uri_scheme);
4836   g_free (uri_scheme);
4837
4838   if (appinfo != NULL)
4839     return appinfo;
4840
4841   info = g_file_query_info (file,
4842                             G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
4843                             0,
4844                             cancellable,
4845                             error);
4846   if (info == NULL)
4847     return NULL;
4848
4849   appinfo = NULL;
4850
4851   content_type = g_file_info_get_content_type (info);
4852   if (content_type)
4853     {
4854       /* Don't use is_native(), as we want to support fuse paths if availible */
4855       path = g_file_get_path (file);
4856       appinfo = g_app_info_get_default_for_type (content_type,
4857                                                  path == NULL);
4858       g_free (path);
4859     }
4860   
4861   g_object_unref (info);
4862
4863   if (appinfo != NULL)
4864     return appinfo;
4865
4866   g_set_error (error, G_IO_ERROR,
4867                G_IO_ERROR_NOT_SUPPORTED,
4868                _("No application is registered as handling this file"));
4869   return NULL;
4870   
4871 }
4872
4873
4874 #define GET_CONTENT_BLOCK_SIZE 8192
4875
4876 /**
4877  * g_file_load_contents:
4878  * @file: input #GFile.
4879  * @cancellable: optional #GCancellable object, %NULL to ignore.
4880  * @contents: a location to place the contents of the file.
4881  * @length: a location to place the length of the contents of the file.
4882  * @etag_out: a location to place the current entity tag for the file.
4883  * @error: a #GError, or %NULL
4884  *
4885  * Loads the content of the file into memory, returning the size of
4886  * the data. The data is always zero terminated, but this is not
4887  * included in the resultant @length.
4888  * 
4889  * If @cancellable is not %NULL, then the operation can be cancelled by
4890  * triggering the cancellable object from another thread. If the operation
4891  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4892  * 
4893  * Returns: %TRUE if the @file's contents were successfully loaded.
4894  * %FALSE if there were errors..
4895  **/
4896 gboolean
4897 g_file_load_contents (GFile         *file,
4898                       GCancellable  *cancellable,
4899                       char         **contents,
4900                       gsize         *length,
4901                       char         **etag_out,
4902                       GError       **error)
4903 {
4904   GFileInputStream *in;
4905   GByteArray *content;
4906   gsize pos;
4907   gssize res;
4908   GFileInfo *info;
4909
4910   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4911   g_return_val_if_fail (contents != NULL, FALSE);
4912
4913   in = g_file_read (file, cancellable, error);
4914   if (in == NULL)
4915     return FALSE;
4916
4917   content = g_byte_array_new ();
4918   pos = 0;
4919   
4920   g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
4921   while ((res = g_input_stream_read (G_INPUT_STREAM (in),
4922                                      content->data + pos,
4923                                      GET_CONTENT_BLOCK_SIZE,
4924                                      cancellable, error)) > 0)
4925     {
4926       pos += res;
4927       g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
4928     }
4929
4930   if (etag_out)
4931     {
4932       *etag_out = NULL;
4933       
4934       info = g_file_input_stream_query_info (in,
4935                                              G_FILE_ATTRIBUTE_ETAG_VALUE,
4936                                              cancellable,
4937                                              NULL);
4938       if (info)
4939         {
4940           *etag_out = g_strdup (g_file_info_get_etag (info));
4941           g_object_unref (info);
4942         }
4943     } 
4944
4945   /* Ignore errors on close */
4946   g_input_stream_close (G_INPUT_STREAM (in), cancellable, NULL);
4947   g_object_unref (in);
4948
4949   if (res < 0)
4950     {
4951       /* error is set already */
4952       g_byte_array_free (content, TRUE);
4953       return FALSE;
4954     }
4955
4956   if (length)
4957     *length = pos;
4958
4959   /* Zero terminate (we got an extra byte allocated for this */
4960   content->data[pos] = 0;
4961   
4962   *contents = (char *)g_byte_array_free (content, FALSE);
4963   
4964   return TRUE;
4965 }
4966
4967 typedef struct {
4968   GFile *file;
4969   GError *error;
4970   GCancellable *cancellable;
4971   GFileReadMoreCallback read_more_callback;
4972   GAsyncReadyCallback callback;
4973   gpointer user_data;
4974   GByteArray *content;
4975   gsize pos;
4976   char *etag;
4977 } LoadContentsData;
4978
4979
4980 static void
4981 load_contents_data_free (LoadContentsData *data)
4982 {
4983   if (data->error)
4984     g_error_free (data->error);
4985   if (data->cancellable)
4986     g_object_unref (data->cancellable);
4987   if (data->content)
4988     g_byte_array_free (data->content, TRUE);
4989   g_free (data->etag);
4990   g_object_unref (data->file);
4991   g_free (data);
4992 }
4993
4994 static void
4995 load_contents_close_callback (GObject      *obj,
4996                               GAsyncResult *close_res,
4997                               gpointer      user_data)
4998 {
4999   GInputStream *stream = G_INPUT_STREAM (obj);
5000   LoadContentsData *data = user_data;
5001   GSimpleAsyncResult *res;
5002
5003   /* Ignore errors here, we're only reading anyway */
5004   g_input_stream_close_finish (stream, close_res, NULL);
5005   g_object_unref (stream);
5006
5007   res = g_simple_async_result_new (G_OBJECT (data->file),
5008                                    data->callback,
5009                                    data->user_data,
5010                                    g_file_load_contents_async);
5011   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)load_contents_data_free);
5012   g_simple_async_result_complete (res);
5013   g_object_unref (res);
5014 }
5015
5016 static void
5017 load_contents_fstat_callback (GObject      *obj,
5018                               GAsyncResult *stat_res,
5019                               gpointer      user_data)
5020 {
5021   GInputStream *stream = G_INPUT_STREAM (obj);
5022   LoadContentsData *data = user_data;
5023   GFileInfo *info;
5024
5025   info = g_file_input_stream_query_info_finish (G_FILE_INPUT_STREAM (stream),
5026                                                    stat_res, NULL);
5027   if (info)
5028     {
5029       data->etag = g_strdup (g_file_info_get_etag (info));
5030       g_object_unref (info);
5031     }
5032
5033   g_input_stream_close_async (stream, 0,
5034                               data->cancellable,
5035                               load_contents_close_callback, data);
5036 }
5037
5038 static void
5039 load_contents_read_callback (GObject      *obj,
5040                              GAsyncResult *read_res,
5041                              gpointer      user_data)
5042 {
5043   GInputStream *stream = G_INPUT_STREAM (obj);
5044   LoadContentsData *data = user_data;
5045   GError *error = NULL;
5046   gssize read_size;
5047
5048   read_size = g_input_stream_read_finish (stream, read_res, &error);
5049
5050   if (read_size < 0) 
5051     {
5052       /* Error or EOF, close the file */
5053       data->error = error;
5054       g_input_stream_close_async (stream, 0,
5055                                   data->cancellable,
5056                                   load_contents_close_callback, data);
5057     }
5058   else if (read_size == 0)
5059     {
5060       g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
5061                                             G_FILE_ATTRIBUTE_ETAG_VALUE,
5062                                             0,
5063                                             data->cancellable,
5064                                             load_contents_fstat_callback,
5065                                             data);
5066     }
5067   else if (read_size > 0)
5068     {
5069       data->pos += read_size;
5070       
5071       g_byte_array_set_size (data->content,
5072                              data->pos + GET_CONTENT_BLOCK_SIZE);
5073
5074
5075       if (data->read_more_callback &&
5076           !data->read_more_callback ((char *)data->content->data, data->pos, data->user_data))
5077         g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
5078                                               G_FILE_ATTRIBUTE_ETAG_VALUE,
5079                                               0,
5080                                               data->cancellable,
5081                                               load_contents_fstat_callback,
5082                                               data);
5083       else 
5084         g_input_stream_read_async (stream,
5085                                    data->content->data + data->pos,
5086                                    GET_CONTENT_BLOCK_SIZE,
5087                                    0,
5088                                    data->cancellable,
5089                                    load_contents_read_callback,
5090                                    data);
5091     }
5092 }
5093
5094 static void
5095 load_contents_open_callback (GObject      *obj,
5096                              GAsyncResult *open_res,
5097                              gpointer      user_data)
5098 {
5099   GFile *file = G_FILE (obj);
5100   GFileInputStream *stream;
5101   LoadContentsData *data = user_data;
5102   GError *error = NULL;
5103   GSimpleAsyncResult *res;
5104
5105   stream = g_file_read_finish (file, open_res, &error);
5106
5107   if (stream)
5108     {
5109       g_byte_array_set_size (data->content,
5110                              data->pos + GET_CONTENT_BLOCK_SIZE);
5111       g_input_stream_read_async (G_INPUT_STREAM (stream),
5112                                  data->content->data + data->pos,
5113                                  GET_CONTENT_BLOCK_SIZE,
5114                                  0,
5115                                  data->cancellable,
5116                                  load_contents_read_callback,
5117                                  data);
5118       
5119     }
5120   else
5121     {
5122       res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
5123                                                   data->callback,
5124                                                   data->user_data,
5125                                                   error);
5126       g_simple_async_result_complete (res);
5127       g_error_free (error);
5128       load_contents_data_free (data);
5129       g_object_unref (res);
5130     }
5131 }
5132
5133 /**
5134  * g_file_load_partial_contents_async:
5135  * @file: input #GFile.
5136  * @cancellable: optional #GCancellable object, %NULL to ignore.
5137  * @read_more_callback: a #GFileReadMoreCallback to receive partial data and to specify whether further data should be read.
5138  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
5139  * @user_data: the data to pass to the callback functions.
5140  *
5141  * Reads the partial contents of a file. A #GFileReadMoreCallback should be 
5142  * used to stop reading from the file when appropriate, else this function
5143  * will behave exactly as g_file_load_contents_async(). This operation 
5144  * can be finished by g_file_load_partial_contents_finish().
5145  *
5146  * Users of this function should be aware that @user_data is passed to 
5147  * both the @read_more_callback and the @callback.
5148  *
5149  * If @cancellable is not %NULL, then the operation can be cancelled by
5150  * triggering the cancellable object from another thread. If the operation
5151  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5152  **/
5153 void
5154 g_file_load_partial_contents_async (GFile                 *file,
5155                                     GCancellable          *cancellable,
5156                                     GFileReadMoreCallback  read_more_callback,
5157                                     GAsyncReadyCallback    callback,
5158                                     gpointer               user_data)
5159 {
5160   LoadContentsData *data;
5161
5162   g_return_if_fail (G_IS_FILE (file));
5163
5164   data = g_new0 (LoadContentsData, 1);
5165
5166   if (cancellable)
5167     data->cancellable = g_object_ref (cancellable);
5168   data->read_more_callback = read_more_callback;
5169   data->callback = callback;
5170   data->user_data = user_data;
5171   data->content = g_byte_array_new ();
5172   data->file = g_object_ref (file);
5173
5174   g_file_read_async (file,
5175                      0,
5176                      cancellable,
5177                      load_contents_open_callback,
5178                      data);
5179 }
5180
5181 /**
5182  * g_file_load_partial_contents_finish:
5183  * @file: input #GFile.
5184  * @res: a #GAsyncResult. 
5185  * @contents: a location to place the contents of the file.
5186  * @length: a location to place the length of the contents of the file.
5187  * @etag_out: a location to place the current entity tag for the file.
5188  * @error: a #GError, or %NULL
5189  * 
5190  * Finishes an asynchronous partial load operation that was started
5191  * with g_file_load_partial_contents_async().
5192  *
5193  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
5194  * present, it will be set appropriately. 
5195  **/
5196 gboolean
5197 g_file_load_partial_contents_finish (GFile         *file,
5198                                      GAsyncResult  *res,
5199                                      char         **contents,
5200                                      gsize         *length,
5201                                      char         **etag_out,
5202                                      GError       **error)
5203 {
5204   GSimpleAsyncResult *simple;
5205   LoadContentsData *data;
5206
5207   g_return_val_if_fail (G_IS_FILE (file), FALSE);
5208   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
5209   g_return_val_if_fail (contents != NULL, FALSE);
5210
5211   simple = G_SIMPLE_ASYNC_RESULT (res);
5212
5213   if (g_simple_async_result_propagate_error (simple, error))
5214     return FALSE;
5215   
5216   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_load_contents_async);
5217   
5218   data = g_simple_async_result_get_op_res_gpointer (simple);
5219
5220   if (data->error)
5221     {
5222       g_propagate_error (error, data->error);
5223       data->error = NULL;
5224       *contents = NULL;
5225       if (length)
5226         *length = 0;
5227       return FALSE;
5228     }
5229
5230   if (length)
5231     *length = data->pos;
5232
5233   if (etag_out)
5234     {
5235       *etag_out = data->etag;
5236       data->etag = NULL;
5237     }
5238
5239   /* Zero terminate */
5240   g_byte_array_set_size (data->content, data->pos + 1);
5241   data->content->data[data->pos] = 0;
5242   
5243   *contents = (char *)g_byte_array_free (data->content, FALSE);
5244   data->content = NULL;
5245
5246   return TRUE;
5247 }
5248
5249 /**
5250  * g_file_load_contents_async:
5251  * @file: input #GFile.
5252  * @cancellable: optional #GCancellable object, %NULL to ignore.
5253  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
5254  * @user_data: the data to pass to callback function
5255  * 
5256  * Starts an asynchronous load of the @file's contents.
5257  *
5258  * For more details, see g_file_load_contents() which is
5259  * the synchronous version of this call.
5260  *
5261  * When the load operation has completed, @callback will be called 
5262  * with @user data. To finish the operation, call 
5263  * g_file_load_contents_finish() with the #GAsyncResult returned by 
5264  * the @callback.
5265  * 
5266  * If @cancellable is not %NULL, then the operation can be cancelled by
5267  * triggering the cancellable object from another thread. If the operation
5268  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5269  **/
5270 void
5271 g_file_load_contents_async (GFile               *file,
5272                            GCancellable        *cancellable,
5273                            GAsyncReadyCallback  callback,
5274                            gpointer             user_data)
5275 {
5276   g_file_load_partial_contents_async (file,
5277                                       cancellable,
5278                                       NULL,
5279                                       callback, user_data);
5280 }
5281
5282 /**
5283  * g_file_load_contents_finish:
5284  * @file: input #GFile.
5285  * @res: a #GAsyncResult. 
5286  * @contents: a location to place the contents of the file.
5287  * @length: a location to place the length of the contents of the file.
5288  * @etag_out: a location to place the current entity tag for the file.
5289  * @error: a #GError, or %NULL
5290  * 
5291  * Finishes an asynchronous load of the @file's contents. 
5292  * The contents are placed in @contents, and @length is set to the 
5293  * size of the @contents string. If @etag_out is present, it will be 
5294  * set to the new entity tag for the @file.
5295  * 
5296  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
5297  * present, it will be set appropriately. 
5298  **/
5299 gboolean
5300 g_file_load_contents_finish (GFile         *file,
5301                              GAsyncResult  *res,
5302                              char         **contents,
5303                              gsize         *length,
5304                              char         **etag_out,
5305                              GError       **error)
5306 {
5307   return g_file_load_partial_contents_finish (file,
5308                                               res,
5309                                               contents,
5310                                               length,
5311                                               etag_out,
5312                                               error);
5313 }
5314   
5315 /**
5316  * g_file_replace_contents:
5317  * @file: input #GFile.
5318  * @contents: a string containing the new contents for @file.
5319  * @length: the length of @contents in bytes.
5320  * @etag: the old <link linkend="gfile-etag">entity tag</link> 
5321  *     for the document.
5322  * @make_backup: %TRUE if a backup should be created.
5323  * @flags: a set of #GFileCreateFlags.
5324  * @new_etag: a location to a new <link linkend="gfile-etag">entity tag</link>
5325  *      for the document. This should be freed with g_free() when no longer 
5326  *      needed.
5327  * @cancellable: optional #GCancellable object, %NULL to ignore.
5328  * @error: a #GError, or %NULL
5329  *
5330  * Replaces the contents of @file with @contents of @length bytes.
5331  
5332  * If @etag is specified (not %NULL) any existing file must have that etag, or
5333  * the error %G_IO_ERROR_WRONG_ETAG will be returned.
5334  *
5335  * If @make_backup is %TRUE, this function will attempt to make a backup of @file.
5336  * 
5337  * If @cancellable is not %NULL, then the operation can be cancelled by
5338  * triggering the cancellable object from another thread. If the operation
5339  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5340  *
5341  * The returned @new_etag can be used to verify that the file hasn't changed the
5342  * next time it is saved over.
5343  * 
5344  * Returns: %TRUE if successful. If an error
5345  * has occurred, this function will return %FALSE and set @error
5346  * appropriately if present.
5347  **/
5348 gboolean
5349 g_file_replace_contents (GFile             *file,
5350                          const char        *contents,
5351                          gsize              length,
5352                          const char        *etag,
5353                          gboolean           make_backup,
5354                          GFileCreateFlags   flags,
5355                          char             **new_etag,
5356                          GCancellable      *cancellable,
5357                          GError           **error)
5358 {
5359   GFileOutputStream *out;
5360   gsize pos, remainder;
5361   gssize res;
5362
5363   g_return_val_if_fail (G_IS_FILE (file), FALSE);
5364   g_return_val_if_fail (contents != NULL, FALSE);
5365
5366   out = g_file_replace (file, etag, make_backup, flags, cancellable, error);
5367   if (out == NULL)
5368     return FALSE;
5369
5370   pos = 0;
5371   remainder = length;
5372   while (remainder > 0 &&
5373          (res = g_output_stream_write (G_OUTPUT_STREAM (out),
5374                                        contents + pos,
5375                                        MIN (remainder, GET_CONTENT_BLOCK_SIZE),
5376                                        cancellable,
5377                                        error)) > 0)
5378     {
5379       pos += res;
5380       remainder -= res;
5381     }
5382   
5383   if (remainder > 0 && res < 0)
5384     {
5385       /* Ignore errors on close */
5386       g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, NULL);
5387       
5388       /* error is set already */
5389       return FALSE;
5390     }
5391   
5392   if (!g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, error))
5393     return FALSE;
5394
5395   if (new_etag)
5396     *new_etag = g_file_output_stream_get_etag (out);
5397   
5398   return TRUE;
5399 }
5400
5401 typedef struct {
5402   GFile *file;
5403   GError *error;
5404   GCancellable *cancellable;
5405   GAsyncReadyCallback callback;
5406   gpointer user_data;
5407   const char *content;
5408   gsize length;
5409   gsize pos;
5410   char *etag;
5411 } ReplaceContentsData;
5412
5413 static void
5414 replace_contents_data_free (ReplaceContentsData *data)
5415 {
5416   if (data->error)
5417     g_error_free (data->error);
5418   if (data->cancellable)
5419     g_object_unref (data->cancellable);
5420   g_object_unref (data->file);
5421   g_free (data->etag);
5422   g_free (data);
5423 }
5424
5425 static void
5426 replace_contents_close_callback (GObject      *obj,
5427                                  GAsyncResult *close_res,
5428                                  gpointer      user_data)
5429 {
5430   GOutputStream *stream = G_OUTPUT_STREAM (obj);
5431   ReplaceContentsData *data = user_data;
5432   GSimpleAsyncResult *res;
5433
5434   /* Ignore errors here, we're only reading anyway */
5435   g_output_stream_close_finish (stream, close_res, NULL);
5436   g_object_unref (stream);
5437
5438   data->etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (stream));
5439   
5440   res = g_simple_async_result_new (G_OBJECT (data->file),
5441                                    data->callback,
5442                                    data->user_data,
5443                                    g_file_replace_contents_async);
5444   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_contents_data_free);
5445   g_simple_async_result_complete (res);
5446   g_object_unref (res);
5447 }
5448
5449 static void
5450 replace_contents_write_callback (GObject      *obj,
5451                                  GAsyncResult *read_res,
5452                                  gpointer      user_data)
5453 {
5454   GOutputStream *stream = G_OUTPUT_STREAM (obj);
5455   ReplaceContentsData *data = user_data;
5456   GError *error = NULL;
5457   gssize write_size;
5458   
5459   write_size = g_output_stream_write_finish (stream, read_res, &error);
5460
5461   if (write_size <= 0) 
5462     {
5463       /* Error or EOF, close the file */
5464       if (write_size < 0)
5465         data->error = error;
5466       g_output_stream_close_async (stream, 0,
5467                                    data->cancellable,
5468                                    replace_contents_close_callback, data);
5469     }
5470   else if (write_size > 0)
5471     {
5472       data->pos += write_size;
5473
5474       if (data->pos >= data->length)
5475         g_output_stream_close_async (stream, 0,
5476                                      data->cancellable,
5477                                      replace_contents_close_callback, data);
5478       else
5479         g_output_stream_write_async (stream,
5480                                      data->content + data->pos,
5481                                      data->length - data->pos,
5482                                      0,
5483                                      data->cancellable,
5484                                      replace_contents_write_callback,
5485                                      data);
5486     }
5487 }
5488
5489 static void
5490 replace_contents_open_callback (GObject      *obj,
5491                                 GAsyncResult *open_res,
5492                                 gpointer      user_data)
5493 {
5494   GFile *file = G_FILE (obj);
5495   GFileOutputStream *stream;
5496   ReplaceContentsData *data = user_data;
5497   GError *error = NULL;
5498   GSimpleAsyncResult *res;
5499
5500   stream = g_file_replace_finish (file, open_res, &error);
5501
5502   if (stream)
5503     {
5504       g_output_stream_write_async (G_OUTPUT_STREAM (stream),
5505                                    data->content + data->pos,
5506                                    data->length - data->pos,
5507                                    0,
5508                                    data->cancellable,
5509                                    replace_contents_write_callback,
5510                                    data);
5511       
5512     }
5513   else
5514     {
5515       res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
5516                                                   data->callback,
5517                                                   data->user_data,
5518                                                   error);
5519       g_simple_async_result_complete (res);
5520       g_error_free (error);
5521       replace_contents_data_free (data);
5522       g_object_unref (res);
5523     }
5524 }
5525
5526 /**
5527  * g_file_replace_contents_async:
5528  * @file: input #GFile.
5529  * @contents: string of contents to replace the file with.
5530  * @length: the length of @contents in bytes.
5531  * @etag: a new <link linkend="gfile-etag">entity tag</link> for the @file.
5532  * @make_backup: %TRUE if a backup should be created.
5533  * @flags: a set of #GFileCreateFlags.
5534  * @cancellable: optional #GCancellable object, %NULL to ignore.
5535  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
5536  * @user_data: the data to pass to callback function
5537  * 
5538  * Starts an asynchronous replacement of @file with the given 
5539  * @contents of @length bytes. @etag will replace the document's 
5540  * current entity tag.
5541  * 
5542  * When this operation has completed, @callback will be called with
5543  * @user_user data, and the operation can be finalized with 
5544  * g_file_replace_contents_finish().
5545  * 
5546  * If @cancellable is not %NULL, then the operation can be cancelled by
5547  * triggering the cancellable object from another thread. If the operation
5548  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5549  * 
5550  * If @make_backup is %TRUE, this function will attempt to 
5551  * make a backup of @file.
5552  **/
5553 void
5554 g_file_replace_contents_async  (GFile               *file,
5555                                 const char          *contents,
5556                                 gsize                length,
5557                                 const char          *etag,
5558                                 gboolean             make_backup,
5559                                 GFileCreateFlags     flags,
5560                                 GCancellable        *cancellable,
5561                                 GAsyncReadyCallback  callback,
5562                                 gpointer             user_data)
5563 {
5564   ReplaceContentsData *data;
5565
5566   g_return_if_fail (G_IS_FILE (file));
5567   g_return_if_fail (contents != NULL);
5568
5569   data = g_new0 (ReplaceContentsData, 1);
5570
5571   if (cancellable)
5572     data->cancellable = g_object_ref (cancellable);
5573   data->callback = callback;
5574   data->user_data = user_data;
5575   data->content = contents;
5576   data->length = length;
5577   data->pos = 0;
5578   data->file = g_object_ref (file);
5579
5580   g_file_replace_async (file,
5581                         etag,
5582                         make_backup,
5583                         flags,
5584                         0,
5585                         cancellable,
5586                         replace_contents_open_callback,
5587                         data);
5588 }
5589   
5590 /**
5591  * g_file_replace_contents_finish:
5592  * @file: input #GFile.
5593  * @res: a #GAsyncResult. 
5594  * @new_etag: a location of a new <link linkend="gfile-etag">entity tag</link> 
5595  *     for the document. This should be freed with g_free() when it is no 
5596  *     longer needed.
5597  * @error: a #GError, or %NULL 
5598  * 
5599  * Finishes an asynchronous replace of the given @file. See
5600  * g_file_replace_contents_async(). Sets @new_etag to the new entity 
5601  * tag for the document, if present.
5602  * 
5603  * Returns: %TRUE on success, %FALSE on failure.
5604  **/
5605 gboolean
5606 g_file_replace_contents_finish (GFile         *file,
5607                                 GAsyncResult  *res,
5608                                 char         **new_etag,
5609                                 GError       **error)
5610 {
5611   GSimpleAsyncResult *simple;
5612   ReplaceContentsData *data;
5613
5614   g_return_val_if_fail (G_IS_FILE (file), FALSE);
5615   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
5616
5617   simple = G_SIMPLE_ASYNC_RESULT (res);
5618
5619   if (g_simple_async_result_propagate_error (simple, error))
5620     return FALSE;
5621   
5622   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_replace_contents_async);
5623   
5624   data = g_simple_async_result_get_op_res_gpointer (simple);
5625
5626   if (data->error)
5627     {
5628       g_propagate_error (error, data->error);
5629       data->error = NULL;
5630       return FALSE;
5631     }
5632
5633
5634   if (new_etag)
5635     {
5636       *new_etag = data->etag;
5637       data->etag = NULL; /* Take ownership */
5638     }
5639   
5640   return TRUE;
5641 }
5642
5643 #define __G_FILE_C__
5644 #include "gioaliasdef.c"