Fix a few typos in translator comments and documentation.
[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       /* Translators: This is an error message when trying to find the
1260          enclosing (user visible) mount of a file, but none exists. */
1261       g_set_error (error, G_IO_ERROR,
1262                    G_IO_ERROR_NOT_FOUND,
1263                    _("Containing mount does not exist"));
1264       return NULL;
1265     }
1266
1267   return (* iface->find_enclosing_mount) (file, cancellable, error);
1268 }
1269 /**
1270  * g_file_find_enclosing_mount_async:
1271  * @file: a #GFile
1272  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1273  *     of the request.
1274  * @cancellable: optional #GCancellable object, %NULL to ignore.
1275  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1276  * @user_data: the data to pass to callback function
1277  *
1278  * Asynchronously gets the mount for the file.
1279  *
1280  * For more details, see g_file_find_enclosing_mount() which is
1281  * the synchronous version of this call.
1282  *
1283  * When the operation is finished, @callback will be called. You can then call
1284  * g_file_find_enclosing_mount_finish() to get the result of the operation.
1285  */
1286 void
1287 g_file_find_enclosing_mount_async (GFile              *file,
1288                                    int                   io_priority,
1289                                    GCancellable         *cancellable,
1290                                    GAsyncReadyCallback   callback,
1291                                    gpointer              user_data)
1292 {
1293   GFileIface *iface;
1294
1295   g_return_if_fail (G_IS_FILE (file));
1296
1297   iface = G_FILE_GET_IFACE (file);
1298   (* iface->find_enclosing_mount_async) (file,
1299                                          io_priority,
1300                                          cancellable,
1301                                          callback,
1302                                          user_data);
1303 }
1304
1305 /**
1306  * g_file_find_enclosing_mount_finish:
1307  * @file: a #GFile
1308  * @res: a #GAsyncResult
1309  * @error: a #GError
1310  * 
1311  * Finishes an asynchronous find mount request. 
1312  * See g_file_find_enclosing_mount_async().
1313  * 
1314  * Returns: #GMount for given @file or %NULL on error.
1315  **/
1316 GMount *
1317 g_file_find_enclosing_mount_finish (GFile         *file,
1318                                     GAsyncResult  *res,
1319                                     GError       **error)
1320 {
1321   GFileIface *iface;
1322   
1323   g_return_val_if_fail (G_IS_FILE (file), NULL);
1324   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1325
1326   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1327     {
1328       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1329       if (g_simple_async_result_propagate_error (simple, error))
1330         return NULL;
1331     }
1332   
1333   iface = G_FILE_GET_IFACE (file);
1334   return (* iface->find_enclosing_mount_finish) (file, res, error);
1335 }
1336
1337
1338 /**
1339  * g_file_read:
1340  * @file: #GFile to read.
1341  * @cancellable: a #GCancellable
1342  * @error: a #GError, or %NULL
1343  *
1344  * Opens a file for reading. The result is a #GFileInputStream that
1345  * can be used to read the contents of the file.
1346  *
1347  * If @cancellable is not %NULL, then the operation can be cancelled by
1348  * triggering the cancellable object from another thread. If the operation
1349  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1350  * 
1351  * If the file does not exist, the G_IO_ERROR_NOT_FOUND error will be returned.
1352  * If the file is a directory, the G_IO_ERROR_IS_DIRECTORY error will be returned.
1353  * Other errors are possible too, and depend on what kind of filesystem the file is on.
1354  *
1355  * Returns: #GFileInputStream or %NULL on error.
1356  **/
1357 GFileInputStream *
1358 g_file_read (GFile         *file,
1359              GCancellable  *cancellable,
1360              GError       **error)
1361 {
1362   GFileIface *iface;
1363   
1364   g_return_val_if_fail (G_IS_FILE (file), NULL);
1365
1366   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1367     return NULL;
1368
1369   iface = G_FILE_GET_IFACE (file);
1370
1371   if (iface->read_fn == NULL)
1372     {
1373       g_set_error (error, G_IO_ERROR,
1374                    G_IO_ERROR_NOT_SUPPORTED,
1375                    _("Operation not supported"));
1376       return NULL;
1377     }
1378   
1379   return (* iface->read_fn) (file, cancellable, error);
1380 }
1381
1382 /**
1383  * g_file_append_to:
1384  * @file: input #GFile.
1385  * @flags: a set of #GFileCreateFlags.
1386  * @cancellable: optional #GCancellable object, %NULL to ignore.
1387  * @error: a #GError, or %NULL
1388  *
1389  * Gets an output stream for appending data to the file. If
1390  * the file doesn't already exist it is created.
1391  *
1392  * By default files created are generally readable by everyone,
1393  * but if you pass #G_FILE_CREATE_PRIVATE in @flags the file
1394  * will be made readable only to the current user, to the level that
1395  * is supported on the target filesystem.
1396  *
1397  * If @cancellable is not %NULL, then the operation can be cancelled by
1398  * triggering the cancellable object from another thread. If the operation
1399  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1400  *
1401  * Some file systems don't allow all file names, and may
1402  * return an G_IO_ERROR_INVALID_FILENAME error.
1403  * If the file is a directory the G_IO_ERROR_IS_DIRECTORY error will be
1404  * returned. Other errors are possible too, and depend on what kind of
1405  * filesystem the file is on.
1406  * 
1407  * Returns: a #GFileOutputStream.
1408  **/
1409 GFileOutputStream *
1410 g_file_append_to (GFile             *file,
1411                   GFileCreateFlags   flags,
1412                   GCancellable      *cancellable,
1413                   GError           **error)
1414 {
1415   GFileIface *iface;
1416
1417   g_return_val_if_fail (G_IS_FILE (file), NULL);
1418
1419   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1420     return NULL;
1421   
1422   iface = G_FILE_GET_IFACE (file);
1423
1424   if (iface->append_to == NULL)
1425     {
1426       g_set_error (error, G_IO_ERROR,
1427                    G_IO_ERROR_NOT_SUPPORTED,
1428                    _("Operation not supported"));
1429       return NULL;
1430     }
1431   
1432   return (* iface->append_to) (file, flags, cancellable, error);
1433 }
1434
1435 /**
1436  * g_file_create:
1437  * @file: input #GFile.
1438  * @flags: a set of #GFileCreateFlags.
1439  * @cancellable: optional #GCancellable object, %NULL to ignore.
1440  * @error: a #GError, or %NULL
1441  *
1442  * Creates a new file and returns an output stream for writing to it.
1443  * The file must not already exists.
1444  *
1445  * By default files created are generally readable by everyone,
1446  * but if you pass #G_FILE_CREATE_PRIVATE in @flags the file
1447  * will be made readable only to the current user, to the level that
1448  * is supported on the target filesystem.
1449  *
1450  * If @cancellable is not %NULL, then the operation can be cancelled by
1451  * triggering the cancellable object from another thread. If the operation
1452  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1453  *
1454  * If a file or directory with this name already exists the G_IO_ERROR_EXISTS
1455  * error will be returned.
1456  * Some file systems don't allow all file names, and may
1457  * return an G_IO_ERROR_INVALID_FILENAME error, and if the name
1458  * is to long G_IO_ERROR_FILENAME_TOO_LONG will be returned.
1459  * Other errors are possible too, and depend on what kind of
1460  * filesystem the file is on.
1461  * 
1462  * Returns: a #GFileOutputStream for the newly created file, or 
1463  * %NULL on error.
1464  **/
1465 GFileOutputStream *
1466 g_file_create (GFile             *file,
1467                GFileCreateFlags   flags,
1468                GCancellable      *cancellable,
1469                GError           **error)
1470 {
1471   GFileIface *iface;
1472   
1473   g_return_val_if_fail (G_IS_FILE (file), NULL);
1474
1475   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1476     return NULL;
1477   
1478   iface = G_FILE_GET_IFACE (file);
1479
1480   if (iface->create == NULL)
1481     {
1482       g_set_error (error, G_IO_ERROR,
1483                    G_IO_ERROR_NOT_SUPPORTED,
1484                    _("Operation not supported"));
1485       return NULL;
1486     }
1487   
1488   return (* iface->create) (file, flags, cancellable, error);
1489 }
1490
1491 /**
1492  * g_file_replace:
1493  * @file: input #GFile.
1494  * @etag: an optional <link linkend="gfile-etag">entity tag</link> for the 
1495  *     current #GFile, or #NULL to ignore.
1496  * @make_backup: %TRUE if a backup should be created.
1497  * @flags: a set of #GFileCreateFlags.
1498  * @cancellable: optional #GCancellable object, %NULL to ignore.
1499  * @error: a #GError, or %NULL
1500  *
1501  * Returns an output stream for overwriting the file, possibly
1502  * creating a backup copy of the file first.
1503  *
1504  * This will try to replace the file in the safest way possible so
1505  * that any errors during the writing will not affect an already
1506  * existing copy of the file. For instance, for local files it
1507  * may write to a temporary file and then atomically rename over
1508  * the destination when the stream is closed.
1509  * 
1510  * By default files created are generally readable by everyone,
1511  * but if you pass #G_FILE_CREATE_PRIVATE in @flags the file
1512  * will be made readable only to the current user, to the level that
1513  * is supported on the target filesystem.
1514  *
1515  * If @cancellable is not %NULL, then the operation can be cancelled by
1516  * triggering the cancellable object from another thread. If the operation
1517  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1518  * 
1519  * If you pass in a non-#NULL @etag value, then this value is
1520  * compared to the current entity tag of the file, and if they differ
1521  * an G_IO_ERROR_WRONG_ETAG error is returned. This generally means
1522  * that the file has been changed since you last read it. You can get
1523  * the new etag from g_file_output_stream_get_etag() after you've
1524  * finished writing and closed the #GFileOutputStream. When you load
1525  * a new file you can use g_file_input_stream_query_info() to get
1526  * the etag of the file.
1527  * 
1528  * If @make_backup is %TRUE, this function will attempt to make a backup
1529  * of the current file before overwriting it. If this fails a G_IO_ERROR_CANT_CREATE_BACKUP
1530  * error will be returned. If you want to replace anyway, try again with
1531  * @make_backup set to %FALSE.
1532  *
1533  * If the file is a directory the G_IO_ERROR_IS_DIRECTORY error will be returned,
1534  * and if the file is some other form of non-regular file then a
1535  * G_IO_ERROR_NOT_REGULAR_FILE error will be returned.
1536  * Some file systems don't allow all file names, and may
1537  * return an G_IO_ERROR_INVALID_FILENAME error, and if the name
1538  * is to long G_IO_ERROR_FILENAME_TOO_LONG will be returned.
1539  * Other errors are possible too, and depend on what kind of
1540  * filesystem the file is on.
1541  *
1542  * Returns: a #GFileOutputStream or %NULL on error. 
1543  **/
1544 GFileOutputStream *
1545 g_file_replace (GFile             *file,
1546                 const char        *etag,
1547                 gboolean           make_backup,
1548                 GFileCreateFlags   flags,
1549                 GCancellable      *cancellable,
1550                 GError           **error)
1551 {
1552   GFileIface *iface;
1553
1554   g_return_val_if_fail (G_IS_FILE (file), NULL);
1555
1556   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1557     return NULL;
1558   
1559   iface = G_FILE_GET_IFACE (file);
1560
1561   if (iface->replace == NULL)
1562     {
1563       g_set_error (error, G_IO_ERROR,
1564                    G_IO_ERROR_NOT_SUPPORTED,
1565                    _("Operation not supported"));
1566       return NULL;
1567     }
1568   
1569   
1570   /* Handle empty tag string as NULL in consistent way. */
1571   if (etag && *etag == 0)
1572     etag = NULL;
1573   
1574   return (* iface->replace) (file, etag, make_backup, flags, cancellable, error);
1575 }
1576
1577 /**
1578  * g_file_read_async:
1579  * @file: input #GFile.
1580  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1581  *     of the request. 
1582  * @cancellable: optional #GCancellable object, %NULL to ignore.
1583  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1584  * @user_data: the data to pass to callback function
1585  *
1586  * Asynchronously opens @file for reading.
1587  *
1588  * For more details, see g_file_read() which is
1589  * the synchronous version of this call.
1590  *
1591  * When the operation is finished, @callback will be called. You can then call
1592  * g_file_read_finish() to get the result of the operation.
1593  **/
1594 void
1595 g_file_read_async (GFile               *file,
1596                    int                  io_priority,
1597                    GCancellable        *cancellable,
1598                    GAsyncReadyCallback  callback,
1599                    gpointer             user_data)
1600 {
1601   GFileIface *iface;
1602   
1603   g_return_if_fail (G_IS_FILE (file));
1604
1605   iface = G_FILE_GET_IFACE (file);
1606   (* iface->read_async) (file,
1607                          io_priority,
1608                          cancellable,
1609                          callback,
1610                          user_data);
1611 }
1612
1613 /**
1614  * g_file_read_finish:
1615  * @file: input #GFile.
1616  * @res: a #GAsyncResult. 
1617  * @error: a #GError, or %NULL
1618  *
1619  * Finishes an asynchronous file read operation started with 
1620  * g_file_read_async(). 
1621  *  
1622  * Returns: a #GFileInputStream or %NULL on error.
1623  **/
1624 GFileInputStream *
1625 g_file_read_finish (GFile         *file,
1626                     GAsyncResult  *res,
1627                     GError       **error)
1628 {
1629   GFileIface *iface;
1630   
1631   g_return_val_if_fail (G_IS_FILE (file), NULL);
1632   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1633
1634   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1635     {
1636       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1637       if (g_simple_async_result_propagate_error (simple, error))
1638         return NULL;
1639     }
1640   
1641   iface = G_FILE_GET_IFACE (file);
1642   return (* iface->read_finish) (file, res, error);
1643 }
1644
1645 /**
1646  * g_file_append_to_async:
1647  * @file: input #GFile.
1648  * @flags: a set of #GFileCreateFlags.
1649  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1650  *     of the request. 
1651  * @cancellable: optional #GCancellable object, %NULL to ignore.
1652  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1653  * @user_data: the data to pass to callback function
1654  * 
1655  * Asynchronously opens @file for appending.
1656  *
1657  * For more details, see g_file_append_to() which is
1658  * the synchronous version of this call.
1659  *
1660  * When the operation is finished, @callback will be called. You can then call
1661  * g_file_append_to_finish() to get the result of the operation.
1662  **/
1663 void
1664 g_file_append_to_async (GFile               *file,
1665                         GFileCreateFlags     flags,
1666                         int                  io_priority,
1667                         GCancellable        *cancellable,
1668                         GAsyncReadyCallback  callback,
1669                         gpointer             user_data)
1670 {
1671   GFileIface *iface;
1672   
1673   g_return_if_fail (G_IS_FILE (file));
1674
1675   iface = G_FILE_GET_IFACE (file);
1676   (* iface->append_to_async) (file,
1677                               flags,
1678                               io_priority,
1679                               cancellable,
1680                               callback,
1681                               user_data);
1682 }
1683
1684 /**
1685  * g_file_append_to_finish:
1686  * @file: input #GFile.
1687  * @res: #GAsyncResult
1688  * @error: a #GError, or %NULL
1689  * 
1690  * Finishes an asynchronous file append operation started with 
1691  * g_file_append_to_async(). 
1692  * 
1693  * Returns: a valid #GFileOutputStream or %NULL on error.
1694  **/
1695 GFileOutputStream *
1696 g_file_append_to_finish (GFile         *file,
1697                          GAsyncResult  *res,
1698                          GError       **error)
1699 {
1700   GFileIface *iface;
1701   
1702   g_return_val_if_fail (G_IS_FILE (file), NULL);
1703   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1704
1705   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1706     {
1707       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1708       if (g_simple_async_result_propagate_error (simple, error))
1709         return NULL;
1710     }
1711   
1712   iface = G_FILE_GET_IFACE (file);
1713   return (* iface->append_to_finish) (file, res, error);
1714 }
1715
1716 /**
1717  * g_file_create_async:
1718  * @file: input #GFile.
1719  * @flags: a set of #GFileCreateFlags.
1720  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1721  *     of the request.
1722  * @cancellable: optional #GCancellable object, %NULL to ignore.
1723  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1724  * @user_data: the data to pass to callback function
1725  * 
1726  * Asynchronously creates a new file and returns an output stream for writing to it.
1727  * The file must not already exists.
1728  *
1729  * For more details, see g_file_create() which is
1730  * the synchronous version of this call.
1731  *
1732  * When the operation is finished, @callback will be called. You can then call
1733  * g_file_create_finish() to get the result of the operation.
1734  **/
1735 void
1736 g_file_create_async (GFile               *file,
1737                      GFileCreateFlags     flags,
1738                      int                  io_priority,
1739                      GCancellable        *cancellable,
1740                      GAsyncReadyCallback  callback,
1741                      gpointer             user_data)
1742 {
1743   GFileIface *iface;
1744   
1745   g_return_if_fail (G_IS_FILE (file));
1746
1747   iface = G_FILE_GET_IFACE (file);
1748   (* iface->create_async) (file,
1749                            flags,
1750                            io_priority,
1751                            cancellable,
1752                            callback,
1753                            user_data);
1754 }
1755
1756 /**
1757  * g_file_create_finish:
1758  * @file: input #GFile.
1759  * @res: a #GAsyncResult. 
1760  * @error: a #GError, or %NULL
1761  * 
1762  * Finishes an asynchronous file create operation started with 
1763  * g_file_create_async(). 
1764  * 
1765  * Returns: a #GFileOutputStream or %NULL on error.
1766  **/
1767 GFileOutputStream *
1768 g_file_create_finish (GFile         *file,
1769                       GAsyncResult  *res,
1770                       GError       **error)
1771 {
1772   GFileIface *iface;
1773   
1774   g_return_val_if_fail (G_IS_FILE (file), NULL);
1775   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1776
1777   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1778     {
1779       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1780       if (g_simple_async_result_propagate_error (simple, error))
1781         return NULL;
1782     }
1783   
1784   iface = G_FILE_GET_IFACE (file);
1785   return (* iface->create_finish) (file, res, error);
1786 }
1787
1788 /**
1789  * g_file_replace_async:
1790  * @file: input #GFile.
1791  * @etag: an <link linkend="gfile-etag">entity tag</link> for the 
1792  *     current #GFile, or NULL to ignore.
1793  * @make_backup: %TRUE if a backup should be created.
1794  * @flags: a set of #GFileCreateFlags.
1795  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1796  *     of the request.
1797  * @cancellable: optional #GCancellable object, %NULL to ignore.
1798  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1799  * @user_data: the data to pass to callback function
1800  *
1801  * Asynchronously overwrites the file, replacing the contents, possibly
1802  * creating a backup copy of the file first.
1803  *
1804  * For more details, see g_file_replace() which is
1805  * the synchronous version of this call.
1806  *
1807  * When the operation is finished, @callback will be called. You can then call
1808  * g_file_replace_finish() to get the result of the operation.
1809  **/
1810 void
1811 g_file_replace_async (GFile               *file,
1812                       const char          *etag,
1813                       gboolean             make_backup,
1814                       GFileCreateFlags     flags,
1815                       int                  io_priority,
1816                       GCancellable        *cancellable,
1817                       GAsyncReadyCallback  callback,
1818                       gpointer             user_data)
1819 {
1820   GFileIface *iface;
1821   
1822   g_return_if_fail (G_IS_FILE (file));
1823
1824   iface = G_FILE_GET_IFACE (file);
1825   (* iface->replace_async) (file,
1826                             etag,
1827                             make_backup,
1828                             flags,
1829                             io_priority,
1830                             cancellable,
1831                             callback,
1832                             user_data);
1833 }
1834
1835 /**
1836  * g_file_replace_finish:
1837  * @file: input #GFile.
1838  * @res: a #GAsyncResult. 
1839  * @error: a #GError, or %NULL
1840  * 
1841  * Finishes an asynchronous file replace operation started with 
1842  * g_file_replace_async(). 
1843  * 
1844  * Returns: a #GFileOutputStream, or %NULL on error.
1845  **/
1846 GFileOutputStream *
1847 g_file_replace_finish (GFile         *file,
1848                        GAsyncResult  *res,
1849                        GError       **error)
1850 {
1851   GFileIface *iface;
1852   
1853   g_return_val_if_fail (G_IS_FILE (file), NULL);
1854   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1855
1856   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1857     {
1858       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1859       if (g_simple_async_result_propagate_error (simple, error))
1860         return NULL;
1861     }
1862   
1863   iface = G_FILE_GET_IFACE (file);
1864   return (* iface->replace_finish) (file, res, error);
1865 }
1866
1867 static gboolean
1868 copy_symlink (GFile           *destination,
1869               GFileCopyFlags   flags,
1870               GCancellable    *cancellable,
1871               const char      *target,
1872               GError         **error)
1873 {
1874   GError *my_error;
1875   gboolean tried_delete;
1876   GFileInfo *info;
1877   GFileType file_type;
1878
1879   tried_delete = FALSE;
1880
1881  retry:
1882   my_error = NULL;
1883   if (!g_file_make_symbolic_link (destination, target, cancellable, &my_error))
1884     {
1885       /* Maybe it already existed, and we want to overwrite? */
1886       if (!tried_delete && (flags & G_FILE_COPY_OVERWRITE) && 
1887           my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_EXISTS)
1888         {
1889           g_error_free (my_error);
1890
1891
1892           /* Don't overwrite if the destination is a directory */
1893           info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_TYPE,
1894                                     G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1895                                     cancellable, &my_error);
1896           if (info != NULL)
1897             {
1898               file_type = g_file_info_get_file_type (info);
1899               g_object_unref (info);
1900               
1901               if (file_type == G_FILE_TYPE_DIRECTORY)
1902                 {
1903                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY,
1904                                _("Can't copy over directory"));
1905                   return FALSE;
1906                 }
1907             }
1908           
1909           if (!g_file_delete (destination, cancellable, error))
1910             return FALSE;
1911           
1912           tried_delete = TRUE;
1913           goto retry;
1914         }
1915             /* Nah, fail */
1916       g_propagate_error (error, my_error);
1917       return FALSE;
1918     }
1919
1920   return TRUE;
1921 }
1922
1923 static GInputStream *
1924 open_source_for_copy (GFile           *source,
1925                       GFile           *destination,
1926                       GFileCopyFlags   flags,
1927                       GCancellable    *cancellable,
1928                       GError         **error)
1929 {
1930   GError *my_error;
1931   GInputStream *in;
1932   GFileInfo *info;
1933   GFileType file_type;
1934   
1935   my_error = NULL;
1936   in = (GInputStream *)g_file_read (source, cancellable, &my_error);
1937   if (in != NULL)
1938     return in;
1939
1940   /* There was an error opening the source, try to set a good error for it: */
1941
1942   if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_IS_DIRECTORY)
1943     {
1944       /* The source is a directory, don't fail with WOULD_RECURSE immediately, 
1945        * as that is less useful to the app. Better check for errors on the 
1946        * target instead. 
1947        */
1948       g_error_free (my_error);
1949       my_error = NULL;
1950       
1951       info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_TYPE,
1952                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1953                                 cancellable, &my_error);
1954       if (info != NULL)
1955         {
1956           file_type = g_file_info_get_file_type (info);
1957           g_object_unref (info);
1958           
1959           if (flags & G_FILE_COPY_OVERWRITE)
1960             {
1961               if (file_type == G_FILE_TYPE_DIRECTORY)
1962                 {
1963                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_MERGE,
1964                                _("Can't copy directory over directory"));
1965                   return NULL;
1966                 }
1967               /* continue to would_recurse error */
1968             }
1969           else
1970             {
1971               g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
1972                            _("Target file exists"));
1973               return NULL;
1974             }
1975         }
1976       else
1977         {
1978           /* Error getting info from target, return that error 
1979            * (except for NOT_FOUND, which is no error here) 
1980            */
1981           if (my_error->domain != G_IO_ERROR && my_error->code != G_IO_ERROR_NOT_FOUND)
1982             {
1983               g_propagate_error (error, my_error);
1984               return NULL;
1985             }
1986           g_error_free (my_error);
1987         }
1988       
1989       g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE,
1990                    _("Can't recursively copy directory"));
1991       return NULL;
1992     }
1993
1994   g_propagate_error (error, my_error);
1995   return NULL;
1996 }
1997
1998 static gboolean
1999 should_copy (GFileAttributeInfo *info, 
2000              gboolean            as_move)
2001 {
2002   if (as_move)
2003     return info->flags & G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED;
2004   return info->flags & G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE;
2005 }
2006
2007 static char *
2008 build_attribute_list_for_copy (GFileAttributeInfoList *attributes,
2009                                GFileAttributeInfoList *namespaces,
2010                                gboolean                as_move)
2011 {
2012   GString *s;
2013   gboolean first;
2014   int i;
2015   
2016   first = TRUE;
2017   s = g_string_new ("");
2018
2019   if (attributes)
2020     {
2021       for (i = 0; i < attributes->n_infos; i++)
2022         {
2023           if (should_copy (&attributes->infos[i], as_move))
2024             {
2025               if (first)
2026                 first = FALSE;
2027               else
2028                 g_string_append_c (s, ',');
2029                 
2030               g_string_append (s, attributes->infos[i].name);
2031             }
2032         }
2033     }
2034
2035   if (namespaces)
2036     {
2037       for (i = 0; i < namespaces->n_infos; i++)
2038         {
2039           if (should_copy (&namespaces->infos[i], as_move))
2040             {
2041               if (first)
2042                 first = FALSE;
2043               else
2044                 g_string_append_c (s, ',');
2045                 
2046               g_string_append (s, namespaces->infos[i].name);
2047               g_string_append (s, ":*");
2048             }
2049         }
2050     }
2051
2052   return g_string_free (s, FALSE);
2053 }
2054
2055 /**
2056  * g_file_copy_attributes:
2057  * @source: a #GFile with attributes.
2058  * @destination: a #GFile to copy attributes to.
2059  * @flags: a set of #GFileCopyFlags.
2060  * @cancellable: optional #GCancellable object, %NULL to ignore.
2061  * @error: a #GError, %NULL to ignore.
2062  *
2063  * Copies the file attributes from @source to @destination. 
2064  *
2065  * Normally only a subset of the file attributes are copied,
2066  * those that are copies in a normal file copy operation
2067  * (which for instance does not include e.g. mtime). However
2068  * if #G_FILE_COPY_ALL_METADATA is specified in @flags, then
2069  * all the metadata that is possible to copy is copied.
2070  *
2071  * Returns: %TRUE if the attributes were copied successfully, %FALSE otherwise.
2072  **/
2073 gboolean
2074 g_file_copy_attributes (GFile           *source,
2075                         GFile           *destination,
2076                         GFileCopyFlags   flags,
2077                         GCancellable    *cancellable,
2078                         GError         **error)
2079 {
2080   GFileAttributeInfoList *attributes, *namespaces;
2081   char *attrs_to_read;
2082   gboolean res;
2083   GFileInfo *info;
2084   gboolean as_move;
2085   gboolean source_nofollow_symlinks;
2086
2087   as_move = flags & G_FILE_COPY_ALL_METADATA;
2088   source_nofollow_symlinks = flags & G_FILE_COPY_NOFOLLOW_SYMLINKS;
2089
2090   /* Ignore errors here, if the target supports no attributes there is nothing to copy */
2091   attributes = g_file_query_settable_attributes (destination, cancellable, NULL);
2092   namespaces = g_file_query_writable_namespaces (destination, cancellable, NULL);
2093
2094   if (attributes == NULL && namespaces == NULL)
2095     return TRUE;
2096
2097   attrs_to_read = build_attribute_list_for_copy (attributes, namespaces, as_move);
2098
2099   /* Ignore errors here, if we can't read some info (e.g. if it doesn't exist)
2100    * we just don't copy it. 
2101    */
2102   info = g_file_query_info (source, attrs_to_read,
2103                             source_nofollow_symlinks ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS:0,
2104                             cancellable,
2105                             NULL);
2106
2107   g_free (attrs_to_read);
2108   
2109   res = TRUE;
2110   if  (info)
2111     {
2112       res = g_file_set_attributes_from_info (destination,
2113                                              info, 0,
2114                                              cancellable,
2115                                              error);
2116       g_object_unref (info);
2117     }
2118   
2119   g_file_attribute_info_list_unref (attributes);
2120   g_file_attribute_info_list_unref (namespaces);
2121   
2122   return res;
2123 }
2124
2125 /* Closes the streams */
2126 static gboolean
2127 copy_stream_with_progress (GInputStream           *in,
2128                            GOutputStream          *out,
2129                            GCancellable           *cancellable,
2130                            GFileProgressCallback   progress_callback,
2131                            gpointer                progress_callback_data,
2132                            GError                **error)
2133 {
2134   gssize n_read, n_written;
2135   goffset current_size;
2136   char buffer[8192], *p;
2137   gboolean res;
2138   goffset total_size;
2139   GFileInfo *info;
2140
2141   total_size = 0;
2142   info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (in),
2143                                          G_FILE_ATTRIBUTE_STANDARD_SIZE,
2144                                          cancellable, NULL);
2145   if (info)
2146     {
2147       total_size = g_file_info_get_size (info);
2148       g_object_unref (info);
2149     }
2150   
2151   current_size = 0;
2152   res = TRUE;
2153   while (TRUE)
2154     {
2155       n_read = g_input_stream_read (in, buffer, sizeof (buffer), cancellable, error);
2156       if (n_read == -1)
2157         {
2158           res = FALSE;
2159           break;
2160         }
2161         
2162       if (n_read == 0)
2163         break;
2164
2165       current_size += n_read;
2166
2167       p = buffer;
2168       while (n_read > 0)
2169         {
2170           n_written = g_output_stream_write (out, p, n_read, cancellable, error);
2171           if (n_written == -1)
2172             {
2173               res = FALSE;
2174               break;
2175             }
2176
2177           p += n_written;
2178           n_read -= n_written;
2179         }
2180
2181       if (!res)
2182         break;
2183       
2184       if (progress_callback)
2185         progress_callback (current_size, total_size, progress_callback_data);
2186     }
2187
2188   if (!res)
2189     error = NULL; /* Ignore further errors */
2190
2191   /* Make sure we send full copied size */
2192   if (progress_callback)
2193     progress_callback (current_size, total_size, progress_callback_data);
2194
2195   
2196   /* Don't care about errors in source here */
2197   g_input_stream_close (in, cancellable, NULL);
2198
2199   /* But write errors on close are bad! */
2200   if (!g_output_stream_close (out, cancellable, error))
2201     res = FALSE;
2202
2203   g_object_unref (in);
2204   g_object_unref (out);
2205       
2206   return res;
2207 }
2208
2209 static gboolean
2210 file_copy_fallback (GFile                  *source,
2211                     GFile                  *destination,
2212                     GFileCopyFlags          flags,
2213                     GCancellable           *cancellable,
2214                     GFileProgressCallback   progress_callback,
2215                     gpointer                progress_callback_data,
2216                     GError                **error)
2217 {
2218   GInputStream *in;
2219   GOutputStream *out;
2220   GFileInfo *info;
2221   const char *target;
2222
2223   /* Maybe copy the symlink? */
2224   if (flags & G_FILE_COPY_NOFOLLOW_SYMLINKS)
2225     {
2226       info = g_file_query_info (source,
2227                                 G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
2228                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
2229                                 cancellable,
2230                                 error);
2231       if (info == NULL)
2232         return FALSE;
2233
2234       if (g_file_info_get_file_type (info) == G_FILE_TYPE_SYMBOLIC_LINK &&
2235           (target = g_file_info_get_symlink_target (info)) != NULL)
2236         {
2237           if (!copy_symlink (destination, flags, cancellable, target, error))
2238             {
2239               g_object_unref (info);
2240               return FALSE;
2241             }
2242           
2243           g_object_unref (info);
2244           goto copied_file;
2245         }
2246       
2247       g_object_unref (info);
2248     }
2249   
2250   in = open_source_for_copy (source, destination, flags, cancellable, error);
2251   if (in == NULL)
2252     return FALSE;
2253   
2254   if (flags & G_FILE_COPY_OVERWRITE)
2255     {
2256       out = (GOutputStream *)g_file_replace (destination,
2257                                              NULL, 0,
2258                                              flags & G_FILE_COPY_BACKUP,
2259                                              cancellable, error);
2260     }
2261   else
2262     {
2263       out = (GOutputStream *)g_file_create (destination, 0, cancellable, error);
2264     }
2265
2266   if (out == NULL)
2267     {
2268       g_object_unref (in);
2269       return FALSE;
2270     }
2271
2272   if (!copy_stream_with_progress (in, out, cancellable,
2273                                   progress_callback, progress_callback_data,
2274                                   error))
2275     return FALSE;
2276
2277  copied_file:
2278
2279   /* Ignore errors here. Failure to copy metadata is not a hard error */
2280   g_file_copy_attributes (source, destination,
2281                           flags, cancellable, NULL);
2282   
2283   return TRUE;
2284 }
2285
2286 /**
2287  * g_file_copy:
2288  * @source: input #GFile.
2289  * @destination: destination #GFile
2290  * @flags: set of #GFileCopyFlags
2291  * @cancellable: optional #GCancellable object, %NULL to ignore.
2292  * @progress_callback: function to callback with progress information
2293  * @progress_callback_data: user data to pass to @progress_callback
2294  * @error: #GError to set on error, or %NULL
2295  *
2296  * Copies the file @source to the location specified by @destination.
2297  * Can not handle recursive copies of directories.
2298  *
2299  * If the flag #G_FILE_COPY_OVERWRITE is specified an already
2300  * existing @destination file is overwritten.
2301  *
2302  * If the flag #G_FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks
2303  * will be copied as symlinks, otherwise the target of the
2304  * @source symlink will be copied.
2305  *
2306  * If @cancellable is not %NULL, then the operation can be cancelled by
2307  * triggering the cancellable object from another thread. If the operation
2308  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2309  * 
2310  * If @progress_callback is not %NULL, then the operation can be monitored by
2311  * setting this to a #GFileProgressCallback function. @progress_callback_data
2312  * will be passed to this function. It is guaranteed that this callback will
2313  * be called after all data has been transferred with the total number of bytes
2314  * copied during the operation.
2315  * 
2316  * If the @source file does not exist then the G_IO_ERROR_NOT_FOUND
2317  * error is returned, independent on the status of the @destination.
2318  *
2319  * If #G_FILE_COPY_OVERWRITE is not specified and the target exists, then the
2320  * error G_IO_ERROR_EXISTS is returned.
2321  *
2322  * If trying to overwrite a file over a directory the G_IO_ERROR_IS_DIRECTORY
2323  * error is returned. If trying to overwrite a directory with a directory the
2324  * G_IO_ERROR_WOULD_MERGE error is returned.
2325  *
2326  * If the source is a directory and the target does not exist, or #G_FILE_COPY_OVERWRITE is
2327  * specified and the target is a file, then the G_IO_ERROR_WOULD_RECURSE error
2328  * is returned.
2329  *
2330  * If you are interested in copying the #GFile object itself (not the on-disk
2331  * file), see g_file_dup().
2332  *
2333  * Returns: %TRUE on success, %FALSE otherwise.
2334  **/
2335 gboolean
2336 g_file_copy (GFile                  *source,
2337              GFile                  *destination,
2338              GFileCopyFlags          flags,
2339              GCancellable           *cancellable,
2340              GFileProgressCallback   progress_callback,
2341              gpointer                progress_callback_data,
2342              GError                **error)
2343 {
2344   GFileIface *iface;
2345   GError *my_error;
2346   gboolean res;
2347
2348   g_return_val_if_fail (G_IS_FILE (source), FALSE);
2349   g_return_val_if_fail (G_IS_FILE (destination), FALSE);
2350
2351   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2352     return FALSE;
2353   
2354   iface = G_FILE_GET_IFACE (destination);
2355   if (iface->copy)
2356     {
2357       my_error = NULL;
2358       res = (* iface->copy) (source, destination,
2359                              flags, cancellable,
2360                              progress_callback, progress_callback_data,
2361                              &my_error);
2362       
2363       if (res)
2364         return TRUE;
2365       
2366       if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2367         {
2368           g_propagate_error (error, my_error);
2369               return FALSE;
2370         }
2371     }
2372
2373   /* If the types are different, and the destination method failed
2374      also try the source method */
2375   if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination))
2376     {
2377       iface = G_FILE_GET_IFACE (source);
2378       
2379       if (iface->copy)
2380         {
2381           my_error = NULL;
2382           res = (* iface->copy) (source, destination,
2383                                  flags, cancellable,
2384                                  progress_callback, progress_callback_data,
2385                                  &my_error);
2386           
2387           if (res)
2388             return TRUE;
2389           
2390           if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2391             {
2392               g_propagate_error (error, my_error);
2393               return FALSE;
2394             }
2395         }
2396     }
2397   
2398   return file_copy_fallback (source, destination, flags, cancellable,
2399                              progress_callback, progress_callback_data,
2400                              error);
2401 }
2402
2403 /**
2404  * g_file_copy_async:
2405  * @source: input #GFile.
2406  * @destination: destination #GFile
2407  * @flags: set of #GFileCopyFlags
2408  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
2409  *     of the request. 
2410  * @cancellable: optional #GCancellable object, %NULL to ignore.
2411  * @progress_callback: function to callback with progress information
2412  * @progress_callback_data: user data to pass to @progress_callback
2413  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
2414  * @user_data: the data to pass to callback function
2415  *
2416  * Copies the file @source to the location specified by @destination 
2417  * asynchronously. For details of the behaviour, see g_file_copy().
2418  *
2419  * If @progress_callback is not %NULL, then that function that will be called
2420  * just like in g_file_copy(), however the callback will run in the main loop,
2421  * not in the thread that is doing the I/O operation.
2422  *
2423  * When the operation is finished, @callback will be called. You can then call
2424  * g_file_copy_finish() to get the result of the operation.
2425  **/
2426 void
2427 g_file_copy_async (GFile                  *source,
2428                    GFile                  *destination,
2429                    GFileCopyFlags          flags,
2430                    int                     io_priority,
2431                    GCancellable           *cancellable,
2432                    GFileProgressCallback   progress_callback,
2433                    gpointer                progress_callback_data,
2434                    GAsyncReadyCallback     callback,
2435                    gpointer                user_data)
2436 {
2437   GFileIface *iface;
2438
2439   g_return_if_fail (G_IS_FILE (source));
2440   g_return_if_fail (G_IS_FILE (destination));
2441
2442   iface = G_FILE_GET_IFACE (source);
2443   (* iface->copy_async) (source,
2444                          destination,
2445                          flags,
2446                          io_priority,
2447                          cancellable,
2448                          progress_callback,
2449                          progress_callback_data,
2450                          callback,
2451                          user_data);
2452 }
2453
2454 /**
2455  * g_file_copy_finish:
2456  * @file: input #GFile.
2457  * @res: a #GAsyncResult. 
2458  * @error: a #GError, or %NULL
2459  * 
2460  * Finishes copying the file started with 
2461  * g_file_copy_async().
2462  * 
2463  * Returns: a %TRUE on success, %FALSE on error.
2464  **/
2465 gboolean
2466 g_file_copy_finish (GFile        *file,
2467                     GAsyncResult *res,
2468                     GError      **error)
2469 {
2470   GFileIface *iface;
2471   
2472   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2473   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
2474
2475   if (G_IS_SIMPLE_ASYNC_RESULT (res))
2476     {
2477       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
2478       
2479       if (g_simple_async_result_propagate_error (simple, error))
2480         return FALSE;
2481     }
2482   
2483   iface = G_FILE_GET_IFACE (file);
2484   return (* iface->copy_finish) (file, res, error);
2485 }
2486
2487 /**
2488  * g_file_move:
2489  * @source: #GFile pointing to the source location.
2490  * @destination: #GFile pointing to the destination location.
2491  * @flags: set of #GFileCopyFlags.
2492  * @cancellable: optional #GCancellable object, %NULL to ignore.
2493  * @progress_callback: #GFileProgressCallback function for updates.
2494  * @progress_callback_data: gpointer to user data for the callback function.
2495  * @error: #GError for returning error conditions, or %NULL
2496  *
2497  *
2498  * Tries to move the file or directory @source to the location specified by @destination.
2499  * If native move operations are supported then this is used, otherwise a copy + delete
2500  * fallback is used. The native implementation may support moving directories (for instance
2501  * on moves inside the same filesystem), but the fallback code does not.
2502  * 
2503  * If the flag #G_FILE_COPY_OVERWRITE is specified an already
2504  * existing @destination file is overwritten.
2505  *
2506  * If the flag #G_FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks
2507  * will be copied as symlinks, otherwise the target of the
2508  * @source symlink will be copied.
2509  *
2510  * If @cancellable is not %NULL, then the operation can be cancelled by
2511  * triggering the cancellable object from another thread. If the operation
2512  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2513  * 
2514  * If @progress_callback is not %NULL, then the operation can be monitored by
2515  * setting this to a #GFileProgressCallback function. @progress_callback_data
2516  * will be passed to this function. It is guaranteed that this callback will
2517  * be called after all data has been transferred with the total number of bytes
2518  * copied during the operation.
2519  * 
2520  * If the @source file does not exist then the G_IO_ERROR_NOT_FOUND
2521  * error is returned, independent on the status of the @destination.
2522  *
2523  * If #G_FILE_COPY_OVERWRITE is not specified and the target exists, then the
2524  * error G_IO_ERROR_EXISTS is returned.
2525  *
2526  * If trying to overwrite a file over a directory the G_IO_ERROR_IS_DIRECTORY
2527  * error is returned. If trying to overwrite a directory with a directory the
2528  * G_IO_ERROR_WOULD_MERGE error is returned.
2529  *
2530  * If the source is a directory and the target does not exist, or #G_FILE_COPY_OVERWRITE is
2531  * specified and the target is a file, then the G_IO_ERROR_WOULD_RECURSE error
2532  * may be returned (if the native move operation isn't available).
2533  *
2534  * Returns: %TRUE on successful move, %FALSE otherwise.
2535  **/
2536 gboolean
2537 g_file_move (GFile                  *source,
2538              GFile                  *destination,
2539              GFileCopyFlags          flags,
2540              GCancellable           *cancellable,
2541              GFileProgressCallback   progress_callback,
2542              gpointer                progress_callback_data,
2543              GError                **error)
2544 {
2545   GFileIface *iface;
2546   GError *my_error;
2547   gboolean res;
2548
2549   g_return_val_if_fail (G_IS_FILE (source), FALSE);
2550   g_return_val_if_fail (G_IS_FILE (destination), FALSE);
2551
2552   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2553     return FALSE;
2554   
2555   iface = G_FILE_GET_IFACE (destination);
2556   if (iface->move)
2557     {
2558       my_error = NULL;
2559       res = (* iface->move) (source, destination,
2560                              flags, cancellable,
2561                              progress_callback, progress_callback_data,
2562                              &my_error);
2563       
2564       if (res)
2565         return TRUE;
2566       
2567       if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2568         {
2569           g_propagate_error (error, my_error);
2570           return FALSE;
2571         }
2572     }
2573
2574   /* If the types are different, and the destination method failed
2575      also try the source method */
2576   if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination))
2577     {
2578       iface = G_FILE_GET_IFACE (source);
2579       
2580       if (iface->move)
2581         {
2582           my_error = NULL;
2583           res = (* iface->move) (source, destination,
2584                                  flags, cancellable,
2585                                  progress_callback, progress_callback_data,
2586                                  &my_error);
2587           
2588           if (res)
2589             return TRUE;
2590           
2591           if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2592             {
2593               g_propagate_error (error, my_error);
2594               return FALSE;
2595             }
2596         }
2597     }
2598   
2599   if (flags & G_FILE_COPY_NO_FALLBACK_FOR_MOVE)
2600     {  
2601       g_set_error (error, G_IO_ERROR,
2602                    G_IO_ERROR_NOT_SUPPORTED,
2603                    _("Operation not supported"));
2604       return FALSE;
2605     }
2606   
2607   flags |= G_FILE_COPY_ALL_METADATA;
2608   if (!g_file_copy (source, destination, flags, cancellable,
2609                     progress_callback, progress_callback_data,
2610                     error))
2611     return FALSE;
2612
2613   return g_file_delete (source, cancellable, error);
2614 }
2615
2616 /**
2617  * g_file_make_directory
2618  * @file: input #GFile.
2619  * @cancellable: optional #GCancellable object, %NULL to ignore.
2620  * @error: a #GError, or %NULL 
2621  *
2622  * Creates a directory.
2623  * 
2624  * If @cancellable is not %NULL, then the operation can be cancelled by
2625  * triggering the cancellable object from another thread. If the operation
2626  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2627  * 
2628  * Returns: %TRUE on successful creation, %FALSE otherwise.
2629  **/
2630 gboolean
2631 g_file_make_directory (GFile         *file,
2632                        GCancellable  *cancellable,
2633                        GError       **error)
2634 {
2635   GFileIface *iface;
2636
2637   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2638
2639   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2640     return FALSE;
2641   
2642   iface = G_FILE_GET_IFACE (file);
2643
2644   if (iface->make_directory == NULL)
2645     {
2646       g_set_error (error, G_IO_ERROR,
2647                    G_IO_ERROR_NOT_SUPPORTED,
2648                    _("Operation not supported"));
2649       return FALSE;
2650     }
2651   
2652   return (* iface->make_directory) (file, cancellable, error);
2653 }
2654
2655 /**
2656  * g_file_make_symbolic_link:
2657  * @file: input #GFile.
2658  * @symlink_value: a string with the value of the new symlink.
2659  * @cancellable: optional #GCancellable object, %NULL to ignore.
2660  * @error: a #GError. 
2661  * 
2662  * Creates a symbolic link.
2663  *
2664  * If @cancellable is not %NULL, then the operation can be cancelled by
2665  * triggering the cancellable object from another thread. If the operation
2666  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2667  * 
2668  * Returns: %TRUE on the creation of a new symlink, %FALSE otherwise.
2669  **/
2670 gboolean
2671 g_file_make_symbolic_link (GFile         *file,
2672                            const char    *symlink_value,
2673                            GCancellable  *cancellable,
2674                            GError       **error)
2675 {
2676   GFileIface *iface;
2677
2678   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2679   g_return_val_if_fail (symlink_value != NULL, FALSE);
2680
2681   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2682     return FALSE;
2683
2684   if (*symlink_value == '\0')
2685     {
2686       g_set_error (error, G_IO_ERROR,
2687                    G_IO_ERROR_INVALID_ARGUMENT,
2688                    _("Invalid symlink value given"));
2689       return FALSE;
2690     }
2691   
2692   iface = G_FILE_GET_IFACE (file);
2693
2694   if (iface->make_symbolic_link == NULL)
2695     {
2696       g_set_error (error, G_IO_ERROR,
2697                    G_IO_ERROR_NOT_SUPPORTED,
2698                    _("Operation not supported"));
2699       return FALSE;
2700     }
2701   
2702   return (* iface->make_symbolic_link) (file, symlink_value, cancellable, error);
2703 }
2704
2705 /**
2706  * g_file_delete:
2707  * @file: input #GFile.
2708  * @cancellable: optional #GCancellable object, %NULL to ignore.
2709  * @error: a #GError, or %NULL 
2710  * 
2711  * Deletes a file.
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"