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