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