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