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