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