Bug 526796 – Wrong order of arguments in g_file_copy's fallback
[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 exists.
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.
1531  *
1532  * This will try to replace the file in the safest way possible so
1533  * that any errors during the writing will not affect an already
1534  * existing copy of the file. For instance, for local files it
1535  * may write to a temporary file and then atomically rename over
1536  * the destination when the stream is closed.
1537  * 
1538  * By default files created are generally readable by everyone,
1539  * but if you pass #G_FILE_CREATE_PRIVATE in @flags the file
1540  * will be made readable only to the current user, to the level that
1541  * is supported on the target filesystem.
1542  *
1543  * If @cancellable is not %NULL, then the operation can be cancelled by
1544  * triggering the cancellable object from another thread. If the operation
1545  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1546  * 
1547  * If you pass in a non-#NULL @etag value, then this value is
1548  * compared to the current entity tag of the file, and if they differ
1549  * an G_IO_ERROR_WRONG_ETAG error is returned. This generally means
1550  * that the file has been changed since you last read it. You can get
1551  * the new etag from g_file_output_stream_get_etag() after you've
1552  * finished writing and closed the #GFileOutputStream. When you load
1553  * a new file you can use g_file_input_stream_query_info() to get
1554  * the etag of the file.
1555  * 
1556  * If @make_backup is %TRUE, this function will attempt to make a backup
1557  * of the current file before overwriting it. If this fails a G_IO_ERROR_CANT_CREATE_BACKUP
1558  * error will be returned. If you want to replace anyway, try again with
1559  * @make_backup set to %FALSE.
1560  *
1561  * If the file is a directory the G_IO_ERROR_IS_DIRECTORY error will be returned,
1562  * and if the file is some other form of non-regular file then a
1563  * G_IO_ERROR_NOT_REGULAR_FILE error will be returned.
1564  * Some file systems don't allow all file names, and may
1565  * return an G_IO_ERROR_INVALID_FILENAME error, and if the name
1566  * is to long G_IO_ERROR_FILENAME_TOO_LONG will be returned.
1567  * Other errors are possible too, and depend on what kind of
1568  * filesystem the file is on.
1569  *
1570  * Returns: a #GFileOutputStream or %NULL on error. 
1571  **/
1572 GFileOutputStream *
1573 g_file_replace (GFile             *file,
1574                 const char        *etag,
1575                 gboolean           make_backup,
1576                 GFileCreateFlags   flags,
1577                 GCancellable      *cancellable,
1578                 GError           **error)
1579 {
1580   GFileIface *iface;
1581
1582   g_return_val_if_fail (G_IS_FILE (file), NULL);
1583
1584   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1585     return NULL;
1586   
1587   iface = G_FILE_GET_IFACE (file);
1588
1589   if (iface->replace == NULL)
1590     {
1591       g_set_error (error, G_IO_ERROR,
1592                    G_IO_ERROR_NOT_SUPPORTED,
1593                    _("Operation not supported"));
1594       return NULL;
1595     }
1596   
1597   
1598   /* Handle empty tag string as NULL in consistent way. */
1599   if (etag && *etag == 0)
1600     etag = NULL;
1601   
1602   return (* iface->replace) (file, etag, make_backup, flags, cancellable, error);
1603 }
1604
1605 /**
1606  * g_file_read_async:
1607  * @file: input #GFile.
1608  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1609  *     of the request. 
1610  * @cancellable: optional #GCancellable object, %NULL to ignore.
1611  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1612  * @user_data: the data to pass to callback function
1613  *
1614  * Asynchronously opens @file for reading.
1615  *
1616  * For more details, see g_file_read() which is
1617  * the synchronous version of this call.
1618  *
1619  * When the operation is finished, @callback will be called. You can then call
1620  * g_file_read_finish() to get the result of the operation.
1621  **/
1622 void
1623 g_file_read_async (GFile               *file,
1624                    int                  io_priority,
1625                    GCancellable        *cancellable,
1626                    GAsyncReadyCallback  callback,
1627                    gpointer             user_data)
1628 {
1629   GFileIface *iface;
1630   
1631   g_return_if_fail (G_IS_FILE (file));
1632
1633   iface = G_FILE_GET_IFACE (file);
1634   (* iface->read_async) (file,
1635                          io_priority,
1636                          cancellable,
1637                          callback,
1638                          user_data);
1639 }
1640
1641 /**
1642  * g_file_read_finish:
1643  * @file: input #GFile.
1644  * @res: a #GAsyncResult. 
1645  * @error: a #GError, or %NULL
1646  *
1647  * Finishes an asynchronous file read operation started with 
1648  * g_file_read_async(). 
1649  *  
1650  * Returns: a #GFileInputStream or %NULL on error.
1651  **/
1652 GFileInputStream *
1653 g_file_read_finish (GFile         *file,
1654                     GAsyncResult  *res,
1655                     GError       **error)
1656 {
1657   GFileIface *iface;
1658   
1659   g_return_val_if_fail (G_IS_FILE (file), NULL);
1660   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1661
1662   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1663     {
1664       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1665       if (g_simple_async_result_propagate_error (simple, error))
1666         return NULL;
1667     }
1668   
1669   iface = G_FILE_GET_IFACE (file);
1670   return (* iface->read_finish) (file, res, error);
1671 }
1672
1673 /**
1674  * g_file_append_to_async:
1675  * @file: input #GFile.
1676  * @flags: a set of #GFileCreateFlags.
1677  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1678  *     of the request. 
1679  * @cancellable: optional #GCancellable object, %NULL to ignore.
1680  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1681  * @user_data: the data to pass to callback function
1682  * 
1683  * Asynchronously opens @file for appending.
1684  *
1685  * For more details, see g_file_append_to() which is
1686  * the synchronous version of this call.
1687  *
1688  * When the operation is finished, @callback will be called. You can then call
1689  * g_file_append_to_finish() to get the result of the operation.
1690  **/
1691 void
1692 g_file_append_to_async (GFile               *file,
1693                         GFileCreateFlags     flags,
1694                         int                  io_priority,
1695                         GCancellable        *cancellable,
1696                         GAsyncReadyCallback  callback,
1697                         gpointer             user_data)
1698 {
1699   GFileIface *iface;
1700   
1701   g_return_if_fail (G_IS_FILE (file));
1702
1703   iface = G_FILE_GET_IFACE (file);
1704   (* iface->append_to_async) (file,
1705                               flags,
1706                               io_priority,
1707                               cancellable,
1708                               callback,
1709                               user_data);
1710 }
1711
1712 /**
1713  * g_file_append_to_finish:
1714  * @file: input #GFile.
1715  * @res: #GAsyncResult
1716  * @error: a #GError, or %NULL
1717  * 
1718  * Finishes an asynchronous file append operation started with 
1719  * g_file_append_to_async(). 
1720  * 
1721  * Returns: a valid #GFileOutputStream or %NULL on error.
1722  **/
1723 GFileOutputStream *
1724 g_file_append_to_finish (GFile         *file,
1725                          GAsyncResult  *res,
1726                          GError       **error)
1727 {
1728   GFileIface *iface;
1729   
1730   g_return_val_if_fail (G_IS_FILE (file), NULL);
1731   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1732
1733   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1734     {
1735       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1736       if (g_simple_async_result_propagate_error (simple, error))
1737         return NULL;
1738     }
1739   
1740   iface = G_FILE_GET_IFACE (file);
1741   return (* iface->append_to_finish) (file, res, error);
1742 }
1743
1744 /**
1745  * g_file_create_async:
1746  * @file: input #GFile.
1747  * @flags: a set of #GFileCreateFlags.
1748  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1749  *     of the request.
1750  * @cancellable: optional #GCancellable object, %NULL to ignore.
1751  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1752  * @user_data: the data to pass to callback function
1753  * 
1754  * Asynchronously creates a new file and returns an output stream for writing to it.
1755  * The file must not already exists.
1756  *
1757  * For more details, see g_file_create() which is
1758  * the synchronous version of this call.
1759  *
1760  * When the operation is finished, @callback will be called. You can then call
1761  * g_file_create_finish() to get the result of the operation.
1762  **/
1763 void
1764 g_file_create_async (GFile               *file,
1765                      GFileCreateFlags     flags,
1766                      int                  io_priority,
1767                      GCancellable        *cancellable,
1768                      GAsyncReadyCallback  callback,
1769                      gpointer             user_data)
1770 {
1771   GFileIface *iface;
1772   
1773   g_return_if_fail (G_IS_FILE (file));
1774
1775   iface = G_FILE_GET_IFACE (file);
1776   (* iface->create_async) (file,
1777                            flags,
1778                            io_priority,
1779                            cancellable,
1780                            callback,
1781                            user_data);
1782 }
1783
1784 /**
1785  * g_file_create_finish:
1786  * @file: input #GFile.
1787  * @res: a #GAsyncResult. 
1788  * @error: a #GError, or %NULL
1789  * 
1790  * Finishes an asynchronous file create operation started with 
1791  * g_file_create_async(). 
1792  * 
1793  * Returns: a #GFileOutputStream or %NULL on error.
1794  **/
1795 GFileOutputStream *
1796 g_file_create_finish (GFile         *file,
1797                       GAsyncResult  *res,
1798                       GError       **error)
1799 {
1800   GFileIface *iface;
1801   
1802   g_return_val_if_fail (G_IS_FILE (file), NULL);
1803   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1804
1805   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1806     {
1807       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1808       if (g_simple_async_result_propagate_error (simple, error))
1809         return NULL;
1810     }
1811   
1812   iface = G_FILE_GET_IFACE (file);
1813   return (* iface->create_finish) (file, res, error);
1814 }
1815
1816 /**
1817  * g_file_replace_async:
1818  * @file: input #GFile.
1819  * @etag: an <link linkend="gfile-etag">entity tag</link> for the 
1820  *     current #GFile, or NULL to ignore.
1821  * @make_backup: %TRUE if a backup should be created.
1822  * @flags: a set of #GFileCreateFlags.
1823  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1824  *     of the request.
1825  * @cancellable: optional #GCancellable object, %NULL to ignore.
1826  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1827  * @user_data: the data to pass to callback function
1828  *
1829  * Asynchronously overwrites the file, replacing the contents, possibly
1830  * creating a backup copy of the file first.
1831  *
1832  * For more details, see g_file_replace() which is
1833  * the synchronous version of this call.
1834  *
1835  * When the operation is finished, @callback will be called. You can then call
1836  * g_file_replace_finish() to get the result of the operation.
1837  **/
1838 void
1839 g_file_replace_async (GFile               *file,
1840                       const char          *etag,
1841                       gboolean             make_backup,
1842                       GFileCreateFlags     flags,
1843                       int                  io_priority,
1844                       GCancellable        *cancellable,
1845                       GAsyncReadyCallback  callback,
1846                       gpointer             user_data)
1847 {
1848   GFileIface *iface;
1849   
1850   g_return_if_fail (G_IS_FILE (file));
1851
1852   iface = G_FILE_GET_IFACE (file);
1853   (* iface->replace_async) (file,
1854                             etag,
1855                             make_backup,
1856                             flags,
1857                             io_priority,
1858                             cancellable,
1859                             callback,
1860                             user_data);
1861 }
1862
1863 /**
1864  * g_file_replace_finish:
1865  * @file: input #GFile.
1866  * @res: a #GAsyncResult. 
1867  * @error: a #GError, or %NULL
1868  * 
1869  * Finishes an asynchronous file replace operation started with 
1870  * g_file_replace_async(). 
1871  * 
1872  * Returns: a #GFileOutputStream, or %NULL on error.
1873  **/
1874 GFileOutputStream *
1875 g_file_replace_finish (GFile         *file,
1876                        GAsyncResult  *res,
1877                        GError       **error)
1878 {
1879   GFileIface *iface;
1880   
1881   g_return_val_if_fail (G_IS_FILE (file), NULL);
1882   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1883
1884   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1885     {
1886       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1887       if (g_simple_async_result_propagate_error (simple, error))
1888         return NULL;
1889     }
1890   
1891   iface = G_FILE_GET_IFACE (file);
1892   return (* iface->replace_finish) (file, res, error);
1893 }
1894
1895 static gboolean
1896 copy_symlink (GFile           *destination,
1897               GFileCopyFlags   flags,
1898               GCancellable    *cancellable,
1899               const char      *target,
1900               GError         **error)
1901 {
1902   GError *my_error;
1903   gboolean tried_delete;
1904   GFileInfo *info;
1905   GFileType file_type;
1906
1907   tried_delete = FALSE;
1908
1909  retry:
1910   my_error = NULL;
1911   if (!g_file_make_symbolic_link (destination, target, cancellable, &my_error))
1912     {
1913       /* Maybe it already existed, and we want to overwrite? */
1914       if (!tried_delete && (flags & G_FILE_COPY_OVERWRITE) && 
1915           my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_EXISTS)
1916         {
1917           g_error_free (my_error);
1918
1919
1920           /* Don't overwrite if the destination is a directory */
1921           info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_TYPE,
1922                                     G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1923                                     cancellable, &my_error);
1924           if (info != NULL)
1925             {
1926               file_type = g_file_info_get_file_type (info);
1927               g_object_unref (info);
1928               
1929               if (file_type == G_FILE_TYPE_DIRECTORY)
1930                 {
1931                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY,
1932                                _("Can't copy over directory"));
1933                   return FALSE;
1934                 }
1935             }
1936           
1937           if (!g_file_delete (destination, cancellable, error))
1938             return FALSE;
1939           
1940           tried_delete = TRUE;
1941           goto retry;
1942         }
1943             /* Nah, fail */
1944       g_propagate_error (error, my_error);
1945       return FALSE;
1946     }
1947
1948   return TRUE;
1949 }
1950
1951 static GInputStream *
1952 open_source_for_copy (GFile           *source,
1953                       GFile           *destination,
1954                       GFileCopyFlags   flags,
1955                       GCancellable    *cancellable,
1956                       GError         **error)
1957 {
1958   GError *my_error;
1959   GInputStream *in;
1960   GFileInfo *info;
1961   GFileType file_type;
1962   
1963   my_error = NULL;
1964   in = (GInputStream *)g_file_read (source, cancellable, &my_error);
1965   if (in != NULL)
1966     return in;
1967
1968   /* There was an error opening the source, try to set a good error for it: */
1969
1970   if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_IS_DIRECTORY)
1971     {
1972       /* The source is a directory, don't fail with WOULD_RECURSE immediately, 
1973        * as that is less useful to the app. Better check for errors on the 
1974        * target instead. 
1975        */
1976       g_error_free (my_error);
1977       my_error = NULL;
1978       
1979       info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_TYPE,
1980                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1981                                 cancellable, &my_error);
1982       if (info != NULL)
1983         {
1984           file_type = g_file_info_get_file_type (info);
1985           g_object_unref (info);
1986           
1987           if (flags & G_FILE_COPY_OVERWRITE)
1988             {
1989               if (file_type == G_FILE_TYPE_DIRECTORY)
1990                 {
1991                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_MERGE,
1992                                _("Can't copy directory over directory"));
1993                   return NULL;
1994                 }
1995               /* continue to would_recurse error */
1996             }
1997           else
1998             {
1999               g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
2000                            _("Target file exists"));
2001               return NULL;
2002             }
2003         }
2004       else
2005         {
2006           /* Error getting info from target, return that error 
2007            * (except for NOT_FOUND, which is no error here) 
2008            */
2009           if (my_error->domain != G_IO_ERROR && my_error->code != G_IO_ERROR_NOT_FOUND)
2010             {
2011               g_propagate_error (error, my_error);
2012               return NULL;
2013             }
2014           g_error_free (my_error);
2015         }
2016       
2017       g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE,
2018                    _("Can't recursively copy directory"));
2019       return NULL;
2020     }
2021
2022   g_propagate_error (error, my_error);
2023   return NULL;
2024 }
2025
2026 static gboolean
2027 should_copy (GFileAttributeInfo *info, 
2028              gboolean            as_move)
2029 {
2030   if (as_move)
2031     return info->flags & G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED;
2032   return info->flags & G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE;
2033 }
2034
2035 static char *
2036 build_attribute_list_for_copy (GFileAttributeInfoList *attributes,
2037                                GFileAttributeInfoList *namespaces,
2038                                gboolean                as_move)
2039 {
2040   GString *s;
2041   gboolean first;
2042   int i;
2043   
2044   first = TRUE;
2045   s = g_string_new ("");
2046
2047   if (attributes)
2048     {
2049       for (i = 0; i < attributes->n_infos; i++)
2050         {
2051           if (should_copy (&attributes->infos[i], as_move))
2052             {
2053               if (first)
2054                 first = FALSE;
2055               else
2056                 g_string_append_c (s, ',');
2057                 
2058               g_string_append (s, attributes->infos[i].name);
2059             }
2060         }
2061     }
2062
2063   if (namespaces)
2064     {
2065       for (i = 0; i < namespaces->n_infos; i++)
2066         {
2067           if (should_copy (&namespaces->infos[i], as_move))
2068             {
2069               if (first)
2070                 first = FALSE;
2071               else
2072                 g_string_append_c (s, ',');
2073                 
2074               g_string_append (s, namespaces->infos[i].name);
2075               g_string_append (s, ":*");
2076             }
2077         }
2078     }
2079
2080   return g_string_free (s, FALSE);
2081 }
2082
2083 /**
2084  * g_file_copy_attributes:
2085  * @source: a #GFile with attributes.
2086  * @destination: a #GFile to copy attributes to.
2087  * @flags: a set of #GFileCopyFlags.
2088  * @cancellable: optional #GCancellable object, %NULL to ignore.
2089  * @error: a #GError, %NULL to ignore.
2090  *
2091  * Copies the file attributes from @source to @destination. 
2092  *
2093  * Normally only a subset of the file attributes are copied,
2094  * those that are copies in a normal file copy operation
2095  * (which for instance does not include e.g. mtime). However
2096  * if #G_FILE_COPY_ALL_METADATA is specified in @flags, then
2097  * all the metadata that is possible to copy is copied.
2098  *
2099  * Returns: %TRUE if the attributes were copied successfully, %FALSE otherwise.
2100  **/
2101 gboolean
2102 g_file_copy_attributes (GFile           *source,
2103                         GFile           *destination,
2104                         GFileCopyFlags   flags,
2105                         GCancellable    *cancellable,
2106                         GError         **error)
2107 {
2108   GFileAttributeInfoList *attributes, *namespaces;
2109   char *attrs_to_read;
2110   gboolean res;
2111   GFileInfo *info;
2112   gboolean as_move;
2113   gboolean source_nofollow_symlinks;
2114
2115   as_move = flags & G_FILE_COPY_ALL_METADATA;
2116   source_nofollow_symlinks = flags & G_FILE_COPY_NOFOLLOW_SYMLINKS;
2117
2118   /* Ignore errors here, if the target supports no attributes there is nothing to copy */
2119   attributes = g_file_query_settable_attributes (destination, cancellable, NULL);
2120   namespaces = g_file_query_writable_namespaces (destination, cancellable, NULL);
2121
2122   if (attributes == NULL && namespaces == NULL)
2123     return TRUE;
2124
2125   attrs_to_read = build_attribute_list_for_copy (attributes, namespaces, as_move);
2126
2127   /* Ignore errors here, if we can't read some info (e.g. if it doesn't exist)
2128    * we just don't copy it. 
2129    */
2130   info = g_file_query_info (source, attrs_to_read,
2131                             source_nofollow_symlinks ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS:0,
2132                             cancellable,
2133                             NULL);
2134
2135   g_free (attrs_to_read);
2136   
2137   res = TRUE;
2138   if  (info)
2139     {
2140       res = g_file_set_attributes_from_info (destination,
2141                                              info, 0,
2142                                              cancellable,
2143                                              error);
2144       g_object_unref (info);
2145     }
2146   
2147   g_file_attribute_info_list_unref (attributes);
2148   g_file_attribute_info_list_unref (namespaces);
2149   
2150   return res;
2151 }
2152
2153 /* Closes the streams */
2154 static gboolean
2155 copy_stream_with_progress (GInputStream           *in,
2156                            GOutputStream          *out,
2157                            GFile                  *source,
2158                            GCancellable           *cancellable,
2159                            GFileProgressCallback   progress_callback,
2160                            gpointer                progress_callback_data,
2161                            GError                **error)
2162 {
2163   gssize n_read, n_written;
2164   goffset current_size;
2165   char buffer[1024*64], *p;
2166   gboolean res;
2167   goffset total_size;
2168   GFileInfo *info;
2169
2170   total_size = -1;
2171   info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (in),
2172                                          G_FILE_ATTRIBUTE_STANDARD_SIZE,
2173                                          cancellable, NULL);
2174   if (info)
2175     {
2176       if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE))
2177         total_size = g_file_info_get_size (info);
2178       g_object_unref (info);
2179     }
2180
2181   if (total_size == -1)
2182     {
2183       info = g_file_query_info (source, 
2184                                 G_FILE_ATTRIBUTE_STANDARD_SIZE,
2185                                 G_FILE_QUERY_INFO_NONE,
2186                                 cancellable, NULL);
2187       if (info)
2188         {
2189           if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE))
2190             total_size = g_file_info_get_size (info);
2191           g_object_unref (info);
2192         }
2193     }
2194
2195   if (total_size == -1)
2196     total_size = 0;
2197   
2198   current_size = 0;
2199   res = TRUE;
2200   while (TRUE)
2201     {
2202       n_read = g_input_stream_read (in, buffer, sizeof (buffer), cancellable, error);
2203       if (n_read == -1)
2204         {
2205           res = FALSE;
2206           break;
2207         }
2208         
2209       if (n_read == 0)
2210         break;
2211
2212       current_size += n_read;
2213
2214       p = buffer;
2215       while (n_read > 0)
2216         {
2217           n_written = g_output_stream_write (out, p, n_read, cancellable, error);
2218           if (n_written == -1)
2219             {
2220               res = FALSE;
2221               break;
2222             }
2223
2224           p += n_written;
2225           n_read -= n_written;
2226         }
2227
2228       if (!res)
2229         break;
2230
2231       if (progress_callback)
2232         progress_callback (current_size, total_size, progress_callback_data);
2233     }
2234
2235   if (!res)
2236     error = NULL; /* Ignore further errors */
2237
2238   /* Make sure we send full copied size */
2239   if (progress_callback)
2240     progress_callback (current_size, total_size, progress_callback_data);
2241   
2242   /* Don't care about errors in source here */
2243   g_input_stream_close (in, cancellable, NULL);
2244
2245   /* But write errors on close are bad! */
2246   if (!g_output_stream_close (out, cancellable, error))
2247     res = FALSE;
2248
2249   g_object_unref (in);
2250   g_object_unref (out);
2251       
2252   return res;
2253 }
2254
2255 static gboolean
2256 file_copy_fallback (GFile                  *source,
2257                     GFile                  *destination,
2258                     GFileCopyFlags          flags,
2259                     GCancellable           *cancellable,
2260                     GFileProgressCallback   progress_callback,
2261                     gpointer                progress_callback_data,
2262                     GError                **error)
2263 {
2264   GInputStream *in;
2265   GOutputStream *out;
2266   GFileInfo *info;
2267   const char *target;
2268
2269   /* Maybe copy the symlink? */
2270   if (flags & G_FILE_COPY_NOFOLLOW_SYMLINKS)
2271     {
2272       info = g_file_query_info (source,
2273                                 G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
2274                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
2275                                 cancellable,
2276                                 error);
2277       if (info == NULL)
2278         return FALSE;
2279
2280       if (g_file_info_get_file_type (info) == G_FILE_TYPE_SYMBOLIC_LINK &&
2281           (target = g_file_info_get_symlink_target (info)) != NULL)
2282         {
2283           if (!copy_symlink (destination, flags, cancellable, target, error))
2284             {
2285               g_object_unref (info);
2286               return FALSE;
2287             }
2288           
2289           g_object_unref (info);
2290           goto copied_file;
2291         }
2292       
2293       g_object_unref (info);
2294     }
2295   
2296   in = open_source_for_copy (source, destination, flags, cancellable, error);
2297   if (in == NULL)
2298     return FALSE;
2299   
2300   if (flags & G_FILE_COPY_OVERWRITE)
2301     {
2302       out = (GOutputStream *)g_file_replace (destination,
2303                                              NULL,
2304                                              flags & G_FILE_COPY_BACKUP,
2305                                              0,
2306                                              cancellable, error);
2307     }
2308   else
2309     {
2310       out = (GOutputStream *)g_file_create (destination, 0, cancellable, error);
2311     }
2312
2313   if (out == NULL)
2314     {
2315       g_object_unref (in);
2316       return FALSE;
2317     }
2318
2319   if (!copy_stream_with_progress (in, out, source, cancellable,
2320                                   progress_callback, progress_callback_data,
2321                                   error))
2322     return FALSE;
2323
2324  copied_file:
2325
2326   /* Ignore errors here. Failure to copy metadata is not a hard error */
2327   g_file_copy_attributes (source, destination,
2328                           flags, cancellable, NULL);
2329   
2330   return TRUE;
2331 }
2332
2333 /**
2334  * g_file_copy:
2335  * @source: input #GFile.
2336  * @destination: destination #GFile
2337  * @flags: set of #GFileCopyFlags
2338  * @cancellable: optional #GCancellable object, %NULL to ignore.
2339  * @progress_callback: function to callback with progress information
2340  * @progress_callback_data: user data to pass to @progress_callback
2341  * @error: #GError to set on error, or %NULL
2342  *
2343  * Copies the file @source to the location specified by @destination.
2344  * Can not handle recursive copies of directories.
2345  *
2346  * If the flag #G_FILE_COPY_OVERWRITE is specified an already
2347  * existing @destination file is overwritten.
2348  *
2349  * If the flag #G_FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks
2350  * will be copied as symlinks, otherwise the target of the
2351  * @source symlink will be copied.
2352  *
2353  * If @cancellable is not %NULL, then the operation can be cancelled by
2354  * triggering the cancellable object from another thread. If the operation
2355  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2356  * 
2357  * If @progress_callback is not %NULL, then the operation can be monitored by
2358  * setting this to a #GFileProgressCallback function. @progress_callback_data
2359  * will be passed to this function. It is guaranteed that this callback will
2360  * be called after all data has been transferred with the total number of bytes
2361  * copied during the operation.
2362  * 
2363  * If the @source file does not exist then the G_IO_ERROR_NOT_FOUND
2364  * error is returned, independent on the status of the @destination.
2365  *
2366  * If #G_FILE_COPY_OVERWRITE is not specified and the target exists, then the
2367  * error G_IO_ERROR_EXISTS is returned.
2368  *
2369  * If trying to overwrite a file over a directory the G_IO_ERROR_IS_DIRECTORY
2370  * error is returned. If trying to overwrite a directory with a directory the
2371  * G_IO_ERROR_WOULD_MERGE error is returned.
2372  *
2373  * If the source is a directory and the target does not exist, or #G_FILE_COPY_OVERWRITE is
2374  * specified and the target is a file, then the G_IO_ERROR_WOULD_RECURSE error
2375  * is returned.
2376  *
2377  * If you are interested in copying the #GFile object itself (not the on-disk
2378  * file), see g_file_dup().
2379  *
2380  * Returns: %TRUE on success, %FALSE otherwise.
2381  **/
2382 gboolean
2383 g_file_copy (GFile                  *source,
2384              GFile                  *destination,
2385              GFileCopyFlags          flags,
2386              GCancellable           *cancellable,
2387              GFileProgressCallback   progress_callback,
2388              gpointer                progress_callback_data,
2389              GError                **error)
2390 {
2391   GFileIface *iface;
2392   GError *my_error;
2393   gboolean res;
2394
2395   g_return_val_if_fail (G_IS_FILE (source), FALSE);
2396   g_return_val_if_fail (G_IS_FILE (destination), FALSE);
2397
2398   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2399     return FALSE;
2400   
2401   iface = G_FILE_GET_IFACE (destination);
2402   if (iface->copy)
2403     {
2404       my_error = NULL;
2405       res = (* iface->copy) (source, destination,
2406                              flags, cancellable,
2407                              progress_callback, progress_callback_data,
2408                              &my_error);
2409       
2410       if (res)
2411         return TRUE;
2412       
2413       if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2414         {
2415           g_propagate_error (error, my_error);
2416               return FALSE;
2417         }
2418     }
2419
2420   /* If the types are different, and the destination method failed
2421      also try the source method */
2422   if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination))
2423     {
2424       iface = G_FILE_GET_IFACE (source);
2425       
2426       if (iface->copy)
2427         {
2428           my_error = NULL;
2429           res = (* iface->copy) (source, destination,
2430                                  flags, cancellable,
2431                                  progress_callback, progress_callback_data,
2432                                  &my_error);
2433           
2434           if (res)
2435             return TRUE;
2436           
2437           if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2438             {
2439               g_propagate_error (error, my_error);
2440               return FALSE;
2441             }
2442         }
2443     }
2444   
2445   return file_copy_fallback (source, destination, flags, cancellable,
2446                              progress_callback, progress_callback_data,
2447                              error);
2448 }
2449
2450 /**
2451  * g_file_copy_async:
2452  * @source: input #GFile.
2453  * @destination: destination #GFile
2454  * @flags: set of #GFileCopyFlags
2455  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
2456  *     of the request. 
2457  * @cancellable: optional #GCancellable object, %NULL to ignore.
2458  * @progress_callback: function to callback with progress information
2459  * @progress_callback_data: user data to pass to @progress_callback
2460  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
2461  * @user_data: the data to pass to callback function
2462  *
2463  * Copies the file @source to the location specified by @destination 
2464  * asynchronously. For details of the behaviour, see g_file_copy().
2465  *
2466  * If @progress_callback is not %NULL, then that function that will be called
2467  * just like in g_file_copy(), however the callback will run in the main loop,
2468  * not in the thread that is doing the I/O operation.
2469  *
2470  * When the operation is finished, @callback will be called. You can then call
2471  * g_file_copy_finish() to get the result of the operation.
2472  **/
2473 void
2474 g_file_copy_async (GFile                  *source,
2475                    GFile                  *destination,
2476                    GFileCopyFlags          flags,
2477                    int                     io_priority,
2478                    GCancellable           *cancellable,
2479                    GFileProgressCallback   progress_callback,
2480                    gpointer                progress_callback_data,
2481                    GAsyncReadyCallback     callback,
2482                    gpointer                user_data)
2483 {
2484   GFileIface *iface;
2485
2486   g_return_if_fail (G_IS_FILE (source));
2487   g_return_if_fail (G_IS_FILE (destination));
2488
2489   iface = G_FILE_GET_IFACE (source);
2490   (* iface->copy_async) (source,
2491                          destination,
2492                          flags,
2493                          io_priority,
2494                          cancellable,
2495                          progress_callback,
2496                          progress_callback_data,
2497                          callback,
2498                          user_data);
2499 }
2500
2501 /**
2502  * g_file_copy_finish:
2503  * @file: input #GFile.
2504  * @res: a #GAsyncResult. 
2505  * @error: a #GError, or %NULL
2506  * 
2507  * Finishes copying the file started with 
2508  * g_file_copy_async().
2509  * 
2510  * Returns: a %TRUE on success, %FALSE on error.
2511  **/
2512 gboolean
2513 g_file_copy_finish (GFile        *file,
2514                     GAsyncResult *res,
2515                     GError      **error)
2516 {
2517   GFileIface *iface;
2518   
2519   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2520   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
2521
2522   if (G_IS_SIMPLE_ASYNC_RESULT (res))
2523     {
2524       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
2525       
2526       if (g_simple_async_result_propagate_error (simple, error))
2527         return FALSE;
2528     }
2529   
2530   iface = G_FILE_GET_IFACE (file);
2531   return (* iface->copy_finish) (file, res, error);
2532 }
2533
2534 /**
2535  * g_file_move:
2536  * @source: #GFile pointing to the source location.
2537  * @destination: #GFile pointing to the destination location.
2538  * @flags: set of #GFileCopyFlags.
2539  * @cancellable: optional #GCancellable object, %NULL to ignore.
2540  * @progress_callback: #GFileProgressCallback function for updates.
2541  * @progress_callback_data: gpointer to user data for the callback function.
2542  * @error: #GError for returning error conditions, or %NULL
2543  *
2544  *
2545  * Tries to move the file or directory @source to the location specified by @destination.
2546  * If native move operations are supported then this is used, otherwise a copy + delete
2547  * fallback is used. The native implementation may support moving directories (for instance
2548  * on moves inside the same filesystem), but the fallback code does not.
2549  * 
2550  * If the flag #G_FILE_COPY_OVERWRITE is specified an already
2551  * existing @destination file is overwritten.
2552  *
2553  * If the flag #G_FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks
2554  * will be copied as symlinks, otherwise the target of the
2555  * @source symlink will be copied.
2556  *
2557  * If @cancellable is not %NULL, then the operation can be cancelled by
2558  * triggering the cancellable object from another thread. If the operation
2559  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2560  * 
2561  * If @progress_callback is not %NULL, then the operation can be monitored by
2562  * setting this to a #GFileProgressCallback function. @progress_callback_data
2563  * will be passed to this function. It is guaranteed that this callback will
2564  * be called after all data has been transferred with the total number of bytes
2565  * copied during the operation.
2566  * 
2567  * If the @source file does not exist then the G_IO_ERROR_NOT_FOUND
2568  * error is returned, independent on the status of the @destination.
2569  *
2570  * If #G_FILE_COPY_OVERWRITE is not specified and the target exists, then the
2571  * error G_IO_ERROR_EXISTS is returned.
2572  *
2573  * If trying to overwrite a file over a directory the G_IO_ERROR_IS_DIRECTORY
2574  * error is returned. If trying to overwrite a directory with a directory the
2575  * G_IO_ERROR_WOULD_MERGE error is returned.
2576  *
2577  * If the source is a directory and the target does not exist, or #G_FILE_COPY_OVERWRITE is
2578  * specified and the target is a file, then the G_IO_ERROR_WOULD_RECURSE error
2579  * may be returned (if the native move operation isn't available).
2580  *
2581  * Returns: %TRUE on successful move, %FALSE otherwise.
2582  **/
2583 gboolean
2584 g_file_move (GFile                  *source,
2585              GFile                  *destination,
2586              GFileCopyFlags          flags,
2587              GCancellable           *cancellable,
2588              GFileProgressCallback   progress_callback,
2589              gpointer                progress_callback_data,
2590              GError                **error)
2591 {
2592   GFileIface *iface;
2593   GError *my_error;
2594   gboolean res;
2595
2596   g_return_val_if_fail (G_IS_FILE (source), FALSE);
2597   g_return_val_if_fail (G_IS_FILE (destination), FALSE);
2598
2599   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2600     return FALSE;
2601   
2602   iface = G_FILE_GET_IFACE (destination);
2603   if (iface->move)
2604     {
2605       my_error = NULL;
2606       res = (* iface->move) (source, destination,
2607                              flags, cancellable,
2608                              progress_callback, progress_callback_data,
2609                              &my_error);
2610       
2611       if (res)
2612         return TRUE;
2613       
2614       if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2615         {
2616           g_propagate_error (error, my_error);
2617           return FALSE;
2618         }
2619     }
2620
2621   /* If the types are different, and the destination method failed
2622      also try the source method */
2623   if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination))
2624     {
2625       iface = G_FILE_GET_IFACE (source);
2626       
2627       if (iface->move)
2628         {
2629           my_error = NULL;
2630           res = (* iface->move) (source, destination,
2631                                  flags, cancellable,
2632                                  progress_callback, progress_callback_data,
2633                                  &my_error);
2634           
2635           if (res)
2636             return TRUE;
2637           
2638           if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2639             {
2640               g_propagate_error (error, my_error);
2641               return FALSE;
2642             }
2643         }
2644     }
2645   
2646   if (flags & G_FILE_COPY_NO_FALLBACK_FOR_MOVE)
2647     {  
2648       g_set_error (error, G_IO_ERROR,
2649                    G_IO_ERROR_NOT_SUPPORTED,
2650                    _("Operation not supported"));
2651       return FALSE;
2652     }
2653   
2654   flags |= G_FILE_COPY_ALL_METADATA;
2655   if (!g_file_copy (source, destination, flags, cancellable,
2656                     progress_callback, progress_callback_data,
2657                     error))
2658     return FALSE;
2659
2660   return g_file_delete (source, cancellable, error);
2661 }
2662
2663 /**
2664  * g_file_make_directory
2665  * @file: input #GFile.
2666  * @cancellable: optional #GCancellable object, %NULL to ignore.
2667  * @error: a #GError, or %NULL 
2668  *
2669  * Creates a directory.
2670  * 
2671  * If @cancellable is not %NULL, then the operation can be cancelled by
2672  * triggering the cancellable object from another thread. If the operation
2673  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2674  * 
2675  * Returns: %TRUE on successful creation, %FALSE otherwise.
2676  **/
2677 gboolean
2678 g_file_make_directory (GFile         *file,
2679                        GCancellable  *cancellable,
2680                        GError       **error)
2681 {
2682   GFileIface *iface;
2683
2684   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2685
2686   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2687     return FALSE;
2688   
2689   iface = G_FILE_GET_IFACE (file);
2690
2691   if (iface->make_directory == NULL)
2692     {
2693       g_set_error (error, G_IO_ERROR,
2694                    G_IO_ERROR_NOT_SUPPORTED,
2695                    _("Operation not supported"));
2696       return FALSE;
2697     }
2698   
2699   return (* iface->make_directory) (file, cancellable, error);
2700 }
2701
2702 /**
2703  * g_file_make_symbolic_link:
2704  * @file: input #GFile.
2705  * @symlink_value: a string with the value of the new symlink.
2706  * @cancellable: optional #GCancellable object, %NULL to ignore.
2707  * @error: a #GError. 
2708  * 
2709  * Creates a symbolic link.
2710  *
2711  * If @cancellable is not %NULL, then the operation can be cancelled by
2712  * triggering the cancellable object from another thread. If the operation
2713  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2714  * 
2715  * Returns: %TRUE on the creation of a new symlink, %FALSE otherwise.
2716  **/
2717 gboolean
2718 g_file_make_symbolic_link (GFile         *file,
2719                            const char    *symlink_value,
2720                            GCancellable  *cancellable,
2721                            GError       **error)
2722 {
2723   GFileIface *iface;
2724
2725   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2726   g_return_val_if_fail (symlink_value != NULL, FALSE);
2727
2728   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2729     return FALSE;
2730
2731   if (*symlink_value == '\0')
2732     {
2733       g_set_error (error, G_IO_ERROR,
2734                    G_IO_ERROR_INVALID_ARGUMENT,
2735                    _("Invalid symlink value given"));
2736       return FALSE;
2737     }
2738   
2739   iface = G_FILE_GET_IFACE (file);
2740
2741   if (iface->make_symbolic_link == NULL)
2742     {
2743       g_set_error (error, G_IO_ERROR,
2744                    G_IO_ERROR_NOT_SUPPORTED,
2745                    _("Operation not supported"));
2746       return FALSE;
2747     }
2748   
2749   return (* iface->make_symbolic_link) (file, symlink_value, cancellable, error);
2750 }
2751
2752 /**
2753  * g_file_delete:
2754  * @file: input #GFile.
2755  * @cancellable: optional #GCancellable object, %NULL to ignore.
2756  * @error: a #GError, or %NULL 
2757  * 
2758  * Deletes a file. If the @file is a directory, it will only be deleted if it 
2759  * is empty.
2760  * 
2761  * If @cancellable is not %NULL, then the operation can be cancelled by
2762  * triggering the cancellable object from another thread. If the operation
2763  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2764  * 
2765  * Returns: %TRUE if the file was deleted. %FALSE otherwise.
2766  **/
2767 gboolean
2768 g_file_delete (GFile         *file,
2769                GCancellable  *cancellable,
2770                GError       **error)
2771 {
2772   GFileIface *iface;
2773   
2774   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2775
2776   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2777     return FALSE;
2778   
2779   iface = G_FILE_GET_IFACE (file);
2780
2781   if (iface->delete_file == NULL)
2782     {
2783       g_set_error (error, G_IO_ERROR,
2784                    G_IO_ERROR_NOT_SUPPORTED,
2785                    _("Operation not supported"));
2786       return FALSE;
2787     }
2788   
2789   return (* iface->delete_file) (file, cancellable, error);
2790 }
2791
2792 /**
2793  * g_file_trash:
2794  * @file: #GFile to send to trash.
2795  * @cancellable: optional #GCancellable object, %NULL to ignore.
2796  * @error: a #GError, or %NULL
2797  *
2798  * Sends @file to the "Trashcan", if possible. This is similar to
2799  * deleting it, but the user can recover it before emptying the trashcan.
2800  * Not all file systems support trashing, so this call can return the
2801  * %G_IO_ERROR_NOT_SUPPORTED error.
2802  *
2803  *
2804  * If @cancellable is not %NULL, then the operation can be cancelled by
2805  * triggering the cancellable object from another thread. If the operation
2806  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2807  * 
2808  * Returns: %TRUE on successful trash, %FALSE otherwise.
2809  **/
2810 gboolean
2811 g_file_trash (GFile         *file,
2812               GCancellable  *cancellable,
2813               GError       **error)
2814 {
2815   GFileIface *iface;
2816   
2817   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2818
2819   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2820     return FALSE;
2821   
2822   iface = G_FILE_GET_IFACE (file);
2823
2824   if (iface->trash == NULL)
2825     {
2826       g_set_error (error,
2827                    G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
2828                    _("Trash not supported"));
2829       return FALSE;
2830     }
2831   
2832   return (* iface->trash) (file, cancellable, error);
2833 }
2834
2835 /**
2836  * g_file_set_display_name:
2837  * @file: input #GFile.
2838  * @display_name: a string.
2839  * @cancellable: optional #GCancellable object, %NULL to ignore.
2840  * @error: a #GError, or %NULL
2841  * 
2842  * Renames @file to the specified display name.
2843  *
2844  * The display name is converted from UTF8 to the correct encoding for the target
2845  * filesystem if possible and the @file is renamed to this.
2846  * 
2847  * If you want to implement a rename operation in the user interface the edit name
2848  * (#G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME) should be used as the initial value in the rename
2849  * widget, and then the result after editing should be passed to g_file_set_display_name().
2850  *
2851  * On success the resulting converted filename is returned.
2852  * 
2853  * If @cancellable is not %NULL, then the operation can be cancelled by
2854  * triggering the cancellable object from another thread. If the operation
2855  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2856  * 
2857  * Returns: a #GFile specifying what @file was renamed to, or %NULL if there was an error.
2858  **/
2859 GFile *
2860 g_file_set_display_name (GFile         *file,
2861                          const char    *display_name,
2862                          GCancellable  *cancellable,
2863                          GError       **error)
2864 {
2865   GFileIface *iface;
2866   
2867   g_return_val_if_fail (G_IS_FILE (file), NULL);
2868   g_return_val_if_fail (display_name != NULL, NULL);
2869
2870   if (strchr (display_name, G_DIR_SEPARATOR) != NULL)
2871     {
2872       g_set_error (error,
2873                    G_IO_ERROR,
2874                    G_IO_ERROR_INVALID_ARGUMENT,
2875                    _("File names cannot contain '%c'"), G_DIR_SEPARATOR);
2876       return NULL;
2877     }
2878   
2879   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2880     return NULL;
2881   
2882   iface = G_FILE_GET_IFACE (file);
2883
2884   return (* iface->set_display_name) (file, display_name, cancellable, error);
2885 }
2886
2887 /**
2888  * g_file_set_display_name_async:
2889  * @file: input #GFile.
2890  * @display_name: a string.
2891  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
2892  *     of the request. 
2893  * @cancellable: optional #GCancellable object, %NULL to ignore.
2894  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
2895  * @user_data: the data to pass to callback function
2896  * 
2897  * Asynchronously sets the display name for a given #GFile.
2898  * 
2899  * For more details, see g_set_display_name() which is
2900  * the synchronous version of this call.
2901  *
2902  * When the operation is finished, @callback will be called. You can then call
2903  * g_file_set_display_name_finish() to get the result of the operation.
2904  **/
2905 void
2906 g_file_set_display_name_async (GFile               *file,
2907                                const char          *display_name,
2908                                int                  io_priority,
2909                                GCancellable        *cancellable,
2910                                GAsyncReadyCallback  callback,
2911                                gpointer             user_data)
2912 {
2913   GFileIface *iface;
2914   
2915   g_return_if_fail (G_IS_FILE (file));
2916   g_return_if_fail (display_name != NULL);
2917
2918   iface = G_FILE_GET_IFACE (file);
2919   (* iface->set_display_name_async) (file,
2920                                      display_name,
2921                                      io_priority,
2922                                      cancellable,
2923                                      callback,
2924                                      user_data);
2925 }
2926
2927 /**
2928  * g_file_set_display_name_finish:
2929  * @file: input #GFile.
2930  * @res: a #GAsyncResult. 
2931  * @error: a #GError, or %NULL
2932  * 
2933  * Finishes setting a display name started with 
2934  * g_file_set_display_name_async().
2935  * 
2936  * Returns: a #GFile or %NULL on error.
2937  **/
2938 GFile *
2939 g_file_set_display_name_finish (GFile         *file,
2940                                 GAsyncResult  *res,
2941                                 GError       **error)
2942 {
2943   GFileIface *iface;
2944   
2945   g_return_val_if_fail (G_IS_FILE (file), NULL);
2946   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2947
2948   if (G_IS_SIMPLE_ASYNC_RESULT (res))
2949     {
2950       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
2951       if (g_simple_async_result_propagate_error (simple, error))
2952         return NULL;
2953     }
2954   
2955   iface = G_FILE_GET_IFACE (file);
2956   return (* iface->set_display_name_finish) (file, res, error);
2957 }
2958
2959 /**
2960  * g_file_query_settable_attributes:
2961  * @file: input #GFile.
2962  * @cancellable: optional #GCancellable object, %NULL to ignore.
2963  * @error: a #GError, or %NULL
2964  * 
2965  * Obtain the list of settable attributes for the file.
2966  *
2967  * Returns the type and full attribute name of all the attributes 
2968  * that can be set on this file. This doesn't mean setting it will always 
2969  * succeed though, you might get an access failure, or some specific 
2970  * file may not support a specific attribute.
2971  *
2972  * If @cancellable is not %NULL, then the operation can be cancelled by
2973  * triggering the cancellable object from another thread. If the operation
2974  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2975  * 
2976  * Returns: a #GFileAttributeInfoList describing the settable attributes.
2977  * When you are done with it, release it with g_file_attribute_info_list_unref()
2978  **/
2979 GFileAttributeInfoList *
2980 g_file_query_settable_attributes (GFile         *file,
2981                                   GCancellable  *cancellable,
2982                                   GError       **error)
2983 {
2984   GFileIface *iface;
2985   GError *my_error;
2986   GFileAttributeInfoList *list;
2987
2988   g_return_val_if_fail (G_IS_FILE (file), NULL);
2989
2990   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2991     return NULL;
2992   
2993   iface = G_FILE_GET_IFACE (file);
2994
2995   if (iface->query_settable_attributes == NULL)
2996     return g_file_attribute_info_list_new ();
2997
2998   my_error = NULL;
2999   list = (* iface->query_settable_attributes) (file, cancellable, &my_error);
3000   
3001   if (list == NULL)
3002     {
3003       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
3004         {
3005           list = g_file_attribute_info_list_new ();
3006           g_error_free (my_error);
3007         }
3008       else
3009         g_propagate_error (error, my_error);
3010     }
3011   
3012   return list;
3013 }
3014
3015 /**
3016  * g_file_query_writable_namespaces:
3017  * @file: input #GFile.
3018  * @cancellable: optional #GCancellable object, %NULL to ignore.
3019  * @error: a #GError, or %NULL
3020  * 
3021  * Obtain the list of attribute namespaces where new attributes 
3022  * can be created by a user. An example of this is extended
3023  * attributes (in the "xattr" namespace).
3024  *
3025  * If @cancellable is not %NULL, then the operation can be cancelled by
3026  * triggering the cancellable object from another thread. If the operation
3027  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3028  * 
3029  * Returns: a #GFileAttributeInfoList describing the writable namespaces.
3030  * When you are done with it, release it with g_file_attribute_info_list_unref()
3031  **/
3032 GFileAttributeInfoList *
3033 g_file_query_writable_namespaces (GFile         *file,
3034                                   GCancellable  *cancellable,
3035                                   GError       **error)
3036 {
3037   GFileIface *iface;
3038   GError *my_error;
3039   GFileAttributeInfoList *list;
3040   
3041   g_return_val_if_fail (G_IS_FILE (file), NULL);
3042
3043   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3044     return NULL;
3045   
3046   iface = G_FILE_GET_IFACE (file);
3047
3048   if (iface->query_writable_namespaces == NULL)
3049     return g_file_attribute_info_list_new ();
3050
3051   my_error = NULL;
3052   list = (* iface->query_writable_namespaces) (file, cancellable, &my_error);
3053   
3054   if (list == NULL)
3055     {
3056       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
3057         {
3058           list = g_file_attribute_info_list_new ();
3059           g_error_free (my_error);
3060         }
3061       else
3062         g_propagate_error (error, my_error);
3063     }
3064   
3065   return list;
3066 }
3067
3068 /**
3069  * g_file_set_attribute:
3070  * @file: input #GFile.
3071  * @attribute: a string containing the attribute's name.
3072  * @type: The type of the attribute
3073  * @value_p: a pointer to the value (or the pointer itself if the type is a pointer type)
3074  * @flags: a set of #GFileQueryInfoFlags.
3075  * @cancellable: optional #GCancellable object, %NULL to ignore.
3076  * @error: a #GError, or %NULL
3077  * 
3078  * Sets an attribute in the file with attribute name @attribute to @value.
3079  * 
3080  * If @cancellable is not %NULL, then the operation can be cancelled by
3081  * triggering the cancellable object from another thread. If the operation
3082  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3083  * 
3084  * Returns: %TRUE if the attribute was set, %FALSE otherwise.
3085  **/
3086 gboolean
3087 g_file_set_attribute (GFile                      *file,
3088                       const char                 *attribute,
3089                       GFileAttributeType          type,
3090                       gpointer                    value_p,
3091                       GFileQueryInfoFlags         flags,
3092                       GCancellable               *cancellable,
3093                       GError                    **error)
3094 {
3095   GFileIface *iface;
3096   
3097   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3098   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
3099
3100   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3101     return FALSE;
3102   
3103   iface = G_FILE_GET_IFACE (file);
3104
3105   if (iface->set_attribute == NULL)
3106     {
3107       g_set_error (error, G_IO_ERROR,
3108                    G_IO_ERROR_NOT_SUPPORTED,
3109                    _("Operation not supported"));
3110       return FALSE;
3111     }
3112
3113   return (* iface->set_attribute) (file, attribute, type, value_p, flags, cancellable, error);
3114 }
3115
3116 /**
3117  * g_file_set_attributes_from_info:
3118  * @file: input #GFile.
3119  * @info: a #GFileInfo.
3120  * @flags: #GFileQueryInfoFlags
3121  * @cancellable: optional #GCancellable object, %NULL to ignore.
3122  * @error: a #GError, or %NULL 
3123  * 
3124  * Tries to set all attributes in the #GFileInfo on the target values, 
3125  * not stopping on the first error.
3126  * 
3127  * If there is any error during this operation then @error will be set to
3128  * the first error. Error on particular fields are flagged by setting 
3129  * the "status" field in the attribute value to 
3130  * %G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING, which means you can also detect
3131  * further errors.
3132  *
3133  * If @cancellable is not %NULL, then the operation can be cancelled by
3134  * triggering the cancellable object from another thread. If the operation
3135  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3136  * 
3137  * Returns: %TRUE if there was any error, %FALSE otherwise.
3138  **/
3139 gboolean
3140 g_file_set_attributes_from_info (GFile                *file,
3141                                  GFileInfo            *info,
3142                                  GFileQueryInfoFlags   flags,
3143                                  GCancellable         *cancellable,
3144                                  GError              **error)
3145 {
3146   GFileIface *iface;
3147
3148   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3149   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
3150
3151   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3152     return FALSE;
3153   
3154   g_file_info_clear_status (info);
3155   
3156   iface = G_FILE_GET_IFACE (file);
3157
3158   return (* iface->set_attributes_from_info) (file, 
3159                                               info, 
3160                                               flags, 
3161                                               cancellable, 
3162                                               error);
3163 }
3164
3165
3166 static gboolean
3167 g_file_real_set_attributes_from_info (GFile                *file,
3168                                       GFileInfo            *info,
3169                                       GFileQueryInfoFlags   flags,
3170                                       GCancellable         *cancellable,
3171                                       GError              **error)
3172 {
3173   char **attributes;
3174   int i;
3175   gboolean res;
3176   GFileAttributeValue *value;
3177   
3178   res = TRUE;
3179   
3180   attributes = g_file_info_list_attributes (info, NULL);
3181
3182   for (i = 0; attributes[i] != NULL; i++)
3183     {
3184       value = _g_file_info_get_attribute_value (info, attributes[i]);
3185
3186       if (value->status != G_FILE_ATTRIBUTE_STATUS_UNSET)
3187         continue;
3188
3189       if (!g_file_set_attribute (file, attributes[i],
3190                                  value->type, _g_file_attribute_value_peek_as_pointer (value),
3191                                  flags, cancellable, error))
3192         {
3193           value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING;
3194           res = FALSE;
3195           /* Don't set error multiple times */
3196           error = NULL;
3197         }
3198       else
3199         value->status = G_FILE_ATTRIBUTE_STATUS_SET;
3200     }
3201   
3202   g_strfreev (attributes);
3203   
3204   return res;
3205 }
3206
3207 /**
3208  * g_file_set_attributes_async:
3209  * @file: input #GFile.
3210  * @info: a #GFileInfo.
3211  * @flags: a #GFileQueryInfoFlags.
3212  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
3213  *     of the request. 
3214  * @cancellable: optional #GCancellable object, %NULL to ignore.
3215  * @callback: a #GAsyncReadyCallback. 
3216  * @user_data: a #gpointer.
3217  *
3218  * Asynchronously sets the attributes of @file with @info.
3219  * 
3220  * For more details, see g_file_set_attributes_from_info() which is
3221  * the synchronous version of this call.
3222  *
3223  * When the operation is finished, @callback will be called. You can then call
3224  * g_file_set_attributes_finish() to get the result of the operation.
3225  **/
3226 void
3227 g_file_set_attributes_async (GFile               *file,
3228                              GFileInfo           *info,
3229                              GFileQueryInfoFlags  flags,
3230                              int                  io_priority,
3231                              GCancellable        *cancellable,
3232                              GAsyncReadyCallback  callback,
3233                              gpointer             user_data)
3234 {
3235   GFileIface *iface;
3236   
3237   g_return_if_fail (G_IS_FILE (file));
3238   g_return_if_fail (G_IS_FILE_INFO (info));
3239
3240   iface = G_FILE_GET_IFACE (file);
3241   (* iface->set_attributes_async) (file, 
3242                                    info, 
3243                                    flags, 
3244                                    io_priority, 
3245                                    cancellable, 
3246                                    callback, 
3247                                    user_data);
3248 }
3249
3250 /**
3251  * g_file_set_attributes_finish:
3252  * @file: input #GFile.
3253  * @result: a #GAsyncResult.
3254  * @info: a #GFileInfo.
3255  * @error: a #GError, or %NULL
3256  * 
3257  * Finishes setting an attribute started in g_file_set_attributes_async().
3258  * 
3259  * Returns: %TRUE if the attributes were set correctly, %FALSE otherwise.
3260  **/
3261 gboolean
3262 g_file_set_attributes_finish (GFile         *file,
3263                               GAsyncResult  *result,
3264                               GFileInfo    **info,
3265                               GError       **error)
3266 {
3267   GFileIface *iface;
3268   
3269   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3270   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3271
3272   /* No standard handling of errors here, as we must set info even
3273    * on errors 
3274    */
3275   iface = G_FILE_GET_IFACE (file);
3276   return (* iface->set_attributes_finish) (file, result, info, error);
3277 }
3278
3279 /**
3280  * g_file_set_attribute_string:
3281  * @file: input #GFile.
3282  * @attribute: a string containing the attribute's name.
3283  * @value: a string containing the attribute's value.
3284  * @flags: #GFileQueryInfoFlags.
3285  * @cancellable: optional #GCancellable object, %NULL to ignore.
3286  * @error: a #GError, or %NULL
3287  * 
3288  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_STRING to @value. 
3289  * If @attribute is of a different type, this operation will fail.
3290  * 
3291  * If @cancellable is not %NULL, then the operation can be cancelled by
3292  * triggering the cancellable object from another thread. If the operation
3293  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3294  * 
3295  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
3296  **/
3297 gboolean
3298 g_file_set_attribute_string (GFile                *file,
3299                              const char           *attribute,
3300                              const char           *value,
3301                              GFileQueryInfoFlags   flags,
3302                              GCancellable         *cancellable,
3303                              GError              **error)
3304 {
3305   return g_file_set_attribute (file, attribute,
3306                                G_FILE_ATTRIBUTE_TYPE_STRING, (gpointer)value,
3307                                flags, cancellable, error);
3308 }
3309
3310 /**
3311  * g_file_set_attribute_byte_string:
3312  * @file: input #GFile.
3313  * @attribute: a string containing the attribute's name.
3314  * @value: a string containing the attribute's new value.
3315  * @flags: a #GFileQueryInfoFlags.
3316  * @cancellable: optional #GCancellable object, %NULL to ignore.
3317  * @error: a #GError, or %NULL
3318  * 
3319  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING to @value. 
3320  * If @attribute is of a different type, this operation will fail, 
3321  * returning %FALSE. 
3322  * 
3323  * If @cancellable is not %NULL, then the operation can be cancelled by
3324  * triggering the cancellable object from another thread. If the operation
3325  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3326  * 
3327  * Returns: %TRUE if the @attribute was successfully set to @value 
3328  * in the @file, %FALSE otherwise.
3329  **/
3330 gboolean
3331 g_file_set_attribute_byte_string  (GFile                *file,
3332                                    const char           *attribute,
3333                                    const char           *value,
3334                                    GFileQueryInfoFlags   flags,
3335                                    GCancellable         *cancellable,
3336                                    GError              **error)
3337 {
3338   return g_file_set_attribute (file, attribute,
3339                                G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, (gpointer)value,
3340                                flags, cancellable, error);
3341 }
3342
3343 /**
3344  * g_file_set_attribute_uint32:
3345  * @file: input #GFile.
3346  * @attribute: a string containing the attribute's name.
3347  * @value: a #guint32 containing the attribute's new value.
3348  * @flags: a #GFileQueryInfoFlags.
3349  * @cancellable: optional #GCancellable object, %NULL to ignore.
3350  * @error: a #GError, or %NULL
3351  * 
3352  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT32 to @value. 
3353  * If @attribute is of a different type, this operation will fail.
3354  * 
3355  * If @cancellable is not %NULL, then the operation can be cancelled by
3356  * triggering the cancellable object from another thread. If the operation
3357  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3358  * 
3359  * Returns: %TRUE if the @attribute was successfully set to @value 
3360  * in the @file, %FALSE otherwise.
3361  **/
3362 gboolean
3363 g_file_set_attribute_uint32 (GFile                *file,
3364                              const char           *attribute,
3365                              guint32               value,
3366                              GFileQueryInfoFlags   flags,
3367                              GCancellable         *cancellable,
3368                              GError              **error)
3369 {
3370   return g_file_set_attribute (file, attribute,
3371                                G_FILE_ATTRIBUTE_TYPE_UINT32, &value,
3372                                flags, cancellable, error);
3373 }
3374
3375 /**
3376  * g_file_set_attribute_int32:
3377  * @file: input #GFile.
3378  * @attribute: a string containing the attribute's name.
3379  * @value: a #gint32 containing the attribute's new value.
3380  * @flags: a #GFileQueryInfoFlags.
3381  * @cancellable: optional #GCancellable object, %NULL to ignore.
3382  * @error: a #GError, or %NULL
3383  * 
3384  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT32 to @value. 
3385  * If @attribute is of a different type, this operation will fail.
3386  * 
3387  * If @cancellable is not %NULL, then the operation can be cancelled by
3388  * triggering the cancellable object from another thread. If the operation
3389  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3390  * 
3391  * Returns: %TRUE if the @attribute was successfully set to @value 
3392  * in the @file, %FALSE otherwise. 
3393  **/
3394 gboolean
3395 g_file_set_attribute_int32 (GFile                *file,
3396                             const char           *attribute,
3397                             gint32                value,
3398                             GFileQueryInfoFlags   flags,
3399                             GCancellable         *cancellable,
3400                             GError              **error)
3401 {
3402   return g_file_set_attribute (file, attribute,
3403                                G_FILE_ATTRIBUTE_TYPE_INT32, &value,
3404                                flags, cancellable, error);
3405 }
3406
3407 /**
3408  * g_file_set_attribute_uint64:
3409  * @file: input #GFile. 
3410  * @attribute: a string containing the attribute's name.
3411  * @value: a #guint64 containing the attribute's new value.
3412  * @flags: a #GFileQueryInfoFlags.
3413  * @cancellable: optional #GCancellable object, %NULL to ignore.
3414  * @error: a #GError, or %NULL
3415  * 
3416  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT64 to @value. 
3417  * If @attribute is of a different type, this operation will fail.
3418  * 
3419  * If @cancellable is not %NULL, then the operation can be cancelled by
3420  * triggering the cancellable object from another thread. If the operation
3421  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3422  * 
3423  * Returns: %TRUE if the @attribute was successfully set to @value 
3424  * in the @file, %FALSE otherwise.
3425  **/
3426 gboolean
3427 g_file_set_attribute_uint64 (GFile                *file,
3428                              const char           *attribute,
3429                              guint64               value,
3430                              GFileQueryInfoFlags   flags,
3431                              GCancellable         *cancellable,
3432                              GError              **error)
3433  {
3434   return g_file_set_attribute (file, attribute,
3435                                G_FILE_ATTRIBUTE_TYPE_UINT64, &value,
3436                                flags, cancellable, error);
3437 }
3438
3439 /**
3440  * g_file_set_attribute_int64:
3441  * @file: input #GFile.
3442  * @attribute: a string containing the attribute's name.
3443  * @value: a #guint64 containing the attribute's new value.
3444  * @flags: a #GFileQueryInfoFlags.
3445  * @cancellable: optional #GCancellable object, %NULL to ignore.
3446  * @error: a #GError, or %NULL
3447  * 
3448  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT64 to @value. 
3449  * If @attribute is of a different type, this operation will fail.
3450  * 
3451  * If @cancellable is not %NULL, then the operation can be cancelled by
3452  * triggering the cancellable object from another thread. If the operation
3453  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3454  * 
3455  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
3456  **/
3457 gboolean
3458 g_file_set_attribute_int64 (GFile                *file,
3459                             const char           *attribute,
3460                             gint64                value,
3461                             GFileQueryInfoFlags   flags,
3462                             GCancellable         *cancellable,
3463                             GError              **error)
3464 {
3465   return g_file_set_attribute (file, attribute,
3466                                G_FILE_ATTRIBUTE_TYPE_INT64, &value,
3467                                flags, cancellable, error);
3468 }
3469
3470 /**
3471  * g_file_mount_mountable:
3472  * @file: input #GFile.
3473  * @flags: flags affecting the operation
3474  * @mount_operation: a #GMountOperation, or %NULL to avoid user interaction.
3475  * @cancellable: optional #GCancellable object, %NULL to ignore.
3476  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
3477  * @user_data: the data to pass to callback function
3478  * 
3479  * Mounts a file of type G_FILE_TYPE_MOUNTABLE.
3480  * Using @mount_operation, you can request callbacks when, for instance, 
3481  * passwords are needed during authentication.
3482  *
3483  * If @cancellable is not %NULL, then the operation can be cancelled by
3484  * triggering the cancellable object from another thread. If the operation
3485  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3486  *
3487  * When the operation is finished, @callback will be called. You can then call
3488  * g_file_mount_mountable_finish() to get the result of the operation.
3489  **/
3490 void
3491 g_file_mount_mountable (GFile               *file,
3492                         GMountMountFlags     flags,
3493                         GMountOperation     *mount_operation,
3494                         GCancellable        *cancellable,
3495                         GAsyncReadyCallback  callback,
3496                         gpointer             user_data)
3497 {
3498   GFileIface *iface;
3499
3500   g_return_if_fail (G_IS_FILE (file));
3501
3502   iface = G_FILE_GET_IFACE (file);
3503
3504   if (iface->mount_mountable == NULL) 
3505     {
3506       g_simple_async_report_error_in_idle (G_OBJECT (file),
3507                                            callback,
3508                                            user_data,
3509                                            G_IO_ERROR,
3510                                            G_IO_ERROR_NOT_SUPPORTED,
3511                                            _("Operation not supported"));
3512       return;
3513     }
3514   
3515   (* iface->mount_mountable) (file,
3516                               flags,
3517                               mount_operation,
3518                               cancellable,
3519                               callback,
3520                               user_data);
3521 }
3522
3523 /**
3524  * g_file_mount_mountable_finish:
3525  * @file: input #GFile.
3526  * @result: a #GAsyncResult.
3527  * @error: a #GError, or %NULL
3528  *
3529  * Finishes a mount operation. See g_file_mount_mountable() for details.
3530  * 
3531  * Finish an asynchronous mount operation that was started 
3532  * with g_file_mount_mountable().
3533  *
3534  * Returns: a #GFile or %NULL on error.
3535  **/
3536 GFile *
3537 g_file_mount_mountable_finish (GFile         *file,
3538                                GAsyncResult  *result,
3539                                GError       **error)
3540 {
3541   GFileIface *iface;
3542
3543   g_return_val_if_fail (G_IS_FILE (file), NULL);
3544   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
3545
3546   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3547     {
3548       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3549       if (g_simple_async_result_propagate_error (simple, error))
3550         return NULL;
3551     }
3552   
3553   iface = G_FILE_GET_IFACE (file);
3554   return (* iface->mount_mountable_finish) (file, result, error);
3555 }
3556
3557 /**
3558  * g_file_unmount_mountable:
3559  * @file: input #GFile.
3560  * @flags: flags affecting the operation
3561  * @cancellable: optional #GCancellable object, %NULL to ignore.
3562  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
3563  * @user_data: the data to pass to callback function
3564  *
3565  * Unmounts a file of type G_FILE_TYPE_MOUNTABLE.
3566  *
3567  * If @cancellable is not %NULL, then the operation can be cancelled by
3568  * triggering the cancellable object from another thread. If the operation
3569  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3570  *
3571  * When the operation is finished, @callback will be called. You can then call
3572  * g_file_unmount_mountable_finish() to get the result of the operation.
3573  **/
3574 void
3575 g_file_unmount_mountable (GFile               *file,
3576                           GMountUnmountFlags   flags,
3577                           GCancellable        *cancellable,
3578                           GAsyncReadyCallback  callback,
3579                           gpointer             user_data)
3580 {
3581   GFileIface *iface;
3582   
3583   g_return_if_fail (G_IS_FILE (file));
3584
3585   iface = G_FILE_GET_IFACE (file);
3586   
3587   if (iface->unmount_mountable == NULL)
3588     {
3589       g_simple_async_report_error_in_idle (G_OBJECT (file),
3590                                            callback,
3591                                            user_data,
3592                                            G_IO_ERROR,
3593                                            G_IO_ERROR_NOT_SUPPORTED,
3594                                            _("Operation not supported"));
3595       return;
3596     }
3597   
3598   (* iface->unmount_mountable) (file,
3599                                 flags,
3600                                 cancellable,
3601                                 callback,
3602                                 user_data);
3603 }
3604
3605 /**
3606  * g_file_unmount_mountable_finish:
3607  * @file: input #GFile.
3608  * @result: a #GAsyncResult.
3609  * @error: a #GError, or %NULL
3610  *
3611  * Finishes an unmount operation, see g_file_unmount_mountable() for details.
3612  * 
3613  * Finish an asynchronous unmount operation that was started 
3614  * with g_file_unmount_mountable().
3615  *
3616  * Returns: %TRUE if the operation finished successfully. %FALSE
3617  * otherwise.
3618  **/
3619 gboolean
3620 g_file_unmount_mountable_finish (GFile         *file,
3621                                  GAsyncResult  *result,
3622                                  GError       **error)
3623 {
3624   GFileIface *iface;
3625   
3626   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3627   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3628
3629   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3630     {
3631       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3632       if (g_simple_async_result_propagate_error (simple, error))
3633         return FALSE;
3634     }
3635   
3636   iface = G_FILE_GET_IFACE (file);
3637   return (* iface->unmount_mountable_finish) (file, result, error);
3638 }
3639
3640 /**
3641  * g_file_eject_mountable:
3642  * @file: input #GFile.
3643  * @flags: flags affecting the operation
3644  * @cancellable: optional #GCancellable object, %NULL to ignore.
3645  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
3646  * @user_data: the data to pass to callback function
3647  * 
3648  * Starts an asynchronous eject on a mountable.  
3649  * When this operation has completed, @callback will be called with
3650  * @user_user data, and the operation can be finalized with 
3651  * g_file_eject_mountable_finish().
3652  * 
3653  * If @cancellable is not %NULL, then the operation can be cancelled by
3654  * triggering the cancellable object from another thread. If the operation
3655  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3656  **/
3657 void
3658 g_file_eject_mountable (GFile               *file,
3659                         GMountUnmountFlags   flags,
3660                         GCancellable        *cancellable,
3661                         GAsyncReadyCallback  callback,
3662                         gpointer             user_data)
3663 {
3664   GFileIface *iface;
3665
3666   g_return_if_fail (G_IS_FILE (file));
3667
3668   iface = G_FILE_GET_IFACE (file);
3669   
3670   if (iface->eject_mountable == NULL) 
3671     {
3672       g_simple_async_report_error_in_idle (G_OBJECT (file),
3673                                            callback,
3674                                            user_data,
3675                                            G_IO_ERROR,
3676                                            G_IO_ERROR_NOT_SUPPORTED,
3677                                            _("Operation not supported"));
3678       return;
3679     }
3680   
3681   (* iface->eject_mountable) (file,
3682                               flags,
3683                               cancellable,
3684                               callback,
3685                               user_data);
3686 }
3687
3688 /**
3689  * g_file_eject_mountable_finish:
3690  * @file: input #GFile.
3691  * @result: a #GAsyncResult.
3692  * @error: a #GError, or %NULL
3693  * 
3694  * Finishes an asynchronous eject operation started by 
3695  * g_file_eject_mountable().
3696  * 
3697  * Returns: %TRUE if the @file was ejected successfully. %FALSE 
3698  * otherwise.
3699  **/
3700 gboolean
3701 g_file_eject_mountable_finish (GFile         *file,
3702                                GAsyncResult  *result,
3703                                GError       **error)
3704 {
3705   GFileIface *iface;
3706   
3707   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3708   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3709
3710   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3711     {
3712       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3713       if (g_simple_async_result_propagate_error (simple, error))
3714         return FALSE;
3715     }
3716   
3717   iface = G_FILE_GET_IFACE (file);
3718   return (* iface->eject_mountable_finish) (file, result, error);
3719 }
3720
3721 /**
3722  * g_file_monitor_directory:
3723  * @file: input #GFile.
3724  * @flags: a set of #GFileMonitorFlags.
3725  * @cancellable: optional #GCancellable object, %NULL to ignore.
3726  * @error: a #GError, or %NULL.
3727  * 
3728  * Obtains a directory monitor for the given file.
3729  * This may fail if directory monitoring is not supported.
3730  *
3731  * If @cancellable is not %NULL, then the operation can be cancelled by
3732  * triggering the cancellable object from another thread. If the operation
3733  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3734  * 
3735  * Returns: a #GFileMonitor for the given @file, 
3736  * or %NULL on error.
3737  **/
3738 GFileMonitor*
3739 g_file_monitor_directory (GFile             *file,
3740                           GFileMonitorFlags  flags,
3741                           GCancellable      *cancellable,
3742                           GError           **error)
3743 {
3744   GFileIface *iface;
3745
3746   g_return_val_if_fail (G_IS_FILE (file), NULL);
3747
3748   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3749     return NULL;
3750
3751   iface = G_FILE_GET_IFACE (file);
3752
3753   if (iface->monitor_dir == NULL)
3754     {
3755       g_set_error (error, G_IO_ERROR,
3756                    G_IO_ERROR_NOT_SUPPORTED,
3757                    _("Operation not supported"));
3758       return NULL;
3759     }
3760
3761   return (* iface->monitor_dir) (file, flags, cancellable, error);
3762 }
3763
3764 /**
3765  * g_file_monitor_file:
3766  * @file: input #GFile.
3767  * @flags: a set of #GFileMonitorFlags.
3768  * @cancellable: optional #GCancellable object, %NULL to ignore.
3769  * @error: a #GError, or %NULL.
3770  * 
3771  * Obtains a file monitor for the given file. If no file notification
3772  * mechanism exists, then regular polling of the file is used.
3773  *
3774  * If @cancellable is not %NULL, then the operation can be cancelled by
3775  * triggering the cancellable object from another thread. If the operation
3776  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3777  * 
3778  * Returns: a #GFileMonitor for the given @file.
3779  **/
3780 GFileMonitor*
3781 g_file_monitor_file (GFile             *file,
3782                      GFileMonitorFlags  flags,
3783                      GCancellable      *cancellable,
3784                      GError           **error)
3785 {
3786   GFileIface *iface;
3787   GFileMonitor *monitor;
3788   
3789   g_return_val_if_fail (G_IS_FILE (file), NULL);
3790
3791   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3792     return NULL;
3793
3794   iface = G_FILE_GET_IFACE (file);
3795
3796   monitor = NULL;
3797   
3798   if (iface->monitor_file)
3799     monitor = (* iface->monitor_file) (file, flags, cancellable, NULL);
3800
3801 /* Fallback to polling */
3802   if (monitor == NULL)
3803     monitor = _g_poll_file_monitor_new (file);
3804
3805   return monitor;
3806 }
3807
3808 /********************************************
3809  *   Default implementation of async ops    *
3810  ********************************************/
3811
3812 typedef struct {
3813   char *attributes;
3814   GFileQueryInfoFlags flags;
3815   GFileInfo *info;
3816 } QueryInfoAsyncData;
3817
3818 static void
3819 query_info_data_free (QueryInfoAsyncData *data)
3820 {
3821   if (data->info)
3822     g_object_unref (data->info);
3823   g_free (data->attributes);
3824   g_free (data);
3825 }
3826
3827 static void
3828 query_info_async_thread (GSimpleAsyncResult *res,
3829                          GObject            *object,
3830                          GCancellable       *cancellable)
3831 {
3832   GError *error = NULL;
3833   QueryInfoAsyncData *data;
3834   GFileInfo *info;
3835   
3836   data = g_simple_async_result_get_op_res_gpointer (res);
3837   
3838   info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error);
3839
3840   if (info == NULL)
3841     {
3842       g_simple_async_result_set_from_error (res, error);
3843       g_error_free (error);
3844     }
3845   else
3846     data->info = info;
3847 }
3848
3849 static void
3850 g_file_real_query_info_async (GFile               *file,
3851                               const char          *attributes,
3852                               GFileQueryInfoFlags  flags,
3853                               int                  io_priority,
3854                               GCancellable        *cancellable,
3855                               GAsyncReadyCallback  callback,
3856                               gpointer             user_data)
3857 {
3858   GSimpleAsyncResult *res;
3859   QueryInfoAsyncData *data;
3860
3861   data = g_new0 (QueryInfoAsyncData, 1);
3862   data->attributes = g_strdup (attributes);
3863   data->flags = flags;
3864   
3865   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_info_async);
3866   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_info_data_free);
3867   
3868   g_simple_async_result_run_in_thread (res, query_info_async_thread, io_priority, cancellable);
3869   g_object_unref (res);
3870 }
3871
3872 static GFileInfo *
3873 g_file_real_query_info_finish (GFile         *file,
3874                                GAsyncResult  *res,
3875                                GError       **error)
3876 {
3877   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3878   QueryInfoAsyncData *data;
3879
3880   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_info_async);
3881
3882   data = g_simple_async_result_get_op_res_gpointer (simple);
3883   if (data->info)
3884     return g_object_ref (data->info);
3885   
3886   return NULL;
3887 }
3888
3889 typedef struct {
3890   char *attributes;
3891   GFileInfo *info;
3892 } QueryFilesystemInfoAsyncData;
3893
3894 static void
3895 query_filesystem_info_data_free (QueryFilesystemInfoAsyncData *data)
3896 {
3897   if (data->info)
3898     g_object_unref (data->info);
3899   g_free (data->attributes);
3900   g_free (data);
3901 }
3902
3903 static void
3904 query_filesystem_info_async_thread (GSimpleAsyncResult *res,
3905                                     GObject            *object,
3906                                     GCancellable       *cancellable)
3907 {
3908   GError *error = NULL;
3909   QueryFilesystemInfoAsyncData *data;
3910   GFileInfo *info;
3911   
3912   data = g_simple_async_result_get_op_res_gpointer (res);
3913   
3914   info = g_file_query_filesystem_info (G_FILE (object), data->attributes, cancellable, &error);
3915
3916   if (info == NULL)
3917     {
3918       g_simple_async_result_set_from_error (res, error);
3919       g_error_free (error);
3920     }
3921   else
3922     data->info = info;
3923 }
3924
3925 static void
3926 g_file_real_query_filesystem_info_async (GFile               *file,
3927                                          const char          *attributes,
3928                                          int                  io_priority,
3929                                          GCancellable        *cancellable,
3930                                          GAsyncReadyCallback  callback,
3931                                          gpointer             user_data)
3932 {
3933   GSimpleAsyncResult *res;
3934   QueryFilesystemInfoAsyncData *data;
3935
3936   data = g_new0 (QueryFilesystemInfoAsyncData, 1);
3937   data->attributes = g_strdup (attributes);
3938   
3939   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_filesystem_info_async);
3940   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_filesystem_info_data_free);
3941   
3942   g_simple_async_result_run_in_thread (res, query_filesystem_info_async_thread, io_priority, cancellable);
3943   g_object_unref (res);
3944 }
3945
3946 static GFileInfo *
3947 g_file_real_query_filesystem_info_finish (GFile         *file,
3948                                           GAsyncResult  *res,
3949                                           GError       **error)
3950 {
3951   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3952   QueryFilesystemInfoAsyncData *data;
3953
3954   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_filesystem_info_async);
3955
3956   data = g_simple_async_result_get_op_res_gpointer (simple);
3957   if (data->info)
3958     return g_object_ref (data->info);
3959   
3960   return NULL;
3961 }
3962
3963 typedef struct {
3964   char *attributes;
3965   GFileQueryInfoFlags flags;
3966   GFileEnumerator *enumerator;
3967 } EnumerateChildrenAsyncData;
3968
3969 static void
3970 enumerate_children_data_free (EnumerateChildrenAsyncData *data)
3971 {
3972   if (data->enumerator)
3973     g_object_unref (data->enumerator);
3974   g_free (data->attributes);
3975   g_free (data);
3976 }
3977
3978 static void
3979 enumerate_children_async_thread (GSimpleAsyncResult *res,
3980                                  GObject            *object,
3981                                  GCancellable       *cancellable)
3982 {
3983   GError *error = NULL;
3984   EnumerateChildrenAsyncData *data;
3985   GFileEnumerator *enumerator;
3986   
3987   data = g_simple_async_result_get_op_res_gpointer (res);
3988   
3989   enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error);
3990
3991   if (enumerator == NULL)
3992     {
3993       g_simple_async_result_set_from_error (res, error);
3994       g_error_free (error);
3995     }
3996   else
3997     data->enumerator = enumerator;
3998 }
3999
4000 static void
4001 g_file_real_enumerate_children_async (GFile               *file,
4002                                       const char          *attributes,
4003                                       GFileQueryInfoFlags  flags,
4004                                       int                  io_priority,
4005                                       GCancellable        *cancellable,
4006                                       GAsyncReadyCallback  callback,
4007                                       gpointer             user_data)
4008 {
4009   GSimpleAsyncResult *res;
4010   EnumerateChildrenAsyncData *data;
4011
4012   data = g_new0 (EnumerateChildrenAsyncData, 1);
4013   data->attributes = g_strdup (attributes);
4014   data->flags = flags;
4015   
4016   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_enumerate_children_async);
4017   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)enumerate_children_data_free);
4018   
4019   g_simple_async_result_run_in_thread (res, enumerate_children_async_thread, io_priority, cancellable);
4020   g_object_unref (res);
4021 }
4022
4023 static GFileEnumerator *
4024 g_file_real_enumerate_children_finish (GFile         *file,
4025                                        GAsyncResult  *res,
4026                                        GError       **error)
4027 {
4028   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4029   EnumerateChildrenAsyncData *data;
4030
4031   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_enumerate_children_async);
4032
4033   data = g_simple_async_result_get_op_res_gpointer (simple);
4034   if (data->enumerator)
4035     return g_object_ref (data->enumerator);
4036   
4037   return NULL;
4038 }
4039
4040 static void
4041 open_read_async_thread (GSimpleAsyncResult *res,
4042                         GObject            *object,
4043                         GCancellable       *cancellable)
4044 {
4045   GFileIface *iface;
4046   GFileInputStream *stream;
4047   GError *error = NULL;
4048
4049   iface = G_FILE_GET_IFACE (object);
4050
4051   stream = iface->read_fn (G_FILE (object), cancellable, &error);
4052
4053   if (stream == NULL)
4054     {
4055       g_simple_async_result_set_from_error (res, error);
4056       g_error_free (error);
4057     }
4058   else
4059     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
4060 }
4061
4062 static void
4063 g_file_real_read_async (GFile               *file,
4064                         int                  io_priority,
4065                         GCancellable        *cancellable,
4066                         GAsyncReadyCallback  callback,
4067                         gpointer             user_data)
4068 {
4069   GSimpleAsyncResult *res;
4070   
4071   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_read_async);
4072   
4073   g_simple_async_result_run_in_thread (res, open_read_async_thread, io_priority, cancellable);
4074   g_object_unref (res);
4075 }
4076
4077 static GFileInputStream *
4078 g_file_real_read_finish (GFile         *file,
4079                          GAsyncResult  *res,
4080                          GError       **error)
4081 {
4082   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4083   gpointer op;
4084
4085   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_read_async);
4086
4087   op = g_simple_async_result_get_op_res_gpointer (simple);
4088   if (op)
4089     return g_object_ref (op);
4090   
4091   return NULL;
4092 }
4093
4094 static void
4095 append_to_async_thread (GSimpleAsyncResult *res,
4096                         GObject            *object,
4097                         GCancellable       *cancellable)
4098 {
4099   GFileIface *iface;
4100   GFileCreateFlags *data;
4101   GFileOutputStream *stream;
4102   GError *error = NULL;
4103
4104   iface = G_FILE_GET_IFACE (object);
4105
4106   data = g_simple_async_result_get_op_res_gpointer (res);
4107
4108   stream = iface->append_to (G_FILE (object), *data, cancellable, &error);
4109
4110   if (stream == NULL)
4111     {
4112       g_simple_async_result_set_from_error (res, error);
4113       g_error_free (error);
4114     }
4115   else
4116     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
4117 }
4118
4119 static void
4120 g_file_real_append_to_async (GFile               *file,
4121                              GFileCreateFlags     flags,
4122                              int                  io_priority,
4123                              GCancellable        *cancellable,
4124                              GAsyncReadyCallback  callback,
4125                              gpointer             user_data)
4126 {
4127   GFileCreateFlags *data;
4128   GSimpleAsyncResult *res;
4129
4130   data = g_new0 (GFileCreateFlags, 1);
4131   *data = flags;
4132
4133   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_append_to_async);
4134   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
4135
4136   g_simple_async_result_run_in_thread (res, append_to_async_thread, io_priority, cancellable);
4137   g_object_unref (res);
4138 }
4139
4140 static GFileOutputStream *
4141 g_file_real_append_to_finish (GFile         *file,
4142                               GAsyncResult  *res,
4143                               GError       **error)
4144 {
4145   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4146   gpointer op;
4147
4148   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_append_to_async);
4149
4150   op = g_simple_async_result_get_op_res_gpointer (simple);
4151   if (op)
4152     return g_object_ref (op);
4153   
4154   return NULL;
4155 }
4156
4157 static void
4158 create_async_thread (GSimpleAsyncResult *res,
4159                      GObject            *object,
4160                      GCancellable       *cancellable)
4161 {
4162   GFileIface *iface;
4163   GFileCreateFlags *data;
4164   GFileOutputStream *stream;
4165   GError *error = NULL;
4166
4167   iface = G_FILE_GET_IFACE (object);
4168
4169   data = g_simple_async_result_get_op_res_gpointer (res);
4170
4171   stream = iface->create (G_FILE (object), *data, cancellable, &error);
4172
4173   if (stream == NULL)
4174     {
4175       g_simple_async_result_set_from_error (res, error);
4176       g_error_free (error);
4177     }
4178   else
4179     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
4180 }
4181
4182 static void
4183 g_file_real_create_async (GFile               *file,
4184                           GFileCreateFlags     flags,
4185                           int                  io_priority,
4186                           GCancellable        *cancellable,
4187                           GAsyncReadyCallback  callback,
4188                           gpointer             user_data)
4189 {
4190   GFileCreateFlags *data;
4191   GSimpleAsyncResult *res;
4192
4193   data = g_new0 (GFileCreateFlags, 1);
4194   *data = flags;
4195
4196   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_create_async);
4197   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
4198
4199   g_simple_async_result_run_in_thread (res, create_async_thread, io_priority, cancellable);
4200   g_object_unref (res);
4201 }
4202
4203 static GFileOutputStream *
4204 g_file_real_create_finish (GFile         *file,
4205                            GAsyncResult  *res,
4206                            GError       **error)
4207 {
4208   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4209   gpointer op;
4210
4211   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_create_async);
4212
4213   op = g_simple_async_result_get_op_res_gpointer (simple);
4214   if (op)
4215     return g_object_ref (op);
4216   
4217   return NULL;
4218 }
4219
4220 typedef struct {
4221   GFileOutputStream *stream;
4222   char *etag;
4223   gboolean make_backup;
4224   GFileCreateFlags flags;
4225 } ReplaceAsyncData;
4226
4227 static void
4228 replace_async_data_free (ReplaceAsyncData *data)
4229 {
4230   if (data->stream)
4231     g_object_unref (data->stream);
4232   g_free (data->etag);
4233   g_free (data);
4234 }
4235
4236 static void
4237 replace_async_thread (GSimpleAsyncResult *res,
4238                       GObject            *object,
4239                       GCancellable       *cancellable)
4240 {
4241   GFileIface *iface;
4242   GFileOutputStream *stream;
4243   GError *error = NULL;
4244   ReplaceAsyncData *data;
4245
4246   iface = G_FILE_GET_IFACE (object);
4247   
4248   data = g_simple_async_result_get_op_res_gpointer (res);
4249
4250   stream = iface->replace (G_FILE (object),
4251                            data->etag,
4252                            data->make_backup,
4253                            data->flags,
4254                            cancellable,
4255                            &error);
4256
4257   if (stream == NULL)
4258     {
4259       g_simple_async_result_set_from_error (res, error);
4260       g_error_free (error);
4261     }
4262   else
4263     data->stream = stream;
4264 }
4265
4266 static void
4267 g_file_real_replace_async (GFile               *file,
4268                            const char          *etag,
4269                            gboolean             make_backup,
4270                            GFileCreateFlags     flags,
4271                            int                  io_priority,
4272                            GCancellable        *cancellable,
4273                            GAsyncReadyCallback  callback,
4274                            gpointer             user_data)
4275 {
4276   GSimpleAsyncResult *res;
4277   ReplaceAsyncData *data;
4278
4279   data = g_new0 (ReplaceAsyncData, 1);
4280   data->etag = g_strdup (etag);
4281   data->make_backup = make_backup;
4282   data->flags = flags;
4283
4284   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_replace_async);
4285   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_async_data_free);
4286
4287   g_simple_async_result_run_in_thread (res, replace_async_thread, io_priority, cancellable);
4288   g_object_unref (res);
4289 }
4290
4291 static GFileOutputStream *
4292 g_file_real_replace_finish (GFile         *file,
4293                             GAsyncResult  *res,
4294                             GError       **error)
4295 {
4296   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4297   ReplaceAsyncData *data;
4298
4299   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_replace_async);
4300
4301   data = g_simple_async_result_get_op_res_gpointer (simple);
4302   if (data->stream)
4303     return g_object_ref (data->stream);
4304   
4305   return NULL;
4306 }
4307
4308 typedef struct {
4309   char *name;
4310   GFile *file;
4311 } SetDisplayNameAsyncData;
4312
4313 static void
4314 set_display_name_data_free (SetDisplayNameAsyncData *data)
4315 {
4316   g_free (data->name);
4317   if (data->file)
4318     g_object_unref (data->file);
4319   g_free (data);
4320 }
4321
4322 static void
4323 set_display_name_async_thread (GSimpleAsyncResult *res,
4324                                GObject            *object,
4325                                GCancellable       *cancellable)
4326 {
4327   GError *error = NULL;
4328   SetDisplayNameAsyncData *data;
4329   GFile *file;
4330   
4331   data = g_simple_async_result_get_op_res_gpointer (res);
4332   
4333   file = g_file_set_display_name (G_FILE (object), data->name, cancellable, &error);
4334
4335   if (file == NULL)
4336     {
4337       g_simple_async_result_set_from_error (res, error);
4338       g_error_free (error);
4339     }
4340   else
4341     data->file = file;
4342 }
4343
4344 static void
4345 g_file_real_set_display_name_async (GFile               *file,  
4346                                     const char          *display_name,
4347                                     int                  io_priority,
4348                                     GCancellable        *cancellable,
4349                                     GAsyncReadyCallback  callback,
4350                                     gpointer             user_data)
4351 {
4352   GSimpleAsyncResult *res;
4353   SetDisplayNameAsyncData *data;
4354
4355   data = g_new0 (SetDisplayNameAsyncData, 1);
4356   data->name = g_strdup (display_name);
4357   
4358   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_display_name_async);
4359   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_display_name_data_free);
4360   
4361   g_simple_async_result_run_in_thread (res, set_display_name_async_thread, io_priority, cancellable);
4362   g_object_unref (res);
4363 }
4364
4365 static GFile *
4366 g_file_real_set_display_name_finish (GFile         *file,
4367                                      GAsyncResult  *res,
4368                                      GError       **error)
4369 {
4370   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4371   SetDisplayNameAsyncData *data;
4372
4373   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_display_name_async);
4374
4375   data = g_simple_async_result_get_op_res_gpointer (simple);
4376   if (data->file)
4377     return g_object_ref (data->file);
4378   
4379   return NULL;
4380 }
4381
4382 typedef struct {
4383   GFileQueryInfoFlags flags;
4384   GFileInfo *info;
4385   gboolean res;
4386   GError *error;
4387 } SetInfoAsyncData;
4388
4389 static void
4390 set_info_data_free (SetInfoAsyncData *data)
4391 {
4392   if (data->info)
4393     g_object_unref (data->info);
4394   if (data->error)
4395     g_error_free (data->error);
4396   g_free (data);
4397 }
4398
4399 static void
4400 set_info_async_thread (GSimpleAsyncResult *res,
4401                        GObject            *object,
4402                        GCancellable       *cancellable)
4403 {
4404   SetInfoAsyncData *data;
4405   
4406   data = g_simple_async_result_get_op_res_gpointer (res);
4407   
4408   data->error = NULL;
4409   data->res = g_file_set_attributes_from_info (G_FILE (object),
4410                                                data->info,
4411                                                data->flags,
4412                                                cancellable,
4413                                                &data->error);
4414 }
4415
4416 static void
4417 g_file_real_set_attributes_async (GFile               *file,
4418                                   GFileInfo           *info,
4419                                   GFileQueryInfoFlags  flags,
4420                                   int                  io_priority,
4421                                   GCancellable        *cancellable,
4422                                   GAsyncReadyCallback  callback,
4423                                   gpointer             user_data)
4424 {
4425   GSimpleAsyncResult *res;
4426   SetInfoAsyncData *data;
4427
4428   data = g_new0 (SetInfoAsyncData, 1);
4429   data->info = g_file_info_dup (info);
4430   data->flags = flags;
4431   
4432   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_attributes_async);
4433   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_info_data_free);
4434   
4435   g_simple_async_result_run_in_thread (res, set_info_async_thread, io_priority, cancellable);
4436   g_object_unref (res);
4437 }
4438
4439 static gboolean
4440 g_file_real_set_attributes_finish (GFile         *file,
4441                                    GAsyncResult  *res,
4442                                    GFileInfo    **info,
4443                                    GError       **error)
4444 {
4445   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4446   SetInfoAsyncData *data;
4447   
4448   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_attributes_async);
4449
4450   data = g_simple_async_result_get_op_res_gpointer (simple);
4451
4452   if (info) 
4453     *info = g_object_ref (data->info);
4454
4455   if (error != NULL && data->error) 
4456     *error = g_error_copy (data->error);
4457   
4458   return data->res;
4459 }
4460
4461 static void
4462 find_enclosing_mount_async_thread (GSimpleAsyncResult *res,
4463                                     GObject            *object,
4464                                     GCancellable       *cancellable)
4465 {
4466   GError *error = NULL;
4467   GMount *mount;
4468   
4469   mount = g_file_find_enclosing_mount (G_FILE (object), cancellable, &error);
4470
4471   if (mount == NULL)
4472     {
4473       g_simple_async_result_set_from_error (res, error);
4474       g_error_free (error);
4475     }
4476   else
4477     g_simple_async_result_set_op_res_gpointer (res, mount, (GDestroyNotify)g_object_unref);
4478 }
4479
4480 static void
4481 g_file_real_find_enclosing_mount_async (GFile               *file,
4482                                         int                  io_priority,
4483                                         GCancellable        *cancellable,
4484                                         GAsyncReadyCallback  callback,
4485                                         gpointer             user_data)
4486 {
4487   GSimpleAsyncResult *res;
4488   
4489   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_find_enclosing_mount_async);
4490   
4491   g_simple_async_result_run_in_thread (res, find_enclosing_mount_async_thread, io_priority, cancellable);
4492   g_object_unref (res);
4493 }
4494
4495 static GMount *
4496 g_file_real_find_enclosing_mount_finish (GFile         *file,
4497                                           GAsyncResult  *res,
4498                                           GError       **error)
4499 {
4500   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4501   GMount *mount;
4502
4503   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_find_enclosing_mount_async);
4504
4505   mount = g_simple_async_result_get_op_res_gpointer (simple);
4506   return g_object_ref (mount);
4507 }
4508
4509
4510 typedef struct {
4511   GFile *source;
4512   GFile *destination;
4513   GFileCopyFlags flags;
4514   GFileProgressCallback progress_cb;
4515   gpointer progress_cb_data;
4516   GIOSchedulerJob *job;
4517 } CopyAsyncData;
4518
4519 static void
4520 copy_async_data_free (CopyAsyncData *data)
4521 {
4522   g_object_unref (data->source);
4523   g_object_unref (data->destination);
4524   g_free (data);
4525 }
4526
4527 typedef struct {
4528   CopyAsyncData *data;
4529   goffset current_num_bytes;
4530   goffset total_num_bytes;
4531 } ProgressData;
4532
4533 static gboolean
4534 copy_async_progress_in_main (gpointer user_data)
4535 {
4536   ProgressData *progress = user_data;
4537   CopyAsyncData *data = progress->data;
4538
4539   data->progress_cb (progress->current_num_bytes,
4540                      progress->total_num_bytes,
4541                      data->progress_cb_data);
4542
4543   return FALSE;
4544 }
4545
4546 static gboolean
4547 mainloop_barrier (gpointer user_data)
4548 {
4549   /* Does nothing, but ensures all queued idles before
4550      this are run */
4551   return FALSE;
4552 }
4553
4554
4555 static void
4556 copy_async_progress_callback (goffset  current_num_bytes,
4557                               goffset  total_num_bytes,
4558                               gpointer user_data)
4559 {
4560   CopyAsyncData *data = user_data;
4561   ProgressData *progress;
4562
4563   progress = g_new (ProgressData, 1);
4564   progress->data = data;
4565   progress->current_num_bytes = current_num_bytes;
4566   progress->total_num_bytes = total_num_bytes;
4567   
4568   g_io_scheduler_job_send_to_mainloop_async (data->job,
4569                                              copy_async_progress_in_main,
4570                                              progress,
4571                                              g_free);
4572 }
4573
4574 static gboolean
4575 copy_async_thread (GIOSchedulerJob *job,
4576                    GCancellable    *cancellable,
4577                    gpointer         user_data)
4578 {
4579   GSimpleAsyncResult *res;
4580   CopyAsyncData *data;
4581   gboolean result;
4582   GError *error;
4583
4584   res = user_data;
4585   data = g_simple_async_result_get_op_res_gpointer (res);
4586
4587   error = NULL;
4588   data->job = job;
4589   result = g_file_copy (data->source,
4590                         data->destination,
4591                         data->flags,
4592                         cancellable,
4593                         (data->progress_cb != NULL) ? copy_async_progress_callback : NULL,
4594                         data,
4595                         &error);
4596
4597   /* Ensure all progress callbacks are done running in main thread */
4598   if (data->progress_cb != NULL)
4599     g_io_scheduler_job_send_to_mainloop (job,
4600                                          mainloop_barrier,
4601                                          NULL, NULL);
4602   
4603   if (!result)
4604     {
4605       g_simple_async_result_set_from_error (res, error);
4606       g_error_free (error);
4607     }
4608
4609   g_simple_async_result_complete_in_idle (res);
4610
4611   return FALSE;
4612 }
4613
4614 static void
4615 g_file_real_copy_async (GFile                  *source,
4616                         GFile                  *destination,
4617                         GFileCopyFlags          flags,
4618                         int                     io_priority,
4619                         GCancellable           *cancellable,
4620                         GFileProgressCallback   progress_callback,
4621                         gpointer                progress_callback_data,
4622                         GAsyncReadyCallback     callback,
4623                         gpointer                user_data)
4624 {
4625   GSimpleAsyncResult *res;
4626   CopyAsyncData *data;
4627
4628   data = g_new0 (CopyAsyncData, 1);
4629   data->source = g_object_ref (source);
4630   data->destination = g_object_ref (destination);
4631   data->flags = flags;
4632   data->progress_cb = progress_callback;
4633   data->progress_cb_data = progress_callback_data;
4634
4635   res = g_simple_async_result_new (G_OBJECT (source), callback, user_data, g_file_real_copy_async);
4636   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)copy_async_data_free);
4637
4638   g_io_scheduler_push_job (copy_async_thread, res, g_object_unref, io_priority, cancellable);
4639 }
4640
4641 static gboolean
4642 g_file_real_copy_finish (GFile        *file,
4643                          GAsyncResult *res,
4644                          GError      **error)
4645 {
4646   /* Error handled in g_file_copy_finish() */
4647   return TRUE;
4648 }
4649
4650
4651 /********************************************
4652  *   Default VFS operations                 *
4653  ********************************************/
4654
4655 /**
4656  * g_file_new_for_path:
4657  * @path: a string containing a relative or absolute path.
4658  * 
4659  * Constructs a #GFile for a given path. This operation never
4660  * fails, but the returned object might not support any I/O
4661  * operation if @path is malformed.
4662  * 
4663  * Returns: a new #GFile for the given @path. 
4664  **/
4665 GFile *
4666 g_file_new_for_path (const char *path)
4667 {
4668   g_return_val_if_fail (path != NULL, NULL);
4669
4670   return g_vfs_get_file_for_path (g_vfs_get_default (), path);
4671 }
4672  
4673 /**
4674  * g_file_new_for_uri:
4675  * @uri: a string containing a URI.
4676  * 
4677  * Constructs a #GFile for a given URI. This operation never 
4678  * fails, but the returned object might not support any I/O 
4679  * operation if @uri is malformed or if the uri type is 
4680  * not supported.
4681  * 
4682  * Returns: a #GFile for the given @uri.
4683  **/ 
4684 GFile *
4685 g_file_new_for_uri (const char *uri)
4686 {
4687   g_return_val_if_fail (uri != NULL, NULL);
4688
4689   return g_vfs_get_file_for_uri (g_vfs_get_default (), uri);
4690 }
4691   
4692 /**
4693  * g_file_parse_name:
4694  * @parse_name: a file name or path to be parsed.
4695  * 
4696  * Constructs a #GFile with the given @parse_name (i.e. something given by g_file_get_parse_name()).
4697  * This operation never fails, but the returned object might not support any I/O
4698  * operation if the @parse_name cannot be parsed.
4699  * 
4700  * Returns: a new #GFile.
4701  **/
4702 GFile *
4703 g_file_parse_name (const char *parse_name)
4704 {
4705   g_return_val_if_fail (parse_name != NULL, NULL);
4706
4707   return g_vfs_parse_name (g_vfs_get_default (), parse_name);
4708 }
4709
4710 static gboolean
4711 is_valid_scheme_character (char c)
4712 {
4713   return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.';
4714 }
4715
4716 static gboolean
4717 has_valid_scheme (const char *uri)
4718 {
4719   const char *p;
4720   
4721   p = uri;
4722   
4723   if (!is_valid_scheme_character (*p))
4724     return FALSE;
4725
4726   do {
4727     p++;
4728   } while (is_valid_scheme_character (*p));
4729
4730   return *p == ':';
4731 }
4732
4733 /**
4734  * g_file_new_for_commandline_arg:
4735  * @arg: a command line string.
4736  * 
4737  * Creates a #GFile with the given argument from the command line. The value of
4738  * @arg can be either a URI, an absolute path or a relative path resolved
4739  * relative to the current working directory.
4740  * This operation never fails, but the returned object might not support any
4741  * I/O operation if @arg points to a malformed path.
4742  *
4743  * Returns: a new #GFile. 
4744  **/
4745 GFile *
4746 g_file_new_for_commandline_arg (const char *arg)
4747 {
4748   GFile *file;
4749   char *filename;
4750   char *current_dir;
4751   
4752   g_return_val_if_fail (arg != NULL, NULL);
4753   
4754   if (g_path_is_absolute (arg))
4755     return g_file_new_for_path (arg);
4756
4757   if (has_valid_scheme (arg))
4758     return g_file_new_for_uri (arg);
4759     
4760   current_dir = g_get_current_dir ();
4761   filename = g_build_filename (current_dir, arg, NULL);
4762   g_free (current_dir);
4763   
4764   file = g_file_new_for_path (filename);
4765   g_free (filename);
4766   
4767   return file;
4768 }
4769
4770 /**
4771  * g_file_mount_enclosing_volume:
4772  * @location: input #GFile.
4773  * @flags: flags affecting the operation
4774  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
4775  * @cancellable: optional #GCancellable object, %NULL to ignore.
4776  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
4777  * @user_data: the data to pass to callback function
4778  * 
4779  * Starts a @mount_operation, mounting the volume that contains the file @location. 
4780  * 
4781  * When this operation has completed, @callback will be called with
4782  * @user_user data, and the operation can be finalized with 
4783  * g_file_mount_enclosing_volume_finish().
4784  * 
4785  * If @cancellable is not %NULL, then the operation can be cancelled by
4786  * triggering the cancellable object from another thread. If the operation
4787  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4788  **/
4789 void
4790 g_file_mount_enclosing_volume (GFile               *location,
4791                                GMountMountFlags     flags,
4792                                GMountOperation     *mount_operation,
4793                                GCancellable        *cancellable,
4794                                GAsyncReadyCallback  callback,
4795                                gpointer             user_data)
4796 {
4797   GFileIface *iface;
4798
4799   g_return_if_fail (G_IS_FILE (location));
4800
4801   iface = G_FILE_GET_IFACE (location);
4802
4803   if (iface->mount_enclosing_volume == NULL)
4804     {
4805       g_simple_async_report_error_in_idle (G_OBJECT (location),
4806                                            callback, user_data,
4807                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
4808                                            _("volume doesn't implement mount"));
4809       
4810       return;
4811     }
4812   
4813   (* iface->mount_enclosing_volume) (location, flags, mount_operation, cancellable, callback, user_data);
4814
4815 }
4816
4817 /**
4818  * g_file_mount_enclosing_volume_finish:
4819  * @location: input #GFile.
4820  * @result: a #GAsyncResult.
4821  * @error: a #GError, or %NULL
4822  * 
4823  * Finishes a mount operation started by g_file_mount_enclosing_volume().
4824  * 
4825  * Returns: %TRUE if successful. If an error
4826  * has occurred, this function will return %FALSE and set @error
4827  * appropriately if present.
4828  **/
4829 gboolean
4830 g_file_mount_enclosing_volume_finish (GFile         *location,
4831                                       GAsyncResult  *result,
4832                                       GError       **error)
4833 {
4834   GFileIface *iface;
4835
4836   g_return_val_if_fail (G_IS_FILE (location), FALSE);
4837   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4838
4839   if (G_IS_SIMPLE_ASYNC_RESULT (result))
4840     {
4841       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
4842       if (g_simple_async_result_propagate_error (simple, error))
4843         return FALSE;
4844     }
4845   
4846   iface = G_FILE_GET_IFACE (location);
4847
4848   return (* iface->mount_enclosing_volume_finish) (location, result, error);
4849 }
4850
4851 /********************************************
4852  *   Utility functions                      *
4853  ********************************************/
4854
4855 /**
4856  * g_file_query_default_handler:
4857  * @file: a #GFile to open.
4858  * @cancellable: optional #GCancellable object, %NULL to ignore.
4859  * @error: a #GError, or %NULL
4860  *
4861  * Returns the #GAppInfo that is registered as the default
4862  * application to handle the file specified by @file.
4863  *
4864  * If @cancellable is not %NULL, then the operation can be cancelled by
4865  * triggering the cancellable object from another thread. If the operation
4866  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4867  *
4868  * Returns: a #GAppInfo if the handle was found, %NULL if there were errors.
4869  * When you are done with it, release it with g_object_unref()
4870  **/
4871 GAppInfo *
4872 g_file_query_default_handler (GFile                  *file,
4873                               GCancellable           *cancellable,
4874                               GError                **error)
4875 {
4876   char *uri_scheme;
4877   const char *content_type;
4878   GAppInfo *appinfo;
4879   GFileInfo *info;
4880   char *path;
4881   
4882   uri_scheme = g_file_get_uri_scheme (file);
4883   appinfo = g_app_info_get_default_for_uri_scheme (uri_scheme);
4884   g_free (uri_scheme);
4885
4886   if (appinfo != NULL)
4887     return appinfo;
4888
4889   info = g_file_query_info (file,
4890                             G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
4891                             0,
4892                             cancellable,
4893                             error);
4894   if (info == NULL)
4895     return NULL;
4896
4897   appinfo = NULL;
4898
4899   content_type = g_file_info_get_content_type (info);
4900   if (content_type)
4901     {
4902       /* Don't use is_native(), as we want to support fuse paths if availible */
4903       path = g_file_get_path (file);
4904       appinfo = g_app_info_get_default_for_type (content_type,
4905                                                  path == NULL);
4906       g_free (path);
4907     }
4908   
4909   g_object_unref (info);
4910
4911   if (appinfo != NULL)
4912     return appinfo;
4913
4914   g_set_error (error, G_IO_ERROR,
4915                G_IO_ERROR_NOT_SUPPORTED,
4916                _("No application is registered as handling this file"));
4917   return NULL;
4918   
4919 }
4920
4921
4922 #define GET_CONTENT_BLOCK_SIZE 8192
4923
4924 /**
4925  * g_file_load_contents:
4926  * @file: input #GFile.
4927  * @cancellable: optional #GCancellable object, %NULL to ignore.
4928  * @contents: a location to place the contents of the file.
4929  * @length: a location to place the length of the contents of the file.
4930  * @etag_out: a location to place the current entity tag for the file.
4931  * @error: a #GError, or %NULL
4932  *
4933  * Loads the content of the file into memory, returning the size of
4934  * the data. The data is always zero terminated, but this is not
4935  * included in the resultant @length.
4936  * 
4937  * If @cancellable is not %NULL, then the operation can be cancelled by
4938  * triggering the cancellable object from another thread. If the operation
4939  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4940  * 
4941  * Returns: %TRUE if the @file's contents were successfully loaded.
4942  * %FALSE if there were errors..
4943  **/
4944 gboolean
4945 g_file_load_contents (GFile         *file,
4946                       GCancellable  *cancellable,
4947                       char         **contents,
4948                       gsize         *length,
4949                       char         **etag_out,
4950                       GError       **error)
4951 {
4952   GFileInputStream *in;
4953   GByteArray *content;
4954   gsize pos;
4955   gssize res;
4956   GFileInfo *info;
4957
4958   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4959   g_return_val_if_fail (contents != NULL, FALSE);
4960
4961   in = g_file_read (file, cancellable, error);
4962   if (in == NULL)
4963     return FALSE;
4964
4965   content = g_byte_array_new ();
4966   pos = 0;
4967   
4968   g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
4969   while ((res = g_input_stream_read (G_INPUT_STREAM (in),
4970                                      content->data + pos,
4971                                      GET_CONTENT_BLOCK_SIZE,
4972                                      cancellable, error)) > 0)
4973     {
4974       pos += res;
4975       g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
4976     }
4977
4978   if (etag_out)
4979     {
4980       *etag_out = NULL;
4981       
4982       info = g_file_input_stream_query_info (in,
4983                                              G_FILE_ATTRIBUTE_ETAG_VALUE,
4984                                              cancellable,
4985                                              NULL);
4986       if (info)
4987         {
4988           *etag_out = g_strdup (g_file_info_get_etag (info));
4989           g_object_unref (info);
4990         }
4991     } 
4992
4993   /* Ignore errors on close */
4994   g_input_stream_close (G_INPUT_STREAM (in), cancellable, NULL);
4995   g_object_unref (in);
4996
4997   if (res < 0)
4998     {
4999       /* error is set already */
5000       g_byte_array_free (content, TRUE);
5001       return FALSE;
5002     }
5003
5004   if (length)
5005     *length = pos;
5006
5007   /* Zero terminate (we got an extra byte allocated for this */
5008   content->data[pos] = 0;
5009   
5010   *contents = (char *)g_byte_array_free (content, FALSE);
5011   
5012   return TRUE;
5013 }
5014
5015 typedef struct {
5016   GFile *file;
5017   GError *error;
5018   GCancellable *cancellable;
5019   GFileReadMoreCallback read_more_callback;
5020   GAsyncReadyCallback callback;
5021   gpointer user_data;
5022   GByteArray *content;
5023   gsize pos;
5024   char *etag;
5025 } LoadContentsData;
5026
5027
5028 static void
5029 load_contents_data_free (LoadContentsData *data)
5030 {
5031   if (data->error)
5032     g_error_free (data->error);
5033   if (data->cancellable)
5034     g_object_unref (data->cancellable);
5035   if (data->content)
5036     g_byte_array_free (data->content, TRUE);
5037   g_free (data->etag);
5038   g_object_unref (data->file);
5039   g_free (data);
5040 }
5041
5042 static void
5043 load_contents_close_callback (GObject      *obj,
5044                               GAsyncResult *close_res,
5045                               gpointer      user_data)
5046 {
5047   GInputStream *stream = G_INPUT_STREAM (obj);
5048   LoadContentsData *data = user_data;
5049   GSimpleAsyncResult *res;
5050
5051   /* Ignore errors here, we're only reading anyway */
5052   g_input_stream_close_finish (stream, close_res, NULL);
5053   g_object_unref (stream);
5054
5055   res = g_simple_async_result_new (G_OBJECT (data->file),
5056                                    data->callback,
5057                                    data->user_data,
5058                                    g_file_load_contents_async);
5059   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)load_contents_data_free);
5060   g_simple_async_result_complete (res);
5061   g_object_unref (res);
5062 }
5063
5064 static void
5065 load_contents_fstat_callback (GObject      *obj,
5066                               GAsyncResult *stat_res,
5067                               gpointer      user_data)
5068 {
5069   GInputStream *stream = G_INPUT_STREAM (obj);
5070   LoadContentsData *data = user_data;
5071   GFileInfo *info;
5072
5073   info = g_file_input_stream_query_info_finish (G_FILE_INPUT_STREAM (stream),
5074                                                    stat_res, NULL);
5075   if (info)
5076     {
5077       data->etag = g_strdup (g_file_info_get_etag (info));
5078       g_object_unref (info);
5079     }
5080
5081   g_input_stream_close_async (stream, 0,
5082                               data->cancellable,
5083                               load_contents_close_callback, data);
5084 }
5085
5086 static void
5087 load_contents_read_callback (GObject      *obj,
5088                              GAsyncResult *read_res,
5089                              gpointer      user_data)
5090 {
5091   GInputStream *stream = G_INPUT_STREAM (obj);
5092   LoadContentsData *data = user_data;
5093   GError *error = NULL;
5094   gssize read_size;
5095
5096   read_size = g_input_stream_read_finish (stream, read_res, &error);
5097
5098   if (read_size < 0) 
5099     {
5100       /* Error or EOF, close the file */
5101       data->error = error;
5102       g_input_stream_close_async (stream, 0,
5103                                   data->cancellable,
5104                                   load_contents_close_callback, data);
5105     }
5106   else if (read_size == 0)
5107     {
5108       g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
5109                                             G_FILE_ATTRIBUTE_ETAG_VALUE,
5110                                             0,
5111                                             data->cancellable,
5112                                             load_contents_fstat_callback,
5113                                             data);
5114     }
5115   else if (read_size > 0)
5116     {
5117       data->pos += read_size;
5118       
5119       g_byte_array_set_size (data->content,
5120                              data->pos + GET_CONTENT_BLOCK_SIZE);
5121
5122
5123       if (data->read_more_callback &&
5124           !data->read_more_callback ((char *)data->content->data, data->pos, data->user_data))
5125         g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
5126                                               G_FILE_ATTRIBUTE_ETAG_VALUE,
5127                                               0,
5128                                               data->cancellable,
5129                                               load_contents_fstat_callback,
5130                                               data);
5131       else 
5132         g_input_stream_read_async (stream,
5133                                    data->content->data + data->pos,
5134                                    GET_CONTENT_BLOCK_SIZE,
5135                                    0,
5136                                    data->cancellable,
5137                                    load_contents_read_callback,
5138                                    data);
5139     }
5140 }
5141
5142 static void
5143 load_contents_open_callback (GObject      *obj,
5144                              GAsyncResult *open_res,
5145                              gpointer      user_data)
5146 {
5147   GFile *file = G_FILE (obj);
5148   GFileInputStream *stream;
5149   LoadContentsData *data = user_data;
5150   GError *error = NULL;
5151   GSimpleAsyncResult *res;
5152
5153   stream = g_file_read_finish (file, open_res, &error);
5154
5155   if (stream)
5156     {
5157       g_byte_array_set_size (data->content,
5158                              data->pos + GET_CONTENT_BLOCK_SIZE);
5159       g_input_stream_read_async (G_INPUT_STREAM (stream),
5160                                  data->content->data + data->pos,
5161                                  GET_CONTENT_BLOCK_SIZE,
5162                                  0,
5163                                  data->cancellable,
5164                                  load_contents_read_callback,
5165                                  data);
5166       
5167     }
5168   else
5169     {
5170       res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
5171                                                   data->callback,
5172                                                   data->user_data,
5173                                                   error);
5174       g_simple_async_result_complete (res);
5175       g_error_free (error);
5176       load_contents_data_free (data);
5177       g_object_unref (res);
5178     }
5179 }
5180
5181 /**
5182  * g_file_load_partial_contents_async:
5183  * @file: input #GFile.
5184  * @cancellable: optional #GCancellable object, %NULL to ignore.
5185  * @read_more_callback: a #GFileReadMoreCallback to receive partial data and to specify whether further data should be read.
5186  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
5187  * @user_data: the data to pass to the callback functions.
5188  *
5189  * Reads the partial contents of a file. A #GFileReadMoreCallback should be 
5190  * used to stop reading from the file when appropriate, else this function
5191  * will behave exactly as g_file_load_contents_async(). This operation 
5192  * can be finished by g_file_load_partial_contents_finish().
5193  *
5194  * Users of this function should be aware that @user_data is passed to 
5195  * both the @read_more_callback and the @callback.
5196  *
5197  * If @cancellable is not %NULL, then the operation can be cancelled by
5198  * triggering the cancellable object from another thread. If the operation
5199  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5200  **/
5201 void
5202 g_file_load_partial_contents_async (GFile                 *file,
5203                                     GCancellable          *cancellable,
5204                                     GFileReadMoreCallback  read_more_callback,
5205                                     GAsyncReadyCallback    callback,
5206                                     gpointer               user_data)
5207 {
5208   LoadContentsData *data;
5209
5210   g_return_if_fail (G_IS_FILE (file));
5211
5212   data = g_new0 (LoadContentsData, 1);
5213
5214   if (cancellable)
5215     data->cancellable = g_object_ref (cancellable);
5216   data->read_more_callback = read_more_callback;
5217   data->callback = callback;
5218   data->user_data = user_data;
5219   data->content = g_byte_array_new ();
5220   data->file = g_object_ref (file);
5221
5222   g_file_read_async (file,
5223                      0,
5224                      cancellable,
5225                      load_contents_open_callback,
5226                      data);
5227 }
5228
5229 /**
5230  * g_file_load_partial_contents_finish:
5231  * @file: input #GFile.
5232  * @res: a #GAsyncResult. 
5233  * @contents: a location to place the contents of the file.
5234  * @length: a location to place the length of the contents of the file.
5235  * @etag_out: a location to place the current entity tag for the file.
5236  * @error: a #GError, or %NULL
5237  * 
5238  * Finishes an asynchronous partial load operation that was started
5239  * with g_file_load_partial_contents_async().
5240  *
5241  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
5242  * present, it will be set appropriately. 
5243  **/
5244 gboolean
5245 g_file_load_partial_contents_finish (GFile         *file,
5246                                      GAsyncResult  *res,
5247                                      char         **contents,
5248                                      gsize         *length,
5249                                      char         **etag_out,
5250                                      GError       **error)
5251 {
5252   GSimpleAsyncResult *simple;
5253   LoadContentsData *data;
5254
5255   g_return_val_if_fail (G_IS_FILE (file), FALSE);
5256   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
5257   g_return_val_if_fail (contents != NULL, FALSE);
5258
5259   simple = G_SIMPLE_ASYNC_RESULT (res);
5260
5261   if (g_simple_async_result_propagate_error (simple, error))
5262     return FALSE;
5263   
5264   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_load_contents_async);
5265   
5266   data = g_simple_async_result_get_op_res_gpointer (simple);
5267
5268   if (data->error)
5269     {
5270       g_propagate_error (error, data->error);
5271       data->error = NULL;
5272       *contents = NULL;
5273       if (length)
5274         *length = 0;
5275       return FALSE;
5276     }
5277
5278   if (length)
5279     *length = data->pos;
5280
5281   if (etag_out)
5282     {
5283       *etag_out = data->etag;
5284       data->etag = NULL;
5285     }
5286
5287   /* Zero terminate */
5288   g_byte_array_set_size (data->content, data->pos + 1);
5289   data->content->data[data->pos] = 0;
5290   
5291   *contents = (char *)g_byte_array_free (data->content, FALSE);
5292   data->content = NULL;
5293
5294   return TRUE;
5295 }
5296
5297 /**
5298  * g_file_load_contents_async:
5299  * @file: input #GFile.
5300  * @cancellable: optional #GCancellable object, %NULL to ignore.
5301  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
5302  * @user_data: the data to pass to callback function
5303  * 
5304  * Starts an asynchronous load of the @file's contents.
5305  *
5306  * For more details, see g_file_load_contents() which is
5307  * the synchronous version of this call.
5308  *
5309  * When the load operation has completed, @callback will be called 
5310  * with @user data. To finish the operation, call 
5311  * g_file_load_contents_finish() with the #GAsyncResult returned by 
5312  * the @callback.
5313  * 
5314  * If @cancellable is not %NULL, then the operation can be cancelled by
5315  * triggering the cancellable object from another thread. If the operation
5316  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5317  **/
5318 void
5319 g_file_load_contents_async (GFile               *file,
5320                            GCancellable        *cancellable,
5321                            GAsyncReadyCallback  callback,
5322                            gpointer             user_data)
5323 {
5324   g_file_load_partial_contents_async (file,
5325                                       cancellable,
5326                                       NULL,
5327                                       callback, user_data);
5328 }
5329
5330 /**
5331  * g_file_load_contents_finish:
5332  * @file: input #GFile.
5333  * @res: a #GAsyncResult. 
5334  * @contents: a location to place the contents of the file.
5335  * @length: a location to place the length of the contents of the file.
5336  * @etag_out: a location to place the current entity tag for the file.
5337  * @error: a #GError, or %NULL
5338  * 
5339  * Finishes an asynchronous load of the @file's contents. 
5340  * The contents are placed in @contents, and @length is set to the 
5341  * size of the @contents string. If @etag_out is present, it will be 
5342  * set to the new entity tag for the @file.
5343  * 
5344  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
5345  * present, it will be set appropriately. 
5346  **/
5347 gboolean
5348 g_file_load_contents_finish (GFile         *file,
5349                              GAsyncResult  *res,
5350                              char         **contents,
5351                              gsize         *length,
5352                              char         **etag_out,
5353                              GError       **error)
5354 {
5355   return g_file_load_partial_contents_finish (file,
5356                                               res,
5357                                               contents,
5358                                               length,
5359                                               etag_out,
5360                                               error);
5361 }
5362   
5363 /**
5364  * g_file_replace_contents:
5365  * @file: input #GFile.
5366  * @contents: a string containing the new contents for @file.
5367  * @length: the length of @contents in bytes.
5368  * @etag: the old <link linkend="gfile-etag">entity tag</link> 
5369  *     for the document.
5370  * @make_backup: %TRUE if a backup should be created.
5371  * @flags: a set of #GFileCreateFlags.
5372  * @new_etag: a location to a new <link linkend="gfile-etag">entity tag</link>
5373  *      for the document. This should be freed with g_free() when no longer 
5374  *      needed.
5375  * @cancellable: optional #GCancellable object, %NULL to ignore.
5376  * @error: a #GError, or %NULL
5377  *
5378  * Replaces the contents of @file with @contents of @length bytes.
5379  
5380  * If @etag is specified (not %NULL) any existing file must have that etag, or
5381  * the error %G_IO_ERROR_WRONG_ETAG will be returned.
5382  *
5383  * If @make_backup is %TRUE, this function will attempt to make a backup of @file.
5384  * 
5385  * If @cancellable is not %NULL, then the operation can be cancelled by
5386  * triggering the cancellable object from another thread. If the operation
5387  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5388  *
5389  * The returned @new_etag can be used to verify that the file hasn't changed the
5390  * next time it is saved over.
5391  * 
5392  * Returns: %TRUE if successful. If an error
5393  * has occurred, this function will return %FALSE and set @error
5394  * appropriately if present.
5395  **/
5396 gboolean
5397 g_file_replace_contents (GFile             *file,
5398                          const char        *contents,
5399                          gsize              length,
5400                          const char        *etag,
5401                          gboolean           make_backup,
5402                          GFileCreateFlags   flags,
5403                          char             **new_etag,
5404                          GCancellable      *cancellable,
5405                          GError           **error)
5406 {
5407   GFileOutputStream *out;
5408   gsize pos, remainder;
5409   gssize res;
5410
5411   g_return_val_if_fail (G_IS_FILE (file), FALSE);
5412   g_return_val_if_fail (contents != NULL, FALSE);
5413
5414   out = g_file_replace (file, etag, make_backup, flags, cancellable, error);
5415   if (out == NULL)
5416     return FALSE;
5417
5418   pos = 0;
5419   remainder = length;
5420   while (remainder > 0 &&
5421          (res = g_output_stream_write (G_OUTPUT_STREAM (out),
5422                                        contents + pos,
5423                                        MIN (remainder, GET_CONTENT_BLOCK_SIZE),
5424                                        cancellable,
5425                                        error)) > 0)
5426     {
5427       pos += res;
5428       remainder -= res;
5429     }
5430   
5431   if (remainder > 0 && res < 0)
5432     {
5433       /* Ignore errors on close */
5434       g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, NULL);
5435       
5436       /* error is set already */
5437       return FALSE;
5438     }
5439   
5440   if (!g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, error))
5441     return FALSE;
5442
5443   if (new_etag)
5444     *new_etag = g_file_output_stream_get_etag (out);
5445   
5446   return TRUE;
5447 }
5448
5449 typedef struct {
5450   GFile *file;
5451   GError *error;
5452   GCancellable *cancellable;
5453   GAsyncReadyCallback callback;
5454   gpointer user_data;
5455   const char *content;
5456   gsize length;
5457   gsize pos;
5458   char *etag;
5459 } ReplaceContentsData;
5460
5461 static void
5462 replace_contents_data_free (ReplaceContentsData *data)
5463 {
5464   if (data->error)
5465     g_error_free (data->error);
5466   if (data->cancellable)
5467     g_object_unref (data->cancellable);
5468   g_object_unref (data->file);
5469   g_free (data->etag);
5470   g_free (data);
5471 }
5472
5473 static void
5474 replace_contents_close_callback (GObject      *obj,
5475                                  GAsyncResult *close_res,
5476                                  gpointer      user_data)
5477 {
5478   GOutputStream *stream = G_OUTPUT_STREAM (obj);
5479   ReplaceContentsData *data = user_data;
5480   GSimpleAsyncResult *res;
5481
5482   /* Ignore errors here, we're only reading anyway */
5483   g_output_stream_close_finish (stream, close_res, NULL);
5484   g_object_unref (stream);
5485
5486   data->etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (stream));
5487   
5488   res = g_simple_async_result_new (G_OBJECT (data->file),
5489                                    data->callback,
5490                                    data->user_data,
5491                                    g_file_replace_contents_async);
5492   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_contents_data_free);
5493   g_simple_async_result_complete (res);
5494   g_object_unref (res);
5495 }
5496
5497 static void
5498 replace_contents_write_callback (GObject      *obj,
5499                                  GAsyncResult *read_res,
5500                                  gpointer      user_data)
5501 {
5502   GOutputStream *stream = G_OUTPUT_STREAM (obj);
5503   ReplaceContentsData *data = user_data;
5504   GError *error = NULL;
5505   gssize write_size;
5506   
5507   write_size = g_output_stream_write_finish (stream, read_res, &error);
5508
5509   if (write_size <= 0) 
5510     {
5511       /* Error or EOF, close the file */
5512       if (write_size < 0)
5513         data->error = error;
5514       g_output_stream_close_async (stream, 0,
5515                                    data->cancellable,
5516                                    replace_contents_close_callback, data);
5517     }
5518   else if (write_size > 0)
5519     {
5520       data->pos += write_size;
5521
5522       if (data->pos >= data->length)
5523         g_output_stream_close_async (stream, 0,
5524                                      data->cancellable,
5525                                      replace_contents_close_callback, data);
5526       else
5527         g_output_stream_write_async (stream,
5528                                      data->content + data->pos,
5529                                      data->length - data->pos,
5530                                      0,
5531                                      data->cancellable,
5532                                      replace_contents_write_callback,
5533                                      data);
5534     }
5535 }
5536
5537 static void
5538 replace_contents_open_callback (GObject      *obj,
5539                                 GAsyncResult *open_res,
5540                                 gpointer      user_data)
5541 {
5542   GFile *file = G_FILE (obj);
5543   GFileOutputStream *stream;
5544   ReplaceContentsData *data = user_data;
5545   GError *error = NULL;
5546   GSimpleAsyncResult *res;
5547
5548   stream = g_file_replace_finish (file, open_res, &error);
5549
5550   if (stream)
5551     {
5552       g_output_stream_write_async (G_OUTPUT_STREAM (stream),
5553                                    data->content + data->pos,
5554                                    data->length - data->pos,
5555                                    0,
5556                                    data->cancellable,
5557                                    replace_contents_write_callback,
5558                                    data);
5559       
5560     }
5561   else
5562     {
5563       res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
5564                                                   data->callback,
5565                                                   data->user_data,
5566                                                   error);
5567       g_simple_async_result_complete (res);
5568       g_error_free (error);
5569       replace_contents_data_free (data);
5570       g_object_unref (res);
5571     }
5572 }
5573
5574 /**
5575  * g_file_replace_contents_async:
5576  * @file: input #GFile.
5577  * @contents: string of contents to replace the file with.
5578  * @length: the length of @contents in bytes.
5579  * @etag: a new <link linkend="gfile-etag">entity tag</link> for the @file.
5580  * @make_backup: %TRUE if a backup should be created.
5581  * @flags: a set of #GFileCreateFlags.
5582  * @cancellable: optional #GCancellable object, %NULL to ignore.
5583  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
5584  * @user_data: the data to pass to callback function
5585  * 
5586  * Starts an asynchronous replacement of @file with the given 
5587  * @contents of @length bytes. @etag will replace the document's 
5588  * current entity tag.
5589  * 
5590  * When this operation has completed, @callback will be called with
5591  * @user_user data, and the operation can be finalized with 
5592  * g_file_replace_contents_finish().
5593  * 
5594  * If @cancellable is not %NULL, then the operation can be cancelled by
5595  * triggering the cancellable object from another thread. If the operation
5596  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5597  * 
5598  * If @make_backup is %TRUE, this function will attempt to 
5599  * make a backup of @file.
5600  **/
5601 void
5602 g_file_replace_contents_async  (GFile               *file,
5603                                 const char          *contents,
5604                                 gsize                length,
5605                                 const char          *etag,
5606                                 gboolean             make_backup,
5607                                 GFileCreateFlags     flags,
5608                                 GCancellable        *cancellable,
5609                                 GAsyncReadyCallback  callback,
5610                                 gpointer             user_data)
5611 {
5612   ReplaceContentsData *data;
5613
5614   g_return_if_fail (G_IS_FILE (file));
5615   g_return_if_fail (contents != NULL);
5616
5617   data = g_new0 (ReplaceContentsData, 1);
5618
5619   if (cancellable)
5620     data->cancellable = g_object_ref (cancellable);
5621   data->callback = callback;
5622   data->user_data = user_data;
5623   data->content = contents;
5624   data->length = length;
5625   data->pos = 0;
5626   data->file = g_object_ref (file);
5627
5628   g_file_replace_async (file,
5629                         etag,
5630                         make_backup,
5631                         flags,
5632                         0,
5633                         cancellable,
5634                         replace_contents_open_callback,
5635                         data);
5636 }
5637   
5638 /**
5639  * g_file_replace_contents_finish:
5640  * @file: input #GFile.
5641  * @res: a #GAsyncResult. 
5642  * @new_etag: a location of a new <link linkend="gfile-etag">entity tag</link> 
5643  *     for the document. This should be freed with g_free() when it is no 
5644  *     longer needed.
5645  * @error: a #GError, or %NULL 
5646  * 
5647  * Finishes an asynchronous replace of the given @file. See
5648  * g_file_replace_contents_async(). Sets @new_etag to the new entity 
5649  * tag for the document, if present.
5650  * 
5651  * Returns: %TRUE on success, %FALSE on failure.
5652  **/
5653 gboolean
5654 g_file_replace_contents_finish (GFile         *file,
5655                                 GAsyncResult  *res,
5656                                 char         **new_etag,
5657                                 GError       **error)
5658 {
5659   GSimpleAsyncResult *simple;
5660   ReplaceContentsData *data;
5661
5662   g_return_val_if_fail (G_IS_FILE (file), FALSE);
5663   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
5664
5665   simple = G_SIMPLE_ASYNC_RESULT (res);
5666
5667   if (g_simple_async_result_propagate_error (simple, error))
5668     return FALSE;
5669   
5670   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_replace_contents_async);
5671   
5672   data = g_simple_async_result_get_op_res_gpointer (simple);
5673
5674   if (data->error)
5675     {
5676       g_propagate_error (error, data->error);
5677       data->error = NULL;
5678       return FALSE;
5679     }
5680
5681
5682   if (new_etag)
5683     {
5684       *new_etag = data->etag;
5685       data->etag = NULL; /* Take ownership */
5686     }
5687   
5688   return TRUE;
5689 }
5690
5691 #define __G_FILE_C__
5692 #include "gioaliasdef.c"