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