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