Test runtime dir getter
[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: #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 inital 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 "fs:*" means all attributes in the fs
1203  * namespace. The standard namespace for filesystem attributes is "fs".
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: (scope call): function to callback with progress information
2993  * @progress_callback_data: (closure): user data to pass to @progress_callback
2994  * @error: #GError to set on error, or %NULL
2995  *
2996  * Copies the file @source to the location specified by @destination.
2997  * Can not handle recursive copies of directories.
2998  *
2999  * If the flag #G_FILE_COPY_OVERWRITE is specified an already
3000  * existing @destination file is overwritten.
3001  *
3002  * If the flag #G_FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks
3003  * will be copied as symlinks, otherwise the target of the
3004  * @source symlink will be copied.
3005  *
3006  * If @cancellable is not %NULL, then the operation can be cancelled by
3007  * triggering the cancellable object from another thread. If the operation
3008  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3009  * 
3010  * If @progress_callback is not %NULL, then the operation can be monitored by
3011  * setting this to a #GFileProgressCallback function. @progress_callback_data
3012  * will be passed to this function. It is guaranteed that this callback will
3013  * be called after all data has been transferred with the total number of bytes
3014  * copied during the operation.
3015  * 
3016  * If the @source file does not exist then the G_IO_ERROR_NOT_FOUND
3017  * error is returned, independent on the status of the @destination.
3018  *
3019  * If #G_FILE_COPY_OVERWRITE is not specified and the target exists, then the
3020  * error G_IO_ERROR_EXISTS is returned.
3021  *
3022  * If trying to overwrite a file over a directory the G_IO_ERROR_IS_DIRECTORY
3023  * error is returned. If trying to overwrite a directory with a directory the
3024  * G_IO_ERROR_WOULD_MERGE error is returned.
3025  *
3026  * If the source is a directory and the target does not exist, or #G_FILE_COPY_OVERWRITE is
3027  * specified and the target is a file, then the G_IO_ERROR_WOULD_RECURSE error
3028  * is returned.
3029  *
3030  * If you are interested in copying the #GFile object itself (not the on-disk
3031  * file), see g_file_dup().
3032  *
3033  * Returns: %TRUE on success, %FALSE otherwise.
3034  **/
3035 gboolean
3036 g_file_copy (GFile                  *source,
3037              GFile                  *destination,
3038              GFileCopyFlags          flags,
3039              GCancellable           *cancellable,
3040              GFileProgressCallback   progress_callback,
3041              gpointer                progress_callback_data,
3042              GError                **error)
3043 {
3044   GFileIface *iface;
3045   GError *my_error;
3046   gboolean res;
3047
3048   g_return_val_if_fail (G_IS_FILE (source), FALSE);
3049   g_return_val_if_fail (G_IS_FILE (destination), FALSE);
3050
3051   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3052     return FALSE;
3053   
3054   iface = G_FILE_GET_IFACE (destination);
3055   if (iface->copy)
3056     {
3057       my_error = NULL;
3058       res = (* iface->copy) (source, destination,
3059                              flags, cancellable,
3060                              progress_callback, progress_callback_data,
3061                              &my_error);
3062       
3063       if (res)
3064         return TRUE;
3065       
3066       if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
3067         {
3068           g_propagate_error (error, my_error);
3069               return FALSE;
3070         }
3071       else
3072         g_clear_error (&my_error);
3073     }
3074
3075   /* If the types are different, and the destination method failed
3076      also try the source method */
3077   if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination))
3078     {
3079       iface = G_FILE_GET_IFACE (source);
3080       
3081       if (iface->copy)
3082         {
3083           my_error = NULL;
3084           res = (* iface->copy) (source, destination,
3085                                  flags, cancellable,
3086                                  progress_callback, progress_callback_data,
3087                                  &my_error);
3088           
3089           if (res)
3090             return TRUE;
3091           
3092           if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
3093             {
3094               g_propagate_error (error, my_error);
3095               return FALSE;
3096             }
3097           else
3098             g_clear_error (&my_error);
3099         }
3100     }
3101   
3102   return file_copy_fallback (source, destination, flags, cancellable,
3103                              progress_callback, progress_callback_data,
3104                              error);
3105 }
3106
3107 /**
3108  * g_file_copy_async: (skip)
3109  * @source: input #GFile.
3110  * @destination: destination #GFile
3111  * @flags: set of #GFileCopyFlags
3112  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
3113  *     of the request. 
3114  * @cancellable: optional #GCancellable object, %NULL to ignore.
3115  * @progress_callback: function to callback with progress information
3116  * @progress_callback_data: user data to pass to @progress_callback
3117  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
3118  * @user_data: the data to pass to callback function
3119  *
3120  * Copies the file @source to the location specified by @destination 
3121  * asynchronously. For details of the behaviour, see g_file_copy().
3122  *
3123  * If @progress_callback is not %NULL, then that function that will be called
3124  * just like in g_file_copy(), however the callback will run in the main loop,
3125  * not in the thread that is doing the I/O operation.
3126  *
3127  * When the operation is finished, @callback will be called. You can then call
3128  * g_file_copy_finish() to get the result of the operation.
3129  **/
3130 void
3131 g_file_copy_async (GFile                  *source,
3132                    GFile                  *destination,
3133                    GFileCopyFlags          flags,
3134                    int                     io_priority,
3135                    GCancellable           *cancellable,
3136                    GFileProgressCallback   progress_callback,
3137                    gpointer                progress_callback_data,
3138                    GAsyncReadyCallback     callback,
3139                    gpointer                user_data)
3140 {
3141   GFileIface *iface;
3142
3143   g_return_if_fail (G_IS_FILE (source));
3144   g_return_if_fail (G_IS_FILE (destination));
3145
3146   iface = G_FILE_GET_IFACE (source);
3147   (* iface->copy_async) (source,
3148                          destination,
3149                          flags,
3150                          io_priority,
3151                          cancellable,
3152                          progress_callback,
3153                          progress_callback_data,
3154                          callback,
3155                          user_data);
3156 }
3157
3158 /**
3159  * g_file_copy_finish:
3160  * @file: input #GFile.
3161  * @res: a #GAsyncResult. 
3162  * @error: a #GError, or %NULL
3163  * 
3164  * Finishes copying the file started with 
3165  * g_file_copy_async().
3166  * 
3167  * Returns: a %TRUE on success, %FALSE on error.
3168  **/
3169 gboolean
3170 g_file_copy_finish (GFile        *file,
3171                     GAsyncResult *res,
3172                     GError      **error)
3173 {
3174   GFileIface *iface;
3175   
3176   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3177   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
3178
3179   if (G_IS_SIMPLE_ASYNC_RESULT (res))
3180     {
3181       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3182       
3183       if (g_simple_async_result_propagate_error (simple, error))
3184         return FALSE;
3185     }
3186   
3187   iface = G_FILE_GET_IFACE (file);
3188   return (* iface->copy_finish) (file, res, error);
3189 }
3190
3191 /**
3192  * g_file_move:
3193  * @source: #GFile pointing to the source location.
3194  * @destination: #GFile pointing to the destination location.
3195  * @flags: set of #GFileCopyFlags.
3196  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3197  * @progress_callback: (scope call): #GFileProgressCallback function for updates.
3198  * @progress_callback_data: (closure): gpointer to user data for the callback function.
3199  * @error: #GError for returning error conditions, or %NULL
3200  *
3201  *
3202  * Tries to move the file or directory @source to the location specified by @destination.
3203  * If native move operations are supported then this is used, otherwise a copy + delete
3204  * fallback is used. The native implementation may support moving directories (for instance
3205  * on moves inside the same filesystem), but the fallback code does not.
3206  * 
3207  * If the flag #G_FILE_COPY_OVERWRITE is specified an already
3208  * existing @destination file is overwritten.
3209  *
3210  * If the flag #G_FILE_COPY_NOFOLLOW_SYMLINKS is specified then symlinks
3211  * will be copied as symlinks, otherwise the target of the
3212  * @source symlink will be copied.
3213  *
3214  * If @cancellable is not %NULL, then the operation can be cancelled by
3215  * triggering the cancellable object from another thread. If the operation
3216  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3217  * 
3218  * If @progress_callback is not %NULL, then the operation can be monitored by
3219  * setting this to a #GFileProgressCallback function. @progress_callback_data
3220  * will be passed to this function. It is guaranteed that this callback will
3221  * be called after all data has been transferred with the total number of bytes
3222  * copied during the operation.
3223  * 
3224  * If the @source file does not exist then the G_IO_ERROR_NOT_FOUND
3225  * error is returned, independent on the status of the @destination.
3226  *
3227  * If #G_FILE_COPY_OVERWRITE is not specified and the target exists, then the
3228  * error G_IO_ERROR_EXISTS is returned.
3229  *
3230  * If trying to overwrite a file over a directory the G_IO_ERROR_IS_DIRECTORY
3231  * error is returned. If trying to overwrite a directory with a directory the
3232  * G_IO_ERROR_WOULD_MERGE error is returned.
3233  *
3234  * If the source is a directory and the target does not exist, or #G_FILE_COPY_OVERWRITE is
3235  * specified and the target is a file, then the G_IO_ERROR_WOULD_RECURSE error
3236  * may be returned (if the native move operation isn't available).
3237  *
3238  * Returns: %TRUE on successful move, %FALSE otherwise.
3239  **/
3240 gboolean
3241 g_file_move (GFile                  *source,
3242              GFile                  *destination,
3243              GFileCopyFlags          flags,
3244              GCancellable           *cancellable,
3245              GFileProgressCallback   progress_callback,
3246              gpointer                progress_callback_data,
3247              GError                **error)
3248 {
3249   GFileIface *iface;
3250   GError *my_error;
3251   gboolean res;
3252
3253   g_return_val_if_fail (G_IS_FILE (source), FALSE);
3254   g_return_val_if_fail (G_IS_FILE (destination), FALSE);
3255
3256   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3257     return FALSE;
3258   
3259   iface = G_FILE_GET_IFACE (destination);
3260   if (iface->move)
3261     {
3262       my_error = NULL;
3263       res = (* iface->move) (source, destination,
3264                              flags, cancellable,
3265                              progress_callback, progress_callback_data,
3266                              &my_error);
3267       
3268       if (res)
3269         return TRUE;
3270       
3271       if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
3272         {
3273           g_propagate_error (error, my_error);
3274           return FALSE;
3275         }
3276     }
3277
3278   /* If the types are different, and the destination method failed
3279      also try the source method */
3280   if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination))
3281     {
3282       iface = G_FILE_GET_IFACE (source);
3283       
3284       if (iface->move)
3285         {
3286           my_error = NULL;
3287           res = (* iface->move) (source, destination,
3288                                  flags, cancellable,
3289                                  progress_callback, progress_callback_data,
3290                                  &my_error);
3291           
3292           if (res)
3293             return TRUE;
3294           
3295           if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
3296             {
3297               g_propagate_error (error, my_error);
3298               return FALSE;
3299             }
3300         }
3301     }
3302   
3303   if (flags & G_FILE_COPY_NO_FALLBACK_FOR_MOVE)
3304     {  
3305       g_set_error_literal (error, G_IO_ERROR,
3306                            G_IO_ERROR_NOT_SUPPORTED,
3307                            _("Operation not supported"));
3308       return FALSE;
3309     }
3310   
3311   flags |= G_FILE_COPY_ALL_METADATA;
3312   if (!g_file_copy (source, destination, flags, cancellable,
3313                     progress_callback, progress_callback_data,
3314                     error))
3315     return FALSE;
3316
3317   return g_file_delete (source, cancellable, error);
3318 }
3319
3320 /**
3321  * g_file_make_directory
3322  * @file: input #GFile.
3323  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3324  * @error: a #GError, or %NULL 
3325  *
3326  * Creates a directory. Note that this will only create a child directory of
3327  * the immediate parent directory of the path or URI given by the #GFile. To 
3328  * recursively create directories, see g_file_make_directory_with_parents().
3329  * This function will fail if the parent directory does not exist, setting 
3330  * @error to %G_IO_ERROR_NOT_FOUND. If the file system doesn't support creating
3331  * directories, this function will fail, setting @error to 
3332  * %G_IO_ERROR_NOT_SUPPORTED.
3333  *
3334  * For a local #GFile the newly created directory will have the default
3335  * (current) ownership and permissions of the current process.
3336  * 
3337  * If @cancellable is not %NULL, then the operation can be cancelled by
3338  * triggering the cancellable object from another thread. If the operation
3339  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3340  * 
3341  * Returns: %TRUE on successful creation, %FALSE otherwise.
3342  **/
3343 gboolean
3344 g_file_make_directory (GFile         *file,
3345                        GCancellable  *cancellable,
3346                        GError       **error)
3347 {
3348   GFileIface *iface;
3349
3350   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3351
3352   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3353     return FALSE;
3354   
3355   iface = G_FILE_GET_IFACE (file);
3356
3357   if (iface->make_directory == NULL)
3358     {
3359       g_set_error_literal (error, G_IO_ERROR,
3360                            G_IO_ERROR_NOT_SUPPORTED,
3361                            _("Operation not supported"));
3362       return FALSE;
3363     }
3364   
3365   return (* iface->make_directory) (file, cancellable, error);
3366 }
3367
3368 /**
3369  * g_file_make_directory_with_parents:
3370  * @file: input #GFile.
3371  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3372  * @error: a #GError, or %NULL 
3373  *
3374  * Creates a directory and any parent directories that may not exist similar to
3375  * 'mkdir -p'. If the file system does not support creating directories, this
3376  * function will fail, setting @error to %G_IO_ERROR_NOT_SUPPORTED.
3377  * 
3378  * For a local #GFile the newly created directories will have the default
3379  * (current) ownership and permissions of the current process.
3380  * 
3381  * If @cancellable is not %NULL, then the operation can be cancelled by
3382  * triggering the cancellable object from another thread. If the operation
3383  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3384  * 
3385  * Returns: %TRUE if all directories have been successfully created, %FALSE
3386  * otherwise.
3387  *
3388  * Since: 2.18
3389  **/
3390 gboolean
3391 g_file_make_directory_with_parents (GFile         *file,
3392                                     GCancellable  *cancellable,
3393                                     GError       **error)
3394 {
3395   gboolean result;
3396   GFile *parent_file, *work_file;
3397   GList *list = NULL, *l;
3398   GError *my_error = NULL;
3399
3400   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3401     return FALSE;
3402   
3403   result = g_file_make_directory (file, cancellable, &my_error);
3404   if (result || my_error->code != G_IO_ERROR_NOT_FOUND) 
3405     {
3406       if (my_error)
3407         g_propagate_error (error, my_error);
3408       return result;
3409     }
3410   
3411   work_file = file;
3412   
3413   while (!result && my_error->code == G_IO_ERROR_NOT_FOUND) 
3414     {
3415       g_clear_error (&my_error);
3416     
3417       parent_file = g_file_get_parent (work_file);
3418       if (parent_file == NULL)
3419         break;
3420       result = g_file_make_directory (parent_file, cancellable, &my_error);
3421     
3422       if (!result && my_error->code == G_IO_ERROR_NOT_FOUND)
3423         list = g_list_prepend (list, parent_file);
3424
3425       work_file = parent_file;
3426     }
3427
3428   for (l = list; result && l; l = l->next)
3429     {
3430       result = g_file_make_directory ((GFile *) l->data, cancellable, &my_error);
3431     }
3432   
3433   /* Clean up */
3434   while (list != NULL) 
3435     {
3436       g_object_unref ((GFile *) list->data);
3437       list = g_list_remove (list, list->data);
3438     }
3439
3440   if (!result) 
3441     {
3442       g_propagate_error (error, my_error);
3443       return result;
3444     }
3445   
3446   return g_file_make_directory (file, cancellable, error);
3447 }
3448
3449 /**
3450  * g_file_make_symbolic_link:
3451  * @file: a #GFile with the name of the symlink to create
3452  * @symlink_value: a string with the path for the target of the new symlink
3453  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3454  * @error: a #GError.
3455  *
3456  * Creates a symbolic link named @file which contains the string
3457  * @symlink_value.
3458  *
3459  * If @cancellable is not %NULL, then the operation can be cancelled by
3460  * triggering the cancellable object from another thread. If the operation
3461  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
3462  *
3463  * Returns: %TRUE on the creation of a new symlink, %FALSE otherwise.
3464  */
3465 gboolean
3466 g_file_make_symbolic_link (GFile         *file,
3467                            const char    *symlink_value,
3468                            GCancellable  *cancellable,
3469                            GError       **error)
3470 {
3471   GFileIface *iface;
3472
3473   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3474   g_return_val_if_fail (symlink_value != NULL, FALSE);
3475
3476   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3477     return FALSE;
3478
3479   if (*symlink_value == '\0')
3480     {
3481       g_set_error_literal (error, G_IO_ERROR,
3482                            G_IO_ERROR_INVALID_ARGUMENT,
3483                            _("Invalid symlink value given"));
3484       return FALSE;
3485     }
3486   
3487   iface = G_FILE_GET_IFACE (file);
3488
3489   if (iface->make_symbolic_link == NULL)
3490     {
3491       g_set_error_literal (error, G_IO_ERROR,
3492                            G_IO_ERROR_NOT_SUPPORTED,
3493                            _("Operation not supported"));
3494       return FALSE;
3495     }
3496   
3497   return (* iface->make_symbolic_link) (file, symlink_value, cancellable, error);
3498 }
3499
3500 /**
3501  * g_file_delete:
3502  * @file: input #GFile.
3503  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3504  * @error: a #GError, or %NULL 
3505  * 
3506  * Deletes a file. If the @file is a directory, it will only be deleted if it 
3507  * is empty.
3508  * 
3509  * If @cancellable is not %NULL, then the operation can be cancelled by
3510  * triggering the cancellable object from another thread. If the operation
3511  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3512  *
3513  * Virtual: delete_file
3514  * Returns: %TRUE if the file was deleted. %FALSE otherwise.
3515  **/
3516 gboolean
3517 g_file_delete (GFile         *file,
3518                GCancellable  *cancellable,
3519                GError       **error)
3520 {
3521   GFileIface *iface;
3522   
3523   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3524
3525   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3526     return FALSE;
3527   
3528   iface = G_FILE_GET_IFACE (file);
3529
3530   if (iface->delete_file == NULL)
3531     {
3532       g_set_error_literal (error, G_IO_ERROR,
3533                            G_IO_ERROR_NOT_SUPPORTED,
3534                            _("Operation not supported"));
3535       return FALSE;
3536     }
3537   
3538   return (* iface->delete_file) (file, cancellable, error);
3539 }
3540
3541 /**
3542  * g_file_trash:
3543  * @file: #GFile to send to trash.
3544  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3545  * @error: a #GError, or %NULL
3546  *
3547  * Sends @file to the "Trashcan", if possible. This is similar to
3548  * deleting it, but the user can recover it before emptying the trashcan.
3549  * Not all file systems support trashing, so this call can return the
3550  * %G_IO_ERROR_NOT_SUPPORTED error.
3551  *
3552  *
3553  * If @cancellable is not %NULL, then the operation can be cancelled by
3554  * triggering the cancellable object from another thread. If the operation
3555  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3556  * 
3557  * Returns: %TRUE on successful trash, %FALSE otherwise.
3558  **/
3559 gboolean
3560 g_file_trash (GFile         *file,
3561               GCancellable  *cancellable,
3562               GError       **error)
3563 {
3564   GFileIface *iface;
3565   
3566   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3567
3568   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3569     return FALSE;
3570   
3571   iface = G_FILE_GET_IFACE (file);
3572
3573   if (iface->trash == NULL)
3574     {
3575       g_set_error_literal (error,
3576                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
3577                            _("Trash not supported"));
3578       return FALSE;
3579     }
3580   
3581   return (* iface->trash) (file, cancellable, error);
3582 }
3583
3584 /**
3585  * g_file_set_display_name:
3586  * @file: input #GFile.
3587  * @display_name: a string.
3588  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3589  * @error: a #GError, or %NULL
3590  * 
3591  * Renames @file to the specified display name.
3592  *
3593  * The display name is converted from UTF8 to the correct encoding for the target
3594  * filesystem if possible and the @file is renamed to this.
3595  * 
3596  * If you want to implement a rename operation in the user interface the edit name
3597  * (#G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME) should be used as the initial value in the rename
3598  * widget, and then the result after editing should be passed to g_file_set_display_name().
3599  *
3600  * On success the resulting converted filename is returned.
3601  * 
3602  * If @cancellable is not %NULL, then the operation can be cancelled by
3603  * triggering the cancellable object from another thread. If the operation
3604  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3605  * 
3606  * Returns: (transfer full): a #GFile specifying what @file was renamed to, or %NULL 
3607  *     if there was an error.
3608  *     Free the returned object with g_object_unref().
3609  **/
3610 GFile *
3611 g_file_set_display_name (GFile         *file,
3612                          const char    *display_name,
3613                          GCancellable  *cancellable,
3614                          GError       **error)
3615 {
3616   GFileIface *iface;
3617   
3618   g_return_val_if_fail (G_IS_FILE (file), NULL);
3619   g_return_val_if_fail (display_name != NULL, NULL);
3620
3621   if (strchr (display_name, G_DIR_SEPARATOR) != NULL)
3622     {
3623       g_set_error (error,
3624                    G_IO_ERROR,
3625                    G_IO_ERROR_INVALID_ARGUMENT,
3626                    _("File names cannot contain '%c'"), G_DIR_SEPARATOR);
3627       return NULL;
3628     }
3629   
3630   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3631     return NULL;
3632   
3633   iface = G_FILE_GET_IFACE (file);
3634
3635   return (* iface->set_display_name) (file, display_name, cancellable, error);
3636 }
3637
3638 /**
3639  * g_file_set_display_name_async:
3640  * @file: input #GFile.
3641  * @display_name: a string.
3642  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
3643  *     of the request. 
3644  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3645  * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
3646  * @user_data: (closure): the data to pass to callback function
3647  * 
3648  * Asynchronously sets the display name for a given #GFile.
3649  * 
3650  * For more details, see g_file_set_display_name() which is
3651  * the synchronous version of this call.
3652  *
3653  * When the operation is finished, @callback will be called. You can then call
3654  * g_file_set_display_name_finish() to get the result of the operation.
3655  **/
3656 void
3657 g_file_set_display_name_async (GFile               *file,
3658                                const char          *display_name,
3659                                int                  io_priority,
3660                                GCancellable        *cancellable,
3661                                GAsyncReadyCallback  callback,
3662                                gpointer             user_data)
3663 {
3664   GFileIface *iface;
3665   
3666   g_return_if_fail (G_IS_FILE (file));
3667   g_return_if_fail (display_name != NULL);
3668
3669   iface = G_FILE_GET_IFACE (file);
3670   (* iface->set_display_name_async) (file,
3671                                      display_name,
3672                                      io_priority,
3673                                      cancellable,
3674                                      callback,
3675                                      user_data);
3676 }
3677
3678 /**
3679  * g_file_set_display_name_finish:
3680  * @file: input #GFile.
3681  * @res: a #GAsyncResult. 
3682  * @error: a #GError, or %NULL
3683  * 
3684  * Finishes setting a display name started with 
3685  * g_file_set_display_name_async().
3686  * 
3687  * Returns: (transfer full): a #GFile or %NULL on error.
3688  *     Free the returned object with g_object_unref().
3689  **/
3690 GFile *
3691 g_file_set_display_name_finish (GFile         *file,
3692                                 GAsyncResult  *res,
3693                                 GError       **error)
3694 {
3695   GFileIface *iface;
3696   
3697   g_return_val_if_fail (G_IS_FILE (file), NULL);
3698   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
3699
3700   if (G_IS_SIMPLE_ASYNC_RESULT (res))
3701     {
3702       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3703       if (g_simple_async_result_propagate_error (simple, error))
3704         return NULL;
3705     }
3706   
3707   iface = G_FILE_GET_IFACE (file);
3708   return (* iface->set_display_name_finish) (file, res, error);
3709 }
3710
3711 /**
3712  * g_file_query_settable_attributes:
3713  * @file: input #GFile.
3714  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3715  * @error: a #GError, or %NULL
3716  * 
3717  * Obtain the list of settable attributes for the file.
3718  *
3719  * Returns the type and full attribute name of all the attributes 
3720  * that can be set on this file. This doesn't mean setting it will always 
3721  * succeed though, you might get an access failure, or some specific 
3722  * file may not support a specific attribute.
3723  *
3724  * If @cancellable is not %NULL, then the operation can be cancelled by
3725  * triggering the cancellable object from another thread. If the operation
3726  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3727  * 
3728  * Returns: a #GFileAttributeInfoList describing the settable attributes.
3729  * When you are done with it, release it with g_file_attribute_info_list_unref()
3730  **/
3731 GFileAttributeInfoList *
3732 g_file_query_settable_attributes (GFile         *file,
3733                                   GCancellable  *cancellable,
3734                                   GError       **error)
3735 {
3736   GFileIface *iface;
3737   GError *my_error;
3738   GFileAttributeInfoList *list;
3739
3740   g_return_val_if_fail (G_IS_FILE (file), NULL);
3741
3742   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3743     return NULL;
3744   
3745   iface = G_FILE_GET_IFACE (file);
3746
3747   if (iface->query_settable_attributes == NULL)
3748     return g_file_attribute_info_list_new ();
3749
3750   my_error = NULL;
3751   list = (* iface->query_settable_attributes) (file, cancellable, &my_error);
3752   
3753   if (list == NULL)
3754     {
3755       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
3756         {
3757           list = g_file_attribute_info_list_new ();
3758           g_error_free (my_error);
3759         }
3760       else
3761         g_propagate_error (error, my_error);
3762     }
3763   
3764   return list;
3765 }
3766
3767 /**
3768  * g_file_query_writable_namespaces:
3769  * @file: input #GFile.
3770  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3771  * @error: a #GError, or %NULL
3772  * 
3773  * Obtain the list of attribute namespaces where new attributes 
3774  * can be created by a user. An example of this is extended
3775  * attributes (in the "xattr" namespace).
3776  *
3777  * If @cancellable is not %NULL, then the operation can be cancelled by
3778  * triggering the cancellable object from another thread. If the operation
3779  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3780  * 
3781  * Returns: a #GFileAttributeInfoList describing the writable namespaces.
3782  * When you are done with it, release it with g_file_attribute_info_list_unref()
3783  **/
3784 GFileAttributeInfoList *
3785 g_file_query_writable_namespaces (GFile         *file,
3786                                   GCancellable  *cancellable,
3787                                   GError       **error)
3788 {
3789   GFileIface *iface;
3790   GError *my_error;
3791   GFileAttributeInfoList *list;
3792   
3793   g_return_val_if_fail (G_IS_FILE (file), NULL);
3794
3795   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3796     return NULL;
3797   
3798   iface = G_FILE_GET_IFACE (file);
3799
3800   if (iface->query_writable_namespaces == NULL)
3801     return g_file_attribute_info_list_new ();
3802
3803   my_error = NULL;
3804   list = (* iface->query_writable_namespaces) (file, cancellable, &my_error);
3805   
3806   if (list == NULL)
3807     {
3808       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
3809         {
3810           list = g_file_attribute_info_list_new ();
3811           g_error_free (my_error);
3812         }
3813       else
3814         g_propagate_error (error, my_error);
3815     }
3816   
3817   return list;
3818 }
3819
3820 /**
3821  * g_file_set_attribute:
3822  * @file: input #GFile.
3823  * @attribute: a string containing the attribute's name.
3824  * @type: The type of the attribute
3825  * @value_p: a pointer to the value (or the pointer itself if the type is a pointer type)
3826  * @flags: a set of #GFileQueryInfoFlags.
3827  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3828  * @error: a #GError, or %NULL
3829  * 
3830  * Sets an attribute in the file with attribute name @attribute to @value.
3831  * 
3832  * If @cancellable is not %NULL, then the operation can be cancelled by
3833  * triggering the cancellable object from another thread. If the operation
3834  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3835  * 
3836  * Returns: %TRUE if the attribute was set, %FALSE otherwise.
3837  **/
3838 gboolean
3839 g_file_set_attribute (GFile                      *file,
3840                       const char                 *attribute,
3841                       GFileAttributeType          type,
3842                       gpointer                    value_p,
3843                       GFileQueryInfoFlags         flags,
3844                       GCancellable               *cancellable,
3845                       GError                    **error)
3846 {
3847   GFileIface *iface;
3848   
3849   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3850   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
3851
3852   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3853     return FALSE;
3854   
3855   iface = G_FILE_GET_IFACE (file);
3856
3857   if (iface->set_attribute == NULL)
3858     {
3859       g_set_error_literal (error, G_IO_ERROR,
3860                            G_IO_ERROR_NOT_SUPPORTED,
3861                            _("Operation not supported"));
3862       return FALSE;
3863     }
3864
3865   return (* iface->set_attribute) (file, attribute, type, value_p, flags, cancellable, error);
3866 }
3867
3868 /**
3869  * g_file_set_attributes_from_info:
3870  * @file: input #GFile.
3871  * @info: a #GFileInfo.
3872  * @flags: #GFileQueryInfoFlags
3873  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3874  * @error: a #GError, or %NULL 
3875  * 
3876  * Tries to set all attributes in the #GFileInfo on the target values, 
3877  * not stopping on the first error.
3878  * 
3879  * If there is any error during this operation then @error will be set to
3880  * the first error. Error on particular fields are flagged by setting 
3881  * the "status" field in the attribute value to 
3882  * %G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING, which means you can also detect
3883  * further errors.
3884  *
3885  * If @cancellable is not %NULL, then the operation can be cancelled by
3886  * triggering the cancellable object from another thread. If the operation
3887  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3888  * 
3889  * Returns: %TRUE if there was any error, %FALSE otherwise.
3890  **/
3891 gboolean
3892 g_file_set_attributes_from_info (GFile                *file,
3893                                  GFileInfo            *info,
3894                                  GFileQueryInfoFlags   flags,
3895                                  GCancellable         *cancellable,
3896                                  GError              **error)
3897 {
3898   GFileIface *iface;
3899
3900   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3901   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
3902
3903   if (g_cancellable_set_error_if_cancelled (cancellable, error))
3904     return FALSE;
3905   
3906   g_file_info_clear_status (info);
3907   
3908   iface = G_FILE_GET_IFACE (file);
3909
3910   return (* iface->set_attributes_from_info) (file, 
3911                                               info, 
3912                                               flags, 
3913                                               cancellable, 
3914                                               error);
3915 }
3916
3917
3918 static gboolean
3919 g_file_real_set_attributes_from_info (GFile                *file,
3920                                       GFileInfo            *info,
3921                                       GFileQueryInfoFlags   flags,
3922                                       GCancellable         *cancellable,
3923                                       GError              **error)
3924 {
3925   char **attributes;
3926   int i;
3927   gboolean res;
3928   GFileAttributeValue *value;
3929   
3930   res = TRUE;
3931   
3932   attributes = g_file_info_list_attributes (info, NULL);
3933
3934   for (i = 0; attributes[i] != NULL; i++)
3935     {
3936       value = _g_file_info_get_attribute_value (info, attributes[i]);
3937
3938       if (value->status != G_FILE_ATTRIBUTE_STATUS_UNSET)
3939         continue;
3940
3941       if (!g_file_set_attribute (file, attributes[i],
3942                                  value->type, _g_file_attribute_value_peek_as_pointer (value),
3943                                  flags, cancellable, error))
3944         {
3945           value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING;
3946           res = FALSE;
3947           /* Don't set error multiple times */
3948           error = NULL;
3949         }
3950       else
3951         value->status = G_FILE_ATTRIBUTE_STATUS_SET;
3952     }
3953   
3954   g_strfreev (attributes);
3955   
3956   return res;
3957 }
3958
3959 /**
3960  * g_file_set_attributes_async:
3961  * @file: input #GFile.
3962  * @info: a #GFileInfo.
3963  * @flags: a #GFileQueryInfoFlags.
3964  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
3965  *     of the request. 
3966  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
3967  * @callback: (scope async): a #GAsyncReadyCallback. 
3968  * @user_data: (closure): a #gpointer.
3969  *
3970  * Asynchronously sets the attributes of @file with @info.
3971  * 
3972  * For more details, see g_file_set_attributes_from_info() which is
3973  * the synchronous version of this call.
3974  *
3975  * When the operation is finished, @callback will be called. You can then call
3976  * g_file_set_attributes_finish() to get the result of the operation.
3977  **/
3978 void
3979 g_file_set_attributes_async (GFile               *file,
3980                              GFileInfo           *info,
3981                              GFileQueryInfoFlags  flags,
3982                              int                  io_priority,
3983                              GCancellable        *cancellable,
3984                              GAsyncReadyCallback  callback,
3985                              gpointer             user_data)
3986 {
3987   GFileIface *iface;
3988   
3989   g_return_if_fail (G_IS_FILE (file));
3990   g_return_if_fail (G_IS_FILE_INFO (info));
3991
3992   iface = G_FILE_GET_IFACE (file);
3993   (* iface->set_attributes_async) (file, 
3994                                    info, 
3995                                    flags, 
3996                                    io_priority, 
3997                                    cancellable, 
3998                                    callback, 
3999                                    user_data);
4000 }
4001
4002 /**
4003  * g_file_set_attributes_finish:
4004  * @file: input #GFile.
4005  * @result: a #GAsyncResult.
4006  * @info: (out) (transfer full): a #GFileInfo.
4007  * @error: a #GError, or %NULL
4008  * 
4009  * Finishes setting an attribute started in g_file_set_attributes_async().
4010  * 
4011  * Returns: %TRUE if the attributes were set correctly, %FALSE otherwise.
4012  **/
4013 gboolean
4014 g_file_set_attributes_finish (GFile         *file,
4015                               GAsyncResult  *result,
4016                               GFileInfo    **info,
4017                               GError       **error)
4018 {
4019   GFileIface *iface;
4020   
4021   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4022   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4023
4024   /* No standard handling of errors here, as we must set info even
4025    * on errors 
4026    */
4027   iface = G_FILE_GET_IFACE (file);
4028   return (* iface->set_attributes_finish) (file, result, info, error);
4029 }
4030
4031 /**
4032  * g_file_set_attribute_string:
4033  * @file: input #GFile.
4034  * @attribute: a string containing the attribute's name.
4035  * @value: a string containing the attribute's value.
4036  * @flags: #GFileQueryInfoFlags.
4037  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4038  * @error: a #GError, or %NULL
4039  * 
4040  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_STRING to @value. 
4041  * If @attribute is of a different type, this operation will fail.
4042  * 
4043  * If @cancellable is not %NULL, then the operation can be cancelled by
4044  * triggering the cancellable object from another thread. If the operation
4045  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4046  * 
4047  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
4048  **/
4049 gboolean
4050 g_file_set_attribute_string (GFile                *file,
4051                              const char           *attribute,
4052                              const char           *value,
4053                              GFileQueryInfoFlags   flags,
4054                              GCancellable         *cancellable,
4055                              GError              **error)
4056 {
4057   return g_file_set_attribute (file, attribute,
4058                                G_FILE_ATTRIBUTE_TYPE_STRING, (gpointer)value,
4059                                flags, cancellable, error);
4060 }
4061
4062 /**
4063  * g_file_set_attribute_byte_string:
4064  * @file: input #GFile.
4065  * @attribute: a string containing the attribute's name.
4066  * @value: a string containing the attribute's new value.
4067  * @flags: a #GFileQueryInfoFlags.
4068  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4069  * @error: a #GError, or %NULL
4070  * 
4071  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING to @value. 
4072  * If @attribute is of a different type, this operation will fail, 
4073  * returning %FALSE. 
4074  * 
4075  * If @cancellable is not %NULL, then the operation can be cancelled by
4076  * triggering the cancellable object from another thread. If the operation
4077  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4078  * 
4079  * Returns: %TRUE if the @attribute was successfully set to @value 
4080  * in the @file, %FALSE otherwise.
4081  **/
4082 gboolean
4083 g_file_set_attribute_byte_string  (GFile                *file,
4084                                    const char           *attribute,
4085                                    const char           *value,
4086                                    GFileQueryInfoFlags   flags,
4087                                    GCancellable         *cancellable,
4088                                    GError              **error)
4089 {
4090   return g_file_set_attribute (file, attribute,
4091                                G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, (gpointer)value,
4092                                flags, cancellable, error);
4093 }
4094
4095 /**
4096  * g_file_set_attribute_uint32:
4097  * @file: input #GFile.
4098  * @attribute: a string containing the attribute's name.
4099  * @value: a #guint32 containing the attribute's new value.
4100  * @flags: a #GFileQueryInfoFlags.
4101  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4102  * @error: a #GError, or %NULL
4103  * 
4104  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT32 to @value. 
4105  * If @attribute is of a different type, this operation will fail.
4106  * 
4107  * If @cancellable is not %NULL, then the operation can be cancelled by
4108  * triggering the cancellable object from another thread. If the operation
4109  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4110  * 
4111  * Returns: %TRUE if the @attribute was successfully set to @value 
4112  * in the @file, %FALSE otherwise.
4113  **/
4114 gboolean
4115 g_file_set_attribute_uint32 (GFile                *file,
4116                              const char           *attribute,
4117                              guint32               value,
4118                              GFileQueryInfoFlags   flags,
4119                              GCancellable         *cancellable,
4120                              GError              **error)
4121 {
4122   return g_file_set_attribute (file, attribute,
4123                                G_FILE_ATTRIBUTE_TYPE_UINT32, &value,
4124                                flags, cancellable, error);
4125 }
4126
4127 /**
4128  * g_file_set_attribute_int32:
4129  * @file: input #GFile.
4130  * @attribute: a string containing the attribute's name.
4131  * @value: a #gint32 containing the attribute's new value.
4132  * @flags: a #GFileQueryInfoFlags.
4133  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4134  * @error: a #GError, or %NULL
4135  * 
4136  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT32 to @value. 
4137  * If @attribute is of a different type, this operation will fail.
4138  * 
4139  * If @cancellable is not %NULL, then the operation can be cancelled by
4140  * triggering the cancellable object from another thread. If the operation
4141  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4142  * 
4143  * Returns: %TRUE if the @attribute was successfully set to @value 
4144  * in the @file, %FALSE otherwise. 
4145  **/
4146 gboolean
4147 g_file_set_attribute_int32 (GFile                *file,
4148                             const char           *attribute,
4149                             gint32                value,
4150                             GFileQueryInfoFlags   flags,
4151                             GCancellable         *cancellable,
4152                             GError              **error)
4153 {
4154   return g_file_set_attribute (file, attribute,
4155                                G_FILE_ATTRIBUTE_TYPE_INT32, &value,
4156                                flags, cancellable, error);
4157 }
4158
4159 /**
4160  * g_file_set_attribute_uint64:
4161  * @file: input #GFile. 
4162  * @attribute: a string containing the attribute's name.
4163  * @value: a #guint64 containing the attribute's new value.
4164  * @flags: a #GFileQueryInfoFlags.
4165  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4166  * @error: a #GError, or %NULL
4167  * 
4168  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT64 to @value. 
4169  * If @attribute is of a different type, this operation will fail.
4170  * 
4171  * If @cancellable is not %NULL, then the operation can be cancelled by
4172  * triggering the cancellable object from another thread. If the operation
4173  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4174  * 
4175  * Returns: %TRUE if the @attribute was successfully set to @value 
4176  * in the @file, %FALSE otherwise.
4177  **/
4178 gboolean
4179 g_file_set_attribute_uint64 (GFile                *file,
4180                              const char           *attribute,
4181                              guint64               value,
4182                              GFileQueryInfoFlags   flags,
4183                              GCancellable         *cancellable,
4184                              GError              **error)
4185  {
4186   return g_file_set_attribute (file, attribute,
4187                                G_FILE_ATTRIBUTE_TYPE_UINT64, &value,
4188                                flags, cancellable, error);
4189 }
4190
4191 /**
4192  * g_file_set_attribute_int64:
4193  * @file: input #GFile.
4194  * @attribute: a string containing the attribute's name.
4195  * @value: a #guint64 containing the attribute's new value.
4196  * @flags: a #GFileQueryInfoFlags.
4197  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4198  * @error: a #GError, or %NULL
4199  * 
4200  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT64 to @value. 
4201  * If @attribute is of a different type, this operation will fail.
4202  * 
4203  * If @cancellable is not %NULL, then the operation can be cancelled by
4204  * triggering the cancellable object from another thread. If the operation
4205  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4206  * 
4207  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
4208  **/
4209 gboolean
4210 g_file_set_attribute_int64 (GFile                *file,
4211                             const char           *attribute,
4212                             gint64                value,
4213                             GFileQueryInfoFlags   flags,
4214                             GCancellable         *cancellable,
4215                             GError              **error)
4216 {
4217   return g_file_set_attribute (file, attribute,
4218                                G_FILE_ATTRIBUTE_TYPE_INT64, &value,
4219                                flags, cancellable, error);
4220 }
4221
4222 /**
4223  * g_file_mount_mountable:
4224  * @file: input #GFile.
4225  * @flags: flags affecting the operation
4226  * @mount_operation: a #GMountOperation, or %NULL to avoid user interaction.
4227  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4228  * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
4229  * @user_data: (closure): the data to pass to callback function
4230  * 
4231  * Mounts a file of type G_FILE_TYPE_MOUNTABLE.
4232  * Using @mount_operation, you can request callbacks when, for instance, 
4233  * passwords are needed during authentication.
4234  *
4235  * If @cancellable is not %NULL, then the operation can be cancelled by
4236  * triggering the cancellable object from another thread. If the operation
4237  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4238  *
4239  * When the operation is finished, @callback will be called. You can then call
4240  * g_file_mount_mountable_finish() to get the result of the operation.
4241  **/
4242 void
4243 g_file_mount_mountable (GFile               *file,
4244                         GMountMountFlags     flags,
4245                         GMountOperation     *mount_operation,
4246                         GCancellable        *cancellable,
4247                         GAsyncReadyCallback  callback,
4248                         gpointer             user_data)
4249 {
4250   GFileIface *iface;
4251
4252   g_return_if_fail (G_IS_FILE (file));
4253
4254   iface = G_FILE_GET_IFACE (file);
4255
4256   if (iface->mount_mountable == NULL) 
4257     {
4258       g_simple_async_report_error_in_idle (G_OBJECT (file),
4259                                            callback,
4260                                            user_data,
4261                                            G_IO_ERROR,
4262                                            G_IO_ERROR_NOT_SUPPORTED,
4263                                            _("Operation not supported"));
4264       return;
4265     }
4266   
4267   (* iface->mount_mountable) (file,
4268                               flags,
4269                               mount_operation,
4270                               cancellable,
4271                               callback,
4272                               user_data);
4273 }
4274
4275 /**
4276  * g_file_mount_mountable_finish:
4277  * @file: input #GFile.
4278  * @result: a #GAsyncResult.
4279  * @error: a #GError, or %NULL
4280  *
4281  * Finishes a mount operation. See g_file_mount_mountable() for details.
4282  * 
4283  * Finish an asynchronous mount operation that was started 
4284  * with g_file_mount_mountable().
4285  *
4286  * Returns: (transfer full): a #GFile or %NULL on error.
4287  *     Free the returned object with g_object_unref().
4288  **/
4289 GFile *
4290 g_file_mount_mountable_finish (GFile         *file,
4291                                GAsyncResult  *result,
4292                                GError       **error)
4293 {
4294   GFileIface *iface;
4295
4296   g_return_val_if_fail (G_IS_FILE (file), NULL);
4297   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
4298
4299   if (G_IS_SIMPLE_ASYNC_RESULT (result))
4300     {
4301       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
4302       if (g_simple_async_result_propagate_error (simple, error))
4303         return NULL;
4304     }
4305   
4306   iface = G_FILE_GET_IFACE (file);
4307   return (* iface->mount_mountable_finish) (file, result, error);
4308 }
4309
4310 /**
4311  * g_file_unmount_mountable:
4312  * @file: input #GFile.
4313  * @flags: flags affecting the operation
4314  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4315  * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
4316  * @user_data: (closure): the data to pass to callback function
4317  *
4318  * Unmounts a file of type G_FILE_TYPE_MOUNTABLE.
4319  *
4320  * If @cancellable is not %NULL, then the operation can be cancelled by
4321  * triggering the cancellable object from another thread. If the operation
4322  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4323  *
4324  * When the operation is finished, @callback will be called. You can then call
4325  * g_file_unmount_mountable_finish() to get the result of the operation.
4326  *
4327  * Deprecated: 2.22: Use g_file_unmount_mountable_with_operation() instead.
4328  **/
4329 void
4330 g_file_unmount_mountable (GFile               *file,
4331                           GMountUnmountFlags   flags,
4332                           GCancellable        *cancellable,
4333                           GAsyncReadyCallback  callback,
4334                           gpointer             user_data)
4335 {
4336   GFileIface *iface;
4337   
4338   g_return_if_fail (G_IS_FILE (file));
4339
4340   iface = G_FILE_GET_IFACE (file);
4341   
4342   if (iface->unmount_mountable == NULL)
4343     {
4344       g_simple_async_report_error_in_idle (G_OBJECT (file),
4345                                            callback,
4346                                            user_data,
4347                                            G_IO_ERROR,
4348                                            G_IO_ERROR_NOT_SUPPORTED,
4349                                            _("Operation not supported"));
4350       return;
4351     }
4352   
4353   (* iface->unmount_mountable) (file,
4354                                 flags,
4355                                 cancellable,
4356                                 callback,
4357                                 user_data);
4358 }
4359
4360 /**
4361  * g_file_unmount_mountable_finish:
4362  * @file: input #GFile.
4363  * @result: a #GAsyncResult.
4364  * @error: a #GError, or %NULL
4365  *
4366  * Finishes an unmount operation, see g_file_unmount_mountable() for details.
4367  * 
4368  * Finish an asynchronous unmount operation that was started 
4369  * with g_file_unmount_mountable().
4370  *
4371  * Returns: %TRUE if the operation finished successfully. %FALSE
4372  * otherwise.
4373  *
4374  * Deprecated: 2.22: Use g_file_unmount_mountable_with_operation_finish() instead.
4375  **/
4376 gboolean
4377 g_file_unmount_mountable_finish (GFile         *file,
4378                                  GAsyncResult  *result,
4379                                  GError       **error)
4380 {
4381   GFileIface *iface;
4382   
4383   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4384   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4385
4386   if (G_IS_SIMPLE_ASYNC_RESULT (result))
4387     {
4388       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
4389       if (g_simple_async_result_propagate_error (simple, error))
4390         return FALSE;
4391     }
4392   
4393   iface = G_FILE_GET_IFACE (file);
4394   return (* iface->unmount_mountable_finish) (file, result, error);
4395 }
4396
4397 /**
4398  * g_file_unmount_mountable_with_operation:
4399  * @file: input #GFile.
4400  * @flags: flags affecting the operation
4401  * @mount_operation: a #GMountOperation, or %NULL to avoid user interaction.
4402  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4403  * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
4404  * @user_data: (closure): the data to pass to callback function
4405  *
4406  * Unmounts a file of type G_FILE_TYPE_MOUNTABLE.
4407  *
4408  * If @cancellable is not %NULL, then the operation can be cancelled by
4409  * triggering the cancellable object from another thread. If the operation
4410  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4411  *
4412  * When the operation is finished, @callback will be called. You can then call
4413  * g_file_unmount_mountable_finish() to get the result of the operation.
4414  *
4415  * Since: 2.22
4416  **/
4417 void
4418 g_file_unmount_mountable_with_operation (GFile               *file,
4419                                          GMountUnmountFlags   flags,
4420                                          GMountOperation     *mount_operation,
4421                                          GCancellable        *cancellable,
4422                                          GAsyncReadyCallback  callback,
4423                                          gpointer             user_data)
4424 {
4425   GFileIface *iface;
4426
4427   g_return_if_fail (G_IS_FILE (file));
4428
4429   iface = G_FILE_GET_IFACE (file);
4430
4431   if (iface->unmount_mountable == NULL && iface->unmount_mountable_with_operation == NULL)
4432     {
4433       g_simple_async_report_error_in_idle (G_OBJECT (file),
4434                                            callback,
4435                                            user_data,
4436                                            G_IO_ERROR,
4437                                            G_IO_ERROR_NOT_SUPPORTED,
4438                                            _("Operation not supported"));
4439       return;
4440     }
4441
4442   if (iface->unmount_mountable_with_operation != NULL)
4443     (* iface->unmount_mountable_with_operation) (file,
4444                                                  flags,
4445                                                  mount_operation,
4446                                                  cancellable,
4447                                                  callback,
4448                                                  user_data);
4449   else
4450     (* iface->unmount_mountable) (file,
4451                                   flags,
4452                                   cancellable,
4453                                   callback,
4454                                   user_data);
4455 }
4456
4457 /**
4458  * g_file_unmount_mountable_with_operation_finish:
4459  * @file: input #GFile.
4460  * @result: a #GAsyncResult.
4461  * @error: a #GError, or %NULL
4462  *
4463  * Finishes an unmount operation, see g_file_unmount_mountable_with_operation() for details.
4464  *
4465  * Finish an asynchronous unmount operation that was started
4466  * with g_file_unmount_mountable_with_operation().
4467  *
4468  * Returns: %TRUE if the operation finished successfully. %FALSE
4469  * otherwise.
4470  *
4471  * Since: 2.22
4472  **/
4473 gboolean
4474 g_file_unmount_mountable_with_operation_finish (GFile         *file,
4475                                                 GAsyncResult  *result,
4476                                                 GError       **error)
4477 {
4478   GFileIface *iface;
4479
4480   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4481   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4482
4483   if (G_IS_SIMPLE_ASYNC_RESULT (result))
4484     {
4485       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
4486       if (g_simple_async_result_propagate_error (simple, error))
4487         return FALSE;
4488     }
4489
4490   iface = G_FILE_GET_IFACE (file);
4491   if (iface->unmount_mountable_with_operation_finish != NULL)
4492     return (* iface->unmount_mountable_with_operation_finish) (file, result, error);
4493   else
4494     return (* iface->unmount_mountable_finish) (file, result, error);
4495 }
4496
4497 /**
4498  * g_file_eject_mountable:
4499  * @file: input #GFile.
4500  * @flags: flags affecting the operation
4501  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4502  * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
4503  * @user_data: (closure): the data to pass to callback function
4504  * 
4505  * Starts an asynchronous eject on a mountable.  
4506  * When this operation has completed, @callback will be called with
4507  * @user_user data, and the operation can be finalized with 
4508  * g_file_eject_mountable_finish().
4509  * 
4510  * If @cancellable is not %NULL, then the operation can be cancelled by
4511  * triggering the cancellable object from another thread. If the operation
4512  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4513  *
4514  * Deprecated: 2.22: Use g_file_eject_mountable_with_operation() instead.
4515  **/
4516 void
4517 g_file_eject_mountable (GFile               *file,
4518                         GMountUnmountFlags   flags,
4519                         GCancellable        *cancellable,
4520                         GAsyncReadyCallback  callback,
4521                         gpointer             user_data)
4522 {
4523   GFileIface *iface;
4524
4525   g_return_if_fail (G_IS_FILE (file));
4526
4527   iface = G_FILE_GET_IFACE (file);
4528   
4529   if (iface->eject_mountable == NULL) 
4530     {
4531       g_simple_async_report_error_in_idle (G_OBJECT (file),
4532                                            callback,
4533                                            user_data,
4534                                            G_IO_ERROR,
4535                                            G_IO_ERROR_NOT_SUPPORTED,
4536                                            _("Operation not supported"));
4537       return;
4538     }
4539   
4540   (* iface->eject_mountable) (file,
4541                               flags,
4542                               cancellable,
4543                               callback,
4544                               user_data);
4545 }
4546
4547 /**
4548  * g_file_eject_mountable_finish:
4549  * @file: input #GFile.
4550  * @result: a #GAsyncResult.
4551  * @error: a #GError, or %NULL
4552  * 
4553  * Finishes an asynchronous eject operation started by 
4554  * g_file_eject_mountable().
4555  * 
4556  * Returns: %TRUE if the @file was ejected successfully. %FALSE 
4557  * otherwise.
4558  *
4559  * Deprecated: 2.22: Use g_file_eject_mountable_with_operation_finish() instead.
4560  **/
4561 gboolean
4562 g_file_eject_mountable_finish (GFile         *file,
4563                                GAsyncResult  *result,
4564                                GError       **error)
4565 {
4566   GFileIface *iface;
4567   
4568   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4569   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4570
4571   if (G_IS_SIMPLE_ASYNC_RESULT (result))
4572     {
4573       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
4574       if (g_simple_async_result_propagate_error (simple, error))
4575         return FALSE;
4576     }
4577   
4578   iface = G_FILE_GET_IFACE (file);
4579   return (* iface->eject_mountable_finish) (file, result, error);
4580 }
4581
4582 /**
4583  * g_file_eject_mountable_with_operation:
4584  * @file: input #GFile.
4585  * @flags: flags affecting the operation
4586  * @mount_operation: a #GMountOperation, or %NULL to avoid user interaction.
4587  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4588  * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
4589  * @user_data: (closure): the data to pass to callback function
4590  *
4591  * Starts an asynchronous eject on a mountable.
4592  * When this operation has completed, @callback will be called with
4593  * @user_user data, and the operation can be finalized with
4594  * g_file_eject_mountable_with_operation_finish().
4595  *
4596  * If @cancellable is not %NULL, then the operation can be cancelled by
4597  * triggering the cancellable object from another thread. If the operation
4598  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
4599  *
4600  * Since: 2.22
4601  **/
4602 void
4603 g_file_eject_mountable_with_operation (GFile               *file,
4604                                        GMountUnmountFlags   flags,
4605                                        GMountOperation     *mount_operation,
4606                                        GCancellable        *cancellable,
4607                                        GAsyncReadyCallback  callback,
4608                                        gpointer             user_data)
4609 {
4610   GFileIface *iface;
4611
4612   g_return_if_fail (G_IS_FILE (file));
4613
4614   iface = G_FILE_GET_IFACE (file);
4615
4616   if (iface->eject_mountable == NULL && iface->eject_mountable_with_operation == NULL)
4617     {
4618       g_simple_async_report_error_in_idle (G_OBJECT (file),
4619                                            callback,
4620                                            user_data,
4621                                            G_IO_ERROR,
4622                                            G_IO_ERROR_NOT_SUPPORTED,
4623                                            _("Operation not supported"));
4624       return;
4625     }
4626
4627   if (iface->eject_mountable_with_operation != NULL)
4628     (* iface->eject_mountable_with_operation) (file,
4629                                                flags,
4630                                                mount_operation,
4631                                                cancellable,
4632                                                callback,
4633                                                user_data);
4634   else
4635     (* iface->eject_mountable) (file,
4636                                 flags,
4637                                 cancellable,
4638                                 callback,
4639                                 user_data);
4640 }
4641
4642 /**
4643  * g_file_eject_mountable_with_operation_finish:
4644  * @file: input #GFile.
4645  * @result: a #GAsyncResult.
4646  * @error: a #GError, or %NULL
4647  *
4648  * Finishes an asynchronous eject operation started by
4649  * g_file_eject_mountable_with_operation().
4650  *
4651  * Returns: %TRUE if the @file was ejected successfully. %FALSE
4652  * otherwise.
4653  *
4654  * Since: 2.22
4655  **/
4656 gboolean
4657 g_file_eject_mountable_with_operation_finish (GFile         *file,
4658                                               GAsyncResult  *result,
4659                                               GError       **error)
4660 {
4661   GFileIface *iface;
4662
4663   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4664   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
4665
4666   if (G_IS_SIMPLE_ASYNC_RESULT (result))
4667     {
4668       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
4669       if (g_simple_async_result_propagate_error (simple, error))
4670         return FALSE;
4671     }
4672
4673   iface = G_FILE_GET_IFACE (file);
4674   if (iface->eject_mountable_with_operation_finish != NULL)
4675     return (* iface->eject_mountable_with_operation_finish) (file, result, error);
4676   else
4677     return (* iface->eject_mountable_finish) (file, result, error);
4678 }
4679
4680 /**
4681  * g_file_monitor_directory:
4682  * @file: input #GFile.
4683  * @flags: a set of #GFileMonitorFlags.
4684  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4685  * @error: a #GError, or %NULL.
4686  * 
4687  * Obtains a directory monitor for the given file.
4688  * This may fail if directory monitoring is not supported.
4689  *
4690  * If @cancellable is not %NULL, then the operation can be cancelled by
4691  * triggering the cancellable object from another thread. If the operation
4692  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4693  *
4694  * Virtual: monitor_dir
4695  * Returns: (transfer full): a #GFileMonitor for the given @file, or %NULL on error.
4696  *     Free the returned object with g_object_unref().
4697  **/
4698 GFileMonitor*
4699 g_file_monitor_directory (GFile             *file,
4700                           GFileMonitorFlags  flags,
4701                           GCancellable      *cancellable,
4702                           GError           **error)
4703 {
4704   GFileIface *iface;
4705
4706   g_return_val_if_fail (G_IS_FILE (file), NULL);
4707
4708   if (g_cancellable_set_error_if_cancelled (cancellable, error))
4709     return NULL;
4710
4711   iface = G_FILE_GET_IFACE (file);
4712
4713   if (iface->monitor_dir == NULL)
4714     {
4715       g_set_error_literal (error, G_IO_ERROR,
4716                            G_IO_ERROR_NOT_SUPPORTED,
4717                            _("Operation not supported"));
4718       return NULL;
4719     }
4720
4721   return (* iface->monitor_dir) (file, flags, cancellable, error);
4722 }
4723
4724 /**
4725  * g_file_monitor_file:
4726  * @file: input #GFile.
4727  * @flags: a set of #GFileMonitorFlags.
4728  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
4729  * @error: a #GError, or %NULL.
4730  * 
4731  * Obtains a file monitor for the given file. If no file notification
4732  * mechanism exists, then regular polling of the file is used.
4733  *
4734  * If @cancellable is not %NULL, then the operation can be cancelled by
4735  * triggering the cancellable object from another thread. If the operation
4736  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4737  * 
4738  * Returns: (transfer full): a #GFileMonitor for the given @file, or %NULL on error.
4739  *     Free the returned object with g_object_unref().
4740  **/
4741 GFileMonitor*
4742 g_file_monitor_file (GFile             *file,
4743                      GFileMonitorFlags  flags,
4744                      GCancellable      *cancellable,
4745                      GError           **error)
4746 {
4747   GFileIface *iface;
4748   GFileMonitor *monitor;
4749   
4750   g_return_val_if_fail (G_IS_FILE (file), NULL);
4751
4752   if (g_cancellable_set_error_if_cancelled (cancellable, error))
4753     return NULL;
4754
4755   iface = G_FILE_GET_IFACE (file);
4756
4757   monitor = NULL;
4758   
4759   if (iface->monitor_file)
4760     monitor = (* iface->monitor_file) (file, flags, cancellable, NULL);
4761
4762 /* Fallback to polling */
4763   if (monitor == NULL)
4764     monitor = _g_poll_file_monitor_new (file);
4765
4766   return monitor;
4767 }
4768
4769 /**
4770  * g_file_monitor:
4771  * @file: input #GFile
4772  * @flags: a set of #GFileMonitorFlags
4773  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
4774  * @error: a #GError, or %NULL
4775  * 
4776  * Obtains a file or directory monitor for the given file, depending
4777  * on the type of the file.
4778  *
4779  * If @cancellable is not %NULL, then the operation can be cancelled by
4780  * triggering the cancellable object from another thread. If the operation
4781  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4782  * 
4783  * Returns: (transfer full): a #GFileMonitor for the given @file, or %NULL on error.
4784  *     Free the returned object with g_object_unref().
4785  *
4786  * Since: 2.18
4787  */
4788 GFileMonitor*
4789 g_file_monitor (GFile             *file,
4790                 GFileMonitorFlags  flags,
4791                 GCancellable      *cancellable,
4792                 GError           **error)
4793 {
4794   if (g_file_query_file_type (file, 0, cancellable) == G_FILE_TYPE_DIRECTORY)
4795     return g_file_monitor_directory (file, flags, cancellable, error);
4796   else
4797     return g_file_monitor_file (file, flags, cancellable, error);
4798 }
4799
4800 /********************************************
4801  *   Default implementation of async ops    *
4802  ********************************************/
4803
4804 typedef struct {
4805   char *attributes;
4806   GFileQueryInfoFlags flags;
4807   GFileInfo *info;
4808 } QueryInfoAsyncData;
4809
4810 static void
4811 query_info_data_free (QueryInfoAsyncData *data)
4812 {
4813   if (data->info)
4814     g_object_unref (data->info);
4815   g_free (data->attributes);
4816   g_free (data);
4817 }
4818
4819 static void
4820 query_info_async_thread (GSimpleAsyncResult *res,
4821                          GObject            *object,
4822                          GCancellable       *cancellable)
4823 {
4824   GError *error = NULL;
4825   QueryInfoAsyncData *data;
4826   GFileInfo *info;
4827   
4828   data = g_simple_async_result_get_op_res_gpointer (res);
4829   
4830   info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error);
4831
4832   if (info == NULL)
4833     g_simple_async_result_take_error (res, error);
4834   else
4835     data->info = info;
4836 }
4837
4838 static void
4839 g_file_real_query_info_async (GFile               *file,
4840                               const char          *attributes,
4841                               GFileQueryInfoFlags  flags,
4842                               int                  io_priority,
4843                               GCancellable        *cancellable,
4844                               GAsyncReadyCallback  callback,
4845                               gpointer             user_data)
4846 {
4847   GSimpleAsyncResult *res;
4848   QueryInfoAsyncData *data;
4849
4850   data = g_new0 (QueryInfoAsyncData, 1);
4851   data->attributes = g_strdup (attributes);
4852   data->flags = flags;
4853   
4854   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_info_async);
4855   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_info_data_free);
4856   
4857   g_simple_async_result_run_in_thread (res, query_info_async_thread, io_priority, cancellable);
4858   g_object_unref (res);
4859 }
4860
4861 static GFileInfo *
4862 g_file_real_query_info_finish (GFile         *file,
4863                                GAsyncResult  *res,
4864                                GError       **error)
4865 {
4866   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4867   QueryInfoAsyncData *data;
4868
4869   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_info_async);
4870
4871   data = g_simple_async_result_get_op_res_gpointer (simple);
4872   if (data->info)
4873     return g_object_ref (data->info);
4874   
4875   return NULL;
4876 }
4877
4878 typedef struct {
4879   char *attributes;
4880   GFileInfo *info;
4881 } QueryFilesystemInfoAsyncData;
4882
4883 static void
4884 query_filesystem_info_data_free (QueryFilesystemInfoAsyncData *data)
4885 {
4886   if (data->info)
4887     g_object_unref (data->info);
4888   g_free (data->attributes);
4889   g_free (data);
4890 }
4891
4892 static void
4893 query_filesystem_info_async_thread (GSimpleAsyncResult *res,
4894                                     GObject            *object,
4895                                     GCancellable       *cancellable)
4896 {
4897   GError *error = NULL;
4898   QueryFilesystemInfoAsyncData *data;
4899   GFileInfo *info;
4900   
4901   data = g_simple_async_result_get_op_res_gpointer (res);
4902   
4903   info = g_file_query_filesystem_info (G_FILE (object), data->attributes, cancellable, &error);
4904
4905   if (info == NULL)
4906     g_simple_async_result_take_error (res, error);
4907   else
4908     data->info = info;
4909 }
4910
4911 static void
4912 g_file_real_query_filesystem_info_async (GFile               *file,
4913                                          const char          *attributes,
4914                                          int                  io_priority,
4915                                          GCancellable        *cancellable,
4916                                          GAsyncReadyCallback  callback,
4917                                          gpointer             user_data)
4918 {
4919   GSimpleAsyncResult *res;
4920   QueryFilesystemInfoAsyncData *data;
4921
4922   data = g_new0 (QueryFilesystemInfoAsyncData, 1);
4923   data->attributes = g_strdup (attributes);
4924   
4925   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_filesystem_info_async);
4926   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_filesystem_info_data_free);
4927   
4928   g_simple_async_result_run_in_thread (res, query_filesystem_info_async_thread, io_priority, cancellable);
4929   g_object_unref (res);
4930 }
4931
4932 static GFileInfo *
4933 g_file_real_query_filesystem_info_finish (GFile         *file,
4934                                           GAsyncResult  *res,
4935                                           GError       **error)
4936 {
4937   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
4938   QueryFilesystemInfoAsyncData *data;
4939
4940   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_filesystem_info_async);
4941
4942   data = g_simple_async_result_get_op_res_gpointer (simple);
4943   if (data->info)
4944     return g_object_ref (data->info);
4945   
4946   return NULL;
4947 }
4948
4949 typedef struct {
4950   char *attributes;
4951   GFileQueryInfoFlags flags;
4952   GFileEnumerator *enumerator;
4953 } EnumerateChildrenAsyncData;
4954
4955 static void
4956 enumerate_children_data_free (EnumerateChildrenAsyncData *data)
4957 {
4958   if (data->enumerator)
4959     g_object_unref (data->enumerator);
4960   g_free (data->attributes);
4961   g_free (data);
4962 }
4963
4964 static void
4965 enumerate_children_async_thread (GSimpleAsyncResult *res,
4966                                  GObject            *object,
4967                                  GCancellable       *cancellable)
4968 {
4969   GError *error = NULL;
4970   EnumerateChildrenAsyncData *data;
4971   GFileEnumerator *enumerator;
4972   
4973   data = g_simple_async_result_get_op_res_gpointer (res);
4974   
4975   enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error);
4976
4977   if (enumerator == NULL)
4978     g_simple_async_result_take_error (res, error);
4979   else
4980     data->enumerator = enumerator;
4981 }
4982
4983 static void
4984 g_file_real_enumerate_children_async (GFile               *file,
4985                                       const char          *attributes,
4986                                       GFileQueryInfoFlags  flags,
4987                                       int                  io_priority,
4988                                       GCancellable        *cancellable,
4989                                       GAsyncReadyCallback  callback,
4990                                       gpointer             user_data)
4991 {
4992   GSimpleAsyncResult *res;
4993   EnumerateChildrenAsyncData *data;
4994
4995   data = g_new0 (EnumerateChildrenAsyncData, 1);
4996   data->attributes = g_strdup (attributes);
4997   data->flags = flags;
4998   
4999   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_enumerate_children_async);
5000   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)enumerate_children_data_free);
5001   
5002   g_simple_async_result_run_in_thread (res, enumerate_children_async_thread, io_priority, cancellable);
5003   g_object_unref (res);
5004 }
5005
5006 static GFileEnumerator *
5007 g_file_real_enumerate_children_finish (GFile         *file,
5008                                        GAsyncResult  *res,
5009                                        GError       **error)
5010 {
5011   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
5012   EnumerateChildrenAsyncData *data;
5013
5014   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_enumerate_children_async);
5015
5016   data = g_simple_async_result_get_op_res_gpointer (simple);
5017   if (data->enumerator)
5018     return g_object_ref (data->enumerator);
5019   
5020   return NULL;
5021 }
5022
5023 static void
5024 open_read_async_thread (GSimpleAsyncResult *res,
5025                         GObject            *object,
5026                         GCancellable       *cancellable)
5027 {
5028   GFileIface *iface;
5029   GFileInputStream *stream;
5030   GError *error = NULL;
5031
5032   iface = G_FILE_GET_IFACE (object);
5033
5034   if (iface->read_fn == NULL)
5035     {
5036       g_set_error_literal (&error, G_IO_ERROR,
5037                            G_IO_ERROR_NOT_SUPPORTED,
5038                            _("Operation not supported"));
5039
5040       g_simple_async_result_take_error (res, error);
5041
5042       return;
5043     }
5044   
5045   stream = iface->read_fn (G_FILE (object), cancellable, &error);
5046
5047   if (stream == NULL)
5048     g_simple_async_result_take_error (res, error);
5049   else
5050     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
5051 }
5052
5053 static void
5054 g_file_real_read_async (GFile               *file,
5055                         int                  io_priority,
5056                         GCancellable        *cancellable,
5057                         GAsyncReadyCallback  callback,
5058                         gpointer             user_data)
5059 {
5060   GSimpleAsyncResult *res;
5061   
5062   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_read_async);
5063   
5064   g_simple_async_result_run_in_thread (res, open_read_async_thread, io_priority, cancellable);
5065   g_object_unref (res);
5066 }
5067
5068 static GFileInputStream *
5069 g_file_real_read_finish (GFile         *file,
5070                          GAsyncResult  *res,
5071                          GError       **error)
5072 {
5073   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
5074   gpointer op;
5075
5076   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_read_async);
5077
5078   op = g_simple_async_result_get_op_res_gpointer (simple);
5079   if (op)
5080     return g_object_ref (op);
5081   
5082   return NULL;
5083 }
5084
5085 static void
5086 append_to_async_thread (GSimpleAsyncResult *res,
5087                         GObject            *object,
5088                         GCancellable       *cancellable)
5089 {
5090   GFileIface *iface;
5091   GFileCreateFlags *data;
5092   GFileOutputStream *stream;
5093   GError *error = NULL;
5094
5095   iface = G_FILE_GET_IFACE (object);
5096
5097   data = g_simple_async_result_get_op_res_gpointer (res);
5098
5099   stream = iface->append_to (G_FILE (object), *data, cancellable, &error);
5100
5101   if (stream == NULL)
5102     g_simple_async_result_take_error (res, error);
5103   else
5104     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
5105 }
5106
5107 static void
5108 g_file_real_append_to_async (GFile               *file,
5109                              GFileCreateFlags     flags,
5110                              int                  io_priority,
5111                              GCancellable        *cancellable,
5112                              GAsyncReadyCallback  callback,
5113                              gpointer             user_data)
5114 {
5115   GFileCreateFlags *data;
5116   GSimpleAsyncResult *res;
5117
5118   data = g_new0 (GFileCreateFlags, 1);
5119   *data = flags;
5120
5121   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_append_to_async);
5122   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
5123
5124   g_simple_async_result_run_in_thread (res, append_to_async_thread, io_priority, cancellable);
5125   g_object_unref (res);
5126 }
5127
5128 static GFileOutputStream *
5129 g_file_real_append_to_finish (GFile         *file,
5130                               GAsyncResult  *res,
5131                               GError       **error)
5132 {
5133   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
5134   gpointer op;
5135
5136   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_append_to_async);
5137
5138   op = g_simple_async_result_get_op_res_gpointer (simple);
5139   if (op)
5140     return g_object_ref (op);
5141   
5142   return NULL;
5143 }
5144
5145 static void
5146 create_async_thread (GSimpleAsyncResult *res,
5147                      GObject            *object,
5148                      GCancellable       *cancellable)
5149 {
5150   GFileIface *iface;
5151   GFileCreateFlags *data;
5152   GFileOutputStream *stream;
5153   GError *error = NULL;
5154
5155   iface = G_FILE_GET_IFACE (object);
5156
5157   data = g_simple_async_result_get_op_res_gpointer (res);
5158
5159   stream = iface->create (G_FILE (object), *data, cancellable, &error);
5160
5161   if (stream == NULL)
5162     g_simple_async_result_take_error (res, error);
5163   else
5164     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
5165 }
5166
5167 static void
5168 g_file_real_create_async (GFile               *file,
5169                           GFileCreateFlags     flags,
5170                           int                  io_priority,
5171                           GCancellable        *cancellable,
5172                           GAsyncReadyCallback  callback,
5173                           gpointer             user_data)
5174 {
5175   GFileCreateFlags *data;
5176   GSimpleAsyncResult *res;
5177
5178   data = g_new0 (GFileCreateFlags, 1);
5179   *data = flags;
5180
5181   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_create_async);
5182   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
5183
5184   g_simple_async_result_run_in_thread (res, create_async_thread, io_priority, cancellable);
5185   g_object_unref (res);
5186 }
5187
5188 static GFileOutputStream *
5189 g_file_real_create_finish (GFile         *file,
5190                            GAsyncResult  *res,
5191                            GError       **error)
5192 {
5193   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
5194   gpointer op;
5195
5196   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_create_async);
5197
5198   op = g_simple_async_result_get_op_res_gpointer (simple);
5199   if (op)
5200     return g_object_ref (op);
5201   
5202   return NULL;
5203 }
5204
5205 typedef struct {
5206   GFileOutputStream *stream;
5207   char *etag;
5208   gboolean make_backup;
5209   GFileCreateFlags flags;
5210 } ReplaceAsyncData;
5211
5212 static void
5213 replace_async_data_free (ReplaceAsyncData *data)
5214 {
5215   if (data->stream)
5216     g_object_unref (data->stream);
5217   g_free (data->etag);
5218   g_free (data);
5219 }
5220
5221 static void
5222 replace_async_thread (GSimpleAsyncResult *res,
5223                       GObject            *object,
5224                       GCancellable       *cancellable)
5225 {
5226   GFileIface *iface;
5227   GFileOutputStream *stream;
5228   GError *error = NULL;
5229   ReplaceAsyncData *data;
5230
5231   iface = G_FILE_GET_IFACE (object);
5232   
5233   data = g_simple_async_result_get_op_res_gpointer (res);
5234
5235   stream = iface->replace (G_FILE (object),
5236                            data->etag,
5237                            data->make_backup,
5238                            data->flags,
5239                            cancellable,
5240                            &error);
5241
5242   if (stream == NULL)
5243     g_simple_async_result_take_error (res, error);
5244   else
5245     data->stream = stream;
5246 }
5247
5248 static void
5249 g_file_real_replace_async (GFile               *file,
5250                            const char          *etag,
5251                            gboolean             make_backup,
5252                            GFileCreateFlags     flags,
5253                            int                  io_priority,
5254                            GCancellable        *cancellable,
5255                            GAsyncReadyCallback  callback,
5256                            gpointer             user_data)
5257 {
5258   GSimpleAsyncResult *res;
5259   ReplaceAsyncData *data;
5260
5261   data = g_new0 (ReplaceAsyncData, 1);
5262   data->etag = g_strdup (etag);
5263   data->make_backup = make_backup;
5264   data->flags = flags;
5265
5266   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_replace_async);
5267   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_async_data_free);
5268
5269   g_simple_async_result_run_in_thread (res, replace_async_thread, io_priority, cancellable);
5270   g_object_unref (res);
5271 }
5272
5273 static GFileOutputStream *
5274 g_file_real_replace_finish (GFile         *file,
5275                             GAsyncResult  *res,
5276                             GError       **error)
5277 {
5278   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
5279   ReplaceAsyncData *data;
5280
5281   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_replace_async);
5282
5283   data = g_simple_async_result_get_op_res_gpointer (simple);
5284   if (data->stream)
5285     return g_object_ref (data->stream);
5286   
5287   return NULL;
5288 }
5289
5290 static void
5291 open_readwrite_async_thread (GSimpleAsyncResult *res,
5292                              GObject            *object,
5293                              GCancellable       *cancellable)
5294 {
5295   GFileIface *iface;
5296   GFileIOStream *stream;
5297   GError *error = NULL;
5298
5299   iface = G_FILE_GET_IFACE (object);
5300
5301   if (iface->open_readwrite == NULL)
5302     {
5303       g_set_error_literal (&error, G_IO_ERROR,
5304                            G_IO_ERROR_NOT_SUPPORTED,
5305                            _("Operation not supported"));
5306
5307       g_simple_async_result_take_error (res, error);
5308
5309       return;
5310     }
5311
5312   stream = iface->open_readwrite (G_FILE (object), cancellable, &error);
5313
5314   if (stream == NULL)
5315     g_simple_async_result_take_error (res, error);
5316   else
5317     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
5318 }
5319
5320 static void
5321 g_file_real_open_readwrite_async (GFile               *file,
5322                                   int                  io_priority,
5323                                   GCancellable        *cancellable,
5324                                   GAsyncReadyCallback  callback,
5325                                   gpointer             user_data)
5326 {
5327   GSimpleAsyncResult *res;
5328
5329   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_open_readwrite_async);
5330
5331   g_simple_async_result_run_in_thread (res, open_readwrite_async_thread, io_priority, cancellable);
5332   g_object_unref (res);
5333 }
5334
5335 static GFileIOStream *
5336 g_file_real_open_readwrite_finish (GFile         *file,
5337                                    GAsyncResult  *res,
5338                                    GError       **error)
5339 {
5340   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
5341   gpointer op;
5342
5343   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_open_readwrite_async);
5344
5345   op = g_simple_async_result_get_op_res_gpointer (simple);
5346   if (op)
5347     return g_object_ref (op);
5348
5349   return NULL;
5350 }
5351
5352 static void
5353 create_readwrite_async_thread (GSimpleAsyncResult *res,
5354                                GObject            *object,
5355                                GCancellable       *cancellable)
5356 {
5357   GFileIface *iface;
5358   GFileCreateFlags *data;
5359   GFileIOStream *stream;
5360   GError *error = NULL;
5361
5362   iface = G_FILE_GET_IFACE (object);
5363
5364   data = g_simple_async_result_get_op_res_gpointer (res);
5365
5366   if (iface->create_readwrite == NULL)
5367     {
5368       g_set_error_literal (&error, G_IO_ERROR,
5369                            G_IO_ERROR_NOT_SUPPORTED,
5370                            _("Operation not supported"));
5371
5372       g_simple_async_result_take_error (res, error);
5373
5374       return;
5375     }
5376
5377   stream = iface->create_readwrite (G_FILE (object), *data, cancellable, &error);
5378
5379   if (stream == NULL)
5380     g_simple_async_result_take_error (res, error);
5381   else
5382     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
5383 }
5384
5385 static void
5386 g_file_real_create_readwrite_async (GFile               *file,
5387                                     GFileCreateFlags     flags,
5388                                     int                  io_priority,
5389                                     GCancellable        *cancellable,
5390                                     GAsyncReadyCallback  callback,
5391                                     gpointer             user_data)
5392 {
5393   GFileCreateFlags *data;
5394   GSimpleAsyncResult *res;
5395
5396   data = g_new0 (GFileCreateFlags, 1);
5397   *data = flags;
5398
5399   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_create_readwrite_async);
5400   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
5401
5402   g_simple_async_result_run_in_thread (res, create_readwrite_async_thread, io_priority, cancellable);
5403   g_object_unref (res);
5404 }
5405
5406 static GFileIOStream *
5407 g_file_real_create_readwrite_finish (GFile         *file,
5408                                      GAsyncResult  *res,
5409                                      GError       **error)
5410 {
5411   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
5412   gpointer op;
5413
5414   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_create_readwrite_async);
5415
5416   op = g_simple_async_result_get_op_res_gpointer (simple);
5417   if (op)
5418     return g_object_ref (op);
5419
5420   return NULL;
5421 }
5422
5423 typedef struct {
5424   GFileIOStream *stream;
5425   char *etag;
5426   gboolean make_backup;
5427   GFileCreateFlags flags;
5428 } ReplaceRWAsyncData;
5429
5430 static void
5431 replace_rw_async_data_free (ReplaceRWAsyncData *data)
5432 {
5433   if (data->stream)
5434     g_object_unref (data->stream);
5435   g_free (data->etag);
5436   g_free (data);
5437 }
5438
5439 static void
5440 replace_readwrite_async_thread (GSimpleAsyncResult *res,
5441                                 GObject            *object,
5442                                 GCancellable       *cancellable)
5443 {
5444   GFileIface *iface;
5445   GFileIOStream *stream;
5446   GError *error = NULL;
5447   ReplaceRWAsyncData *data;
5448
5449   iface = G_FILE_GET_IFACE (object);
5450
5451   data = g_simple_async_result_get_op_res_gpointer (res);
5452
5453   stream = iface->replace_readwrite (G_FILE (object),
5454                                      data->etag,
5455                                      data->make_backup,
5456                                      data->flags,
5457                                      cancellable,
5458                                      &error);
5459
5460   if (stream == NULL)
5461     g_simple_async_result_take_error (res, error);
5462   else
5463     data->stream = stream;
5464 }
5465
5466 static void
5467 g_file_real_replace_readwrite_async (GFile               *file,
5468                                      const char          *etag,
5469                                      gboolean             make_backup,
5470                                      GFileCreateFlags     flags,
5471                                      int                  io_priority,
5472                                      GCancellable        *cancellable,
5473                                      GAsyncReadyCallback  callback,
5474                                      gpointer             user_data)
5475 {
5476   GSimpleAsyncResult *res;
5477   ReplaceRWAsyncData *data;
5478
5479   data = g_new0 (ReplaceRWAsyncData, 1);
5480   data->etag = g_strdup (etag);
5481   data->make_backup = make_backup;
5482   data->flags = flags;
5483
5484   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_replace_readwrite_async);
5485   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_rw_async_data_free);
5486
5487   g_simple_async_result_run_in_thread (res, replace_readwrite_async_thread, io_priority, cancellable);
5488   g_object_unref (res);
5489 }
5490
5491 static GFileIOStream *
5492 g_file_real_replace_readwrite_finish (GFile         *file,
5493                                       GAsyncResult  *res,
5494                                       GError       **error)
5495 {
5496   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
5497   ReplaceRWAsyncData *data;
5498
5499   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_replace_readwrite_async);
5500
5501   data = g_simple_async_result_get_op_res_gpointer (simple);
5502   if (data->stream)
5503     return g_object_ref (data->stream);
5504
5505   return NULL;
5506 }
5507
5508 typedef struct {
5509   char *name;
5510   GFile *file;
5511 } SetDisplayNameAsyncData;
5512
5513 static void
5514 set_display_name_data_free (SetDisplayNameAsyncData *data)
5515 {
5516   g_free (data->name);
5517   if (data->file)
5518     g_object_unref (data->file);
5519   g_free (data);
5520 }
5521
5522 static void
5523 set_display_name_async_thread (GSimpleAsyncResult *res,
5524                                GObject            *object,
5525                                GCancellable       *cancellable)
5526 {
5527   GError *error = NULL;
5528   SetDisplayNameAsyncData *data;
5529   GFile *file;
5530   
5531   data = g_simple_async_result_get_op_res_gpointer (res);
5532   
5533   file = g_file_set_display_name (G_FILE (object), data->name, cancellable, &error);
5534
5535   if (file == NULL)
5536     g_simple_async_result_take_error (res, error);
5537   else
5538     data->file = file;
5539 }
5540
5541 static void
5542 g_file_real_set_display_name_async (GFile               *file,  
5543                                     const char          *display_name,
5544                                     int                  io_priority,
5545                                     GCancellable        *cancellable,
5546                                     GAsyncReadyCallback  callback,
5547                                     gpointer             user_data)
5548 {
5549   GSimpleAsyncResult *res;
5550   SetDisplayNameAsyncData *data;
5551
5552   data = g_new0 (SetDisplayNameAsyncData, 1);
5553   data->name = g_strdup (display_name);
5554   
5555   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_display_name_async);
5556   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_display_name_data_free);
5557   
5558   g_simple_async_result_run_in_thread (res, set_display_name_async_thread, io_priority, cancellable);
5559   g_object_unref (res);
5560 }
5561
5562 static GFile *
5563 g_file_real_set_display_name_finish (GFile         *file,
5564                                      GAsyncResult  *res,
5565                                      GError       **error)
5566 {
5567   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
5568   SetDisplayNameAsyncData *data;
5569
5570   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_display_name_async);
5571
5572   data = g_simple_async_result_get_op_res_gpointer (simple);
5573   if (data->file)
5574     return g_object_ref (data->file);
5575   
5576   return NULL;
5577 }
5578
5579 typedef struct {
5580   GFileQueryInfoFlags flags;
5581   GFileInfo *info;
5582   gboolean res;
5583   GError *error;
5584 } SetInfoAsyncData;
5585
5586 static void
5587 set_info_data_free (SetInfoAsyncData *data)
5588 {
5589   if (data->info)
5590     g_object_unref (data->info);
5591   if (data->error)
5592     g_error_free (data->error);
5593   g_free (data);
5594 }
5595
5596 static void
5597 set_info_async_thread (GSimpleAsyncResult *res,
5598                        GObject            *object,
5599                        GCancellable       *cancellable)
5600 {
5601   SetInfoAsyncData *data;
5602   
5603   data = g_simple_async_result_get_op_res_gpointer (res);
5604   
5605   data->error = NULL;
5606   data->res = g_file_set_attributes_from_info (G_FILE (object),
5607                                                data->info,
5608                                                data->flags,
5609                                                cancellable,
5610                                                &data->error);
5611 }
5612
5613 static void
5614 g_file_real_set_attributes_async (GFile               *file,
5615                                   GFileInfo           *info,
5616                                   GFileQueryInfoFlags  flags,
5617                                   int                  io_priority,
5618                                   GCancellable        *cancellable,
5619                                   GAsyncReadyCallback  callback,
5620                                   gpointer             user_data)
5621 {
5622   GSimpleAsyncResult *res;
5623   SetInfoAsyncData *data;
5624
5625   data = g_new0 (SetInfoAsyncData, 1);
5626   data->info = g_file_info_dup (info);
5627   data->flags = flags;
5628   
5629   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_attributes_async);
5630   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_info_data_free);
5631   
5632   g_simple_async_result_run_in_thread (res, set_info_async_thread, io_priority, cancellable);
5633   g_object_unref (res);
5634 }
5635
5636 static gboolean
5637 g_file_real_set_attributes_finish (GFile         *file,
5638                                    GAsyncResult  *res,
5639                                    GFileInfo    **info,
5640                                    GError       **error)
5641 {
5642   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
5643   SetInfoAsyncData *data;
5644   
5645   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_set_attributes_async);
5646
5647   data = g_simple_async_result_get_op_res_gpointer (simple);
5648
5649   if (info) 
5650     *info = g_object_ref (data->info);
5651
5652   if (error != NULL && data->error) 
5653     *error = g_error_copy (data->error);
5654   
5655   return data->res;
5656 }
5657
5658 static void
5659 find_enclosing_mount_async_thread (GSimpleAsyncResult *res,
5660                                     GObject            *object,
5661                                     GCancellable       *cancellable)
5662 {
5663   GError *error = NULL;
5664   GMount *mount;
5665   
5666   mount = g_file_find_enclosing_mount (G_FILE (object), cancellable, &error);
5667
5668   if (mount == NULL)
5669     g_simple_async_result_take_error (res, error);
5670   else
5671     g_simple_async_result_set_op_res_gpointer (res, mount, (GDestroyNotify)g_object_unref);
5672 }
5673
5674 static void
5675 g_file_real_find_enclosing_mount_async (GFile               *file,
5676                                         int                  io_priority,
5677                                         GCancellable        *cancellable,
5678                                         GAsyncReadyCallback  callback,
5679                                         gpointer             user_data)
5680 {
5681   GSimpleAsyncResult *res;
5682   
5683   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_find_enclosing_mount_async);
5684   
5685   g_simple_async_result_run_in_thread (res, find_enclosing_mount_async_thread, io_priority, cancellable);
5686   g_object_unref (res);
5687 }
5688
5689 static GMount *
5690 g_file_real_find_enclosing_mount_finish (GFile         *file,
5691                                           GAsyncResult  *res,
5692                                           GError       **error)
5693 {
5694   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
5695   GMount *mount;
5696
5697   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_find_enclosing_mount_async);
5698
5699   mount = g_simple_async_result_get_op_res_gpointer (simple);
5700   return g_object_ref (mount);
5701 }
5702
5703
5704 typedef struct {
5705   GFile *source;
5706   GFile *destination;
5707   GFileCopyFlags flags;
5708   GFileProgressCallback progress_cb;
5709   gpointer progress_cb_data;
5710   GIOSchedulerJob *job;
5711 } CopyAsyncData;
5712
5713 static void
5714 copy_async_data_free (CopyAsyncData *data)
5715 {
5716   g_object_unref (data->source);
5717   g_object_unref (data->destination);
5718   g_free (data);
5719 }
5720
5721 typedef struct {
5722   CopyAsyncData *data;
5723   goffset current_num_bytes;
5724   goffset total_num_bytes;
5725 } ProgressData;
5726
5727 static gboolean
5728 copy_async_progress_in_main (gpointer user_data)
5729 {
5730   ProgressData *progress = user_data;
5731   CopyAsyncData *data = progress->data;
5732
5733   data->progress_cb (progress->current_num_bytes,
5734                      progress->total_num_bytes,
5735                      data->progress_cb_data);
5736
5737   return FALSE;
5738 }
5739
5740 static gboolean
5741 mainloop_barrier (gpointer user_data)
5742 {
5743   /* Does nothing, but ensures all queued idles before
5744      this are run */
5745   return FALSE;
5746 }
5747
5748
5749 static void
5750 copy_async_progress_callback (goffset  current_num_bytes,
5751                               goffset  total_num_bytes,
5752                               gpointer user_data)
5753 {
5754   CopyAsyncData *data = user_data;
5755   ProgressData *progress;
5756
5757   progress = g_new (ProgressData, 1);
5758   progress->data = data;
5759   progress->current_num_bytes = current_num_bytes;
5760   progress->total_num_bytes = total_num_bytes;
5761   
5762   g_io_scheduler_job_send_to_mainloop_async (data->job,
5763                                              copy_async_progress_in_main,
5764                                              progress,
5765                                              g_free);
5766 }
5767
5768 static gboolean
5769 copy_async_thread (GIOSchedulerJob *job,
5770                    GCancellable    *cancellable,
5771                    gpointer         user_data)
5772 {
5773   GSimpleAsyncResult *res;
5774   CopyAsyncData *data;
5775   gboolean result;
5776   GError *error;
5777
5778   res = user_data;
5779   data = g_simple_async_result_get_op_res_gpointer (res);
5780
5781   error = NULL;
5782   data->job = job;
5783   result = g_file_copy (data->source,
5784                         data->destination,
5785                         data->flags,
5786                         cancellable,
5787                         (data->progress_cb != NULL) ? copy_async_progress_callback : NULL,
5788                         data,
5789                         &error);
5790
5791   /* Ensure all progress callbacks are done running in main thread */
5792   if (data->progress_cb != NULL)
5793     g_io_scheduler_job_send_to_mainloop (job,
5794                                          mainloop_barrier,
5795                                          NULL, NULL);
5796   
5797   if (!result)
5798     g_simple_async_result_take_error (res, error);
5799
5800   g_simple_async_result_complete_in_idle (res);
5801
5802   return FALSE;
5803 }
5804
5805 static void
5806 g_file_real_copy_async (GFile                  *source,
5807                         GFile                  *destination,
5808                         GFileCopyFlags          flags,
5809                         int                     io_priority,
5810                         GCancellable           *cancellable,
5811                         GFileProgressCallback   progress_callback,
5812                         gpointer                progress_callback_data,
5813                         GAsyncReadyCallback     callback,
5814                         gpointer                user_data)
5815 {
5816   GSimpleAsyncResult *res;
5817   CopyAsyncData *data;
5818
5819   data = g_new0 (CopyAsyncData, 1);
5820   data->source = g_object_ref (source);
5821   data->destination = g_object_ref (destination);
5822   data->flags = flags;
5823   data->progress_cb = progress_callback;
5824   data->progress_cb_data = progress_callback_data;
5825
5826   res = g_simple_async_result_new (G_OBJECT (source), callback, user_data, g_file_real_copy_async);
5827   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)copy_async_data_free);
5828
5829   g_io_scheduler_push_job (copy_async_thread, res, g_object_unref, io_priority, cancellable);
5830 }
5831
5832 static gboolean
5833 g_file_real_copy_finish (GFile        *file,
5834                          GAsyncResult *res,
5835                          GError      **error)
5836 {
5837   /* Error handled in g_file_copy_finish() */
5838   return TRUE;
5839 }
5840
5841
5842 /********************************************
5843  *   Default VFS operations                 *
5844  ********************************************/
5845
5846 /**
5847  * g_file_new_for_path:
5848  * @path: a string containing a relative or absolute path. The string
5849  *   must be encoded in the glib filename encoding.
5850  * 
5851  * Constructs a #GFile for a given path. This operation never
5852  * fails, but the returned object might not support any I/O
5853  * operation if @path is malformed.
5854  * 
5855  * Returns: (transfer full): a new #GFile for the given @path. 
5856  **/
5857 GFile *
5858 g_file_new_for_path (const char *path)
5859 {
5860   g_return_val_if_fail (path != NULL, NULL);
5861
5862   return g_vfs_get_file_for_path (g_vfs_get_default (), path);
5863 }
5864  
5865 /**
5866  * g_file_new_for_uri:
5867  * @uri: a UTF8 string containing a URI.
5868  * 
5869  * Constructs a #GFile for a given URI. This operation never 
5870  * fails, but the returned object might not support any I/O 
5871  * operation if @uri is malformed or if the uri type is 
5872  * not supported.
5873  * 
5874  * Returns: (transfer full): a #GFile for the given @uri.
5875  **/ 
5876 GFile *
5877 g_file_new_for_uri (const char *uri)
5878 {
5879   g_return_val_if_fail (uri != NULL, NULL);
5880
5881   return g_vfs_get_file_for_uri (g_vfs_get_default (), uri);
5882 }
5883   
5884 /**
5885  * g_file_parse_name:
5886  * @parse_name: a file name or path to be parsed.
5887  * 
5888  * Constructs a #GFile with the given @parse_name (i.e. something given by g_file_get_parse_name()).
5889  * This operation never fails, but the returned object might not support any I/O
5890  * operation if the @parse_name cannot be parsed.
5891  * 
5892  * Returns: (transfer full): a new #GFile.
5893  **/
5894 GFile *
5895 g_file_parse_name (const char *parse_name)
5896 {
5897   g_return_val_if_fail (parse_name != NULL, NULL);
5898
5899   return g_vfs_parse_name (g_vfs_get_default (), parse_name);
5900 }
5901
5902 static gboolean
5903 is_valid_scheme_character (char c)
5904 {
5905   return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.';
5906 }
5907
5908 /* Following RFC 2396, valid schemes are built like:
5909  *       scheme        = alpha *( alpha | digit | "+" | "-" | "." )
5910  */
5911 static gboolean
5912 has_valid_scheme (const char *uri)
5913 {
5914   const char *p;
5915   
5916   p = uri;
5917   
5918   if (!g_ascii_isalpha (*p))
5919     return FALSE;
5920
5921   do {
5922     p++;
5923   } while (is_valid_scheme_character (*p));
5924
5925   return *p == ':';
5926 }
5927
5928 /**
5929  * g_file_new_for_commandline_arg:
5930  * @arg: a command line string.
5931  * 
5932  * Creates a #GFile with the given argument from the command line. The value of
5933  * @arg can be either a URI, an absolute path or a relative path resolved
5934  * relative to the current working directory.
5935  * This operation never fails, but the returned object might not support any
5936  * I/O operation if @arg points to a malformed path.
5937  *
5938  * Returns: (transfer full): a new #GFile. 
5939  **/
5940 GFile *
5941 g_file_new_for_commandline_arg (const char *arg)
5942 {
5943   GFile *file;
5944   char *filename;
5945   char *current_dir;
5946   
5947   g_return_val_if_fail (arg != NULL, NULL);
5948   
5949   if (g_path_is_absolute (arg))
5950     return g_file_new_for_path (arg);
5951
5952   if (has_valid_scheme (arg))
5953     return g_file_new_for_uri (arg);
5954     
5955   current_dir = g_get_current_dir ();
5956   filename = g_build_filename (current_dir, arg, NULL);
5957   g_free (current_dir);
5958   
5959   file = g_file_new_for_path (filename);
5960   g_free (filename);
5961   
5962   return file;
5963 }
5964
5965 /**
5966  * g_file_mount_enclosing_volume:
5967  * @location: input #GFile.
5968  * @flags: flags affecting the operation
5969  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
5970  * @cancellable: optional #GCancellable object, %NULL to ignore.
5971  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
5972  * @user_data: the data to pass to callback function
5973  * 
5974  * Starts a @mount_operation, mounting the volume that contains the file @location. 
5975  * 
5976  * When this operation has completed, @callback will be called with
5977  * @user_user data, and the operation can be finalized with 
5978  * g_file_mount_enclosing_volume_finish().
5979  * 
5980  * If @cancellable is not %NULL, then the operation can be cancelled by
5981  * triggering the cancellable object from another thread. If the operation
5982  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
5983  **/
5984 void
5985 g_file_mount_enclosing_volume (GFile               *location,
5986                                GMountMountFlags     flags,
5987                                GMountOperation     *mount_operation,
5988                                GCancellable        *cancellable,
5989                                GAsyncReadyCallback  callback,
5990                                gpointer             user_data)
5991 {
5992   GFileIface *iface;
5993
5994   g_return_if_fail (G_IS_FILE (location));
5995
5996   iface = G_FILE_GET_IFACE (location);
5997
5998   if (iface->mount_enclosing_volume == NULL)
5999     {
6000       g_simple_async_report_error_in_idle (G_OBJECT (location),
6001                                            callback, user_data,
6002                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
6003                                            _("volume doesn't implement mount"));
6004       
6005       return;
6006     }
6007   
6008   (* iface->mount_enclosing_volume) (location, flags, mount_operation, cancellable, callback, user_data);
6009
6010 }
6011
6012 /**
6013  * g_file_mount_enclosing_volume_finish:
6014  * @location: input #GFile.
6015  * @result: a #GAsyncResult.
6016  * @error: a #GError, or %NULL
6017  * 
6018  * Finishes a mount operation started by g_file_mount_enclosing_volume().
6019  * 
6020  * Returns: %TRUE if successful. If an error
6021  * has occurred, this function will return %FALSE and set @error
6022  * appropriately if present.
6023  **/
6024 gboolean
6025 g_file_mount_enclosing_volume_finish (GFile         *location,
6026                                       GAsyncResult  *result,
6027                                       GError       **error)
6028 {
6029   GFileIface *iface;
6030
6031   g_return_val_if_fail (G_IS_FILE (location), FALSE);
6032   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
6033
6034   if (G_IS_SIMPLE_ASYNC_RESULT (result))
6035     {
6036       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
6037       if (g_simple_async_result_propagate_error (simple, error))
6038         return FALSE;
6039     }
6040   
6041   iface = G_FILE_GET_IFACE (location);
6042
6043   return (* iface->mount_enclosing_volume_finish) (location, result, error);
6044 }
6045
6046 /********************************************
6047  *   Utility functions                      *
6048  ********************************************/
6049
6050 /**
6051  * g_file_query_default_handler:
6052  * @file: a #GFile to open.
6053  * @cancellable: optional #GCancellable object, %NULL to ignore.
6054  * @error: a #GError, or %NULL
6055  *
6056  * Returns the #GAppInfo that is registered as the default
6057  * application to handle the file specified by @file.
6058  *
6059  * If @cancellable is not %NULL, then the operation can be cancelled by
6060  * triggering the cancellable object from another thread. If the operation
6061  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
6062  *
6063  * Returns: (transfer full): a #GAppInfo if the handle was found, %NULL if there were errors.
6064  * When you are done with it, release it with g_object_unref()
6065  **/
6066 GAppInfo *
6067 g_file_query_default_handler (GFile                  *file,
6068                               GCancellable           *cancellable,
6069                               GError                **error)
6070 {
6071   char *uri_scheme;
6072   const char *content_type;
6073   GAppInfo *appinfo;
6074   GFileInfo *info;
6075   char *path;
6076   
6077   uri_scheme = g_file_get_uri_scheme (file);
6078   if (uri_scheme && uri_scheme[0] != '\0')
6079     {
6080       appinfo = g_app_info_get_default_for_uri_scheme (uri_scheme);
6081       g_free (uri_scheme);
6082
6083       if (appinfo != NULL)
6084         return appinfo;
6085     }
6086
6087   info = g_file_query_info (file,
6088                             G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
6089                             0,
6090                             cancellable,
6091                             error);
6092   if (info == NULL)
6093     return NULL;
6094
6095   appinfo = NULL;
6096
6097   content_type = g_file_info_get_content_type (info);
6098   if (content_type)
6099     {
6100       /* Don't use is_native(), as we want to support fuse paths if availible */
6101       path = g_file_get_path (file);
6102       appinfo = g_app_info_get_default_for_type (content_type,
6103                                                  path == NULL);
6104       g_free (path);
6105     }
6106   
6107   g_object_unref (info);
6108
6109   if (appinfo != NULL)
6110     return appinfo;
6111
6112   g_set_error_literal (error, G_IO_ERROR,
6113                        G_IO_ERROR_NOT_SUPPORTED,
6114                        _("No application is registered as handling this file"));
6115   return NULL;
6116   
6117 }
6118
6119
6120 #define GET_CONTENT_BLOCK_SIZE 8192
6121
6122 /**
6123  * g_file_load_contents:
6124  * @file: input #GFile.
6125  * @cancellable: optional #GCancellable object, %NULL to ignore.
6126  * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file.
6127  * @length: (out) (allow-none): a location to place the length of the contents of the file,
6128  *    or %NULL if the length is not needed
6129  * @etag_out: (out) (allow-none): a location to place the current entity tag for the file,
6130  *    or %NULL if the entity tag is not needed
6131  * @error: a #GError, or %NULL
6132  *
6133  * Loads the content of the file into memory. The data is always 
6134  * zero-terminated, but this is not included in the resultant @length.
6135  * The returned @content should be freed with g_free() when no longer
6136  * needed.
6137  * 
6138  * If @cancellable is not %NULL, then the operation can be cancelled by
6139  * triggering the cancellable object from another thread. If the operation
6140  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
6141  * 
6142  * Returns: %TRUE if the @file's contents were successfully loaded.
6143  * %FALSE if there were errors.
6144  **/
6145 gboolean
6146 g_file_load_contents (GFile         *file,
6147                       GCancellable  *cancellable,
6148                       char         **contents,
6149                       gsize         *length,
6150                       char         **etag_out,
6151                       GError       **error)
6152 {
6153   GFileInputStream *in;
6154   GByteArray *content;
6155   gsize pos;
6156   gssize res;
6157   GFileInfo *info;
6158
6159   g_return_val_if_fail (G_IS_FILE (file), FALSE);
6160   g_return_val_if_fail (contents != NULL, FALSE);
6161
6162   in = g_file_read (file, cancellable, error);
6163   if (in == NULL)
6164     return FALSE;
6165
6166   content = g_byte_array_new ();
6167   pos = 0;
6168   
6169   g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
6170   while ((res = g_input_stream_read (G_INPUT_STREAM (in),
6171                                      content->data + pos,
6172                                      GET_CONTENT_BLOCK_SIZE,
6173                                      cancellable, error)) > 0)
6174     {
6175       pos += res;
6176       g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
6177     }
6178
6179   if (etag_out)
6180     {
6181       *etag_out = NULL;
6182       
6183       info = g_file_input_stream_query_info (in,
6184                                              G_FILE_ATTRIBUTE_ETAG_VALUE,
6185                                              cancellable,
6186                                              NULL);
6187       if (info)
6188         {
6189           *etag_out = g_strdup (g_file_info_get_etag (info));
6190           g_object_unref (info);
6191         }
6192     } 
6193
6194   /* Ignore errors on close */
6195   g_input_stream_close (G_INPUT_STREAM (in), cancellable, NULL);
6196   g_object_unref (in);
6197
6198   if (res < 0)
6199     {
6200       /* error is set already */
6201       g_byte_array_free (content, TRUE);
6202       return FALSE;
6203     }
6204
6205   if (length)
6206     *length = pos;
6207
6208   /* Zero terminate (we got an extra byte allocated for this */
6209   content->data[pos] = 0;
6210   
6211   *contents = (char *)g_byte_array_free (content, FALSE);
6212   
6213   return TRUE;
6214 }
6215
6216 typedef struct {
6217   GFile *file;
6218   GError *error;
6219   GCancellable *cancellable;
6220   GFileReadMoreCallback read_more_callback;
6221   GAsyncReadyCallback callback;
6222   gpointer user_data;
6223   GByteArray *content;
6224   gsize pos;
6225   char *etag;
6226 } LoadContentsData;
6227
6228
6229 static void
6230 load_contents_data_free (LoadContentsData *data)
6231 {
6232   if (data->error)
6233     g_error_free (data->error);
6234   if (data->cancellable)
6235     g_object_unref (data->cancellable);
6236   if (data->content)
6237     g_byte_array_free (data->content, TRUE);
6238   g_free (data->etag);
6239   g_object_unref (data->file);
6240   g_free (data);
6241 }
6242
6243 static void
6244 load_contents_close_callback (GObject      *obj,
6245                               GAsyncResult *close_res,
6246                               gpointer      user_data)
6247 {
6248   GInputStream *stream = G_INPUT_STREAM (obj);
6249   LoadContentsData *data = user_data;
6250   GSimpleAsyncResult *res;
6251
6252   /* Ignore errors here, we're only reading anyway */
6253   g_input_stream_close_finish (stream, close_res, NULL);
6254   g_object_unref (stream);
6255
6256   res = g_simple_async_result_new (G_OBJECT (data->file),
6257                                    data->callback,
6258                                    data->user_data,
6259                                    g_file_load_contents_async);
6260   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)load_contents_data_free);
6261   g_simple_async_result_complete (res);
6262   g_object_unref (res);
6263 }
6264
6265 static void
6266 load_contents_fstat_callback (GObject      *obj,
6267                               GAsyncResult *stat_res,
6268                               gpointer      user_data)
6269 {
6270   GInputStream *stream = G_INPUT_STREAM (obj);
6271   LoadContentsData *data = user_data;
6272   GFileInfo *info;
6273
6274   info = g_file_input_stream_query_info_finish (G_FILE_INPUT_STREAM (stream),
6275                                                    stat_res, NULL);
6276   if (info)
6277     {
6278       data->etag = g_strdup (g_file_info_get_etag (info));
6279       g_object_unref (info);
6280     }
6281
6282   g_input_stream_close_async (stream, 0,
6283                               data->cancellable,
6284                               load_contents_close_callback, data);
6285 }
6286
6287 static void
6288 load_contents_read_callback (GObject      *obj,
6289                              GAsyncResult *read_res,
6290                              gpointer      user_data)
6291 {
6292   GInputStream *stream = G_INPUT_STREAM (obj);
6293   LoadContentsData *data = user_data;
6294   GError *error = NULL;
6295   gssize read_size;
6296
6297   read_size = g_input_stream_read_finish (stream, read_res, &error);
6298
6299   if (read_size < 0) 
6300     {
6301       /* Error or EOF, close the file */
6302       data->error = error;
6303       g_input_stream_close_async (stream, 0,
6304                                   data->cancellable,
6305                                   load_contents_close_callback, data);
6306     }
6307   else if (read_size == 0)
6308     {
6309       g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
6310                                             G_FILE_ATTRIBUTE_ETAG_VALUE,
6311                                             0,
6312                                             data->cancellable,
6313                                             load_contents_fstat_callback,
6314                                             data);
6315     }
6316   else if (read_size > 0)
6317     {
6318       data->pos += read_size;
6319       
6320       g_byte_array_set_size (data->content,
6321                              data->pos + GET_CONTENT_BLOCK_SIZE);
6322
6323
6324       if (data->read_more_callback &&
6325           !data->read_more_callback ((char *)data->content->data, data->pos, data->user_data))
6326         g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
6327                                               G_FILE_ATTRIBUTE_ETAG_VALUE,
6328                                               0,
6329                                               data->cancellable,
6330                                               load_contents_fstat_callback,
6331                                               data);
6332       else 
6333         g_input_stream_read_async (stream,
6334                                    data->content->data + data->pos,
6335                                    GET_CONTENT_BLOCK_SIZE,
6336                                    0,
6337                                    data->cancellable,
6338                                    load_contents_read_callback,
6339                                    data);
6340     }
6341 }
6342
6343 static void
6344 load_contents_open_callback (GObject      *obj,
6345                              GAsyncResult *open_res,
6346                              gpointer      user_data)
6347 {
6348   GFile *file = G_FILE (obj);
6349   GFileInputStream *stream;
6350   LoadContentsData *data = user_data;
6351   GError *error = NULL;
6352   GSimpleAsyncResult *res;
6353
6354   stream = g_file_read_finish (file, open_res, &error);
6355
6356   if (stream)
6357     {
6358       g_byte_array_set_size (data->content,
6359                              data->pos + GET_CONTENT_BLOCK_SIZE);
6360       g_input_stream_read_async (G_INPUT_STREAM (stream),
6361                                  data->content->data + data->pos,
6362                                  GET_CONTENT_BLOCK_SIZE,
6363                                  0,
6364                                  data->cancellable,
6365                                  load_contents_read_callback,
6366                                  data);
6367       
6368     }
6369   else
6370     {
6371       res = g_simple_async_result_new_take_error (G_OBJECT (data->file),
6372                                                   data->callback,
6373                                                   data->user_data,
6374                                                   error);
6375       g_simple_async_result_complete (res);
6376       load_contents_data_free (data);
6377       g_object_unref (res);
6378     }
6379 }
6380
6381 /**
6382  * g_file_load_partial_contents_async: (skip)
6383  * @file: input #GFile.
6384  * @cancellable: optional #GCancellable object, %NULL to ignore.
6385  * @read_more_callback: a #GFileReadMoreCallback to receive partial data and to specify whether further data should be read.
6386  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
6387  * @user_data: the data to pass to the callback functions.
6388  *
6389  * Reads the partial contents of a file. A #GFileReadMoreCallback should be 
6390  * used to stop reading from the file when appropriate, else this function
6391  * will behave exactly as g_file_load_contents_async(). This operation 
6392  * can be finished by g_file_load_partial_contents_finish().
6393  *
6394  * Users of this function should be aware that @user_data is passed to 
6395  * both the @read_more_callback and the @callback.
6396  *
6397  * If @cancellable is not %NULL, then the operation can be cancelled by
6398  * triggering the cancellable object from another thread. If the operation
6399  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
6400  **/
6401 void
6402 g_file_load_partial_contents_async (GFile                 *file,
6403                                     GCancellable          *cancellable,
6404                                     GFileReadMoreCallback  read_more_callback,
6405                                     GAsyncReadyCallback    callback,
6406                                     gpointer               user_data)
6407 {
6408   LoadContentsData *data;
6409
6410   g_return_if_fail (G_IS_FILE (file));
6411
6412   data = g_new0 (LoadContentsData, 1);
6413
6414   if (cancellable)
6415     data->cancellable = g_object_ref (cancellable);
6416   data->read_more_callback = read_more_callback;
6417   data->callback = callback;
6418   data->user_data = user_data;
6419   data->content = g_byte_array_new ();
6420   data->file = g_object_ref (file);
6421
6422   g_file_read_async (file,
6423                      0,
6424                      cancellable,
6425                      load_contents_open_callback,
6426                      data);
6427 }
6428
6429 /**
6430  * g_file_load_partial_contents_finish:
6431  * @file: input #GFile.
6432  * @res: a #GAsyncResult. 
6433  * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file.
6434  * @length: (out) (allow-none): a location to place the length of the contents of the file,
6435  *     or %NULL if the length is not needed
6436  * @etag_out: (out) (allow-none): a location to place the current entity tag for the file,
6437  *     or %NULL if the entity tag is not needed
6438  * @error: a #GError, or %NULL
6439  * 
6440  * Finishes an asynchronous partial load operation that was started
6441  * with g_file_load_partial_contents_async(). The data is always 
6442  * zero-terminated, but this is not included in the resultant @length.
6443  * The returned @content should be freed with g_free() when no longer
6444  * needed.
6445  *
6446  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
6447  * present, it will be set appropriately. 
6448  **/
6449 gboolean
6450 g_file_load_partial_contents_finish (GFile         *file,
6451                                      GAsyncResult  *res,
6452                                      char         **contents,
6453                                      gsize         *length,
6454                                      char         **etag_out,
6455                                      GError       **error)
6456 {
6457   GSimpleAsyncResult *simple;
6458   LoadContentsData *data;
6459
6460   g_return_val_if_fail (G_IS_FILE (file), FALSE);
6461   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
6462   g_return_val_if_fail (contents != NULL, FALSE);
6463
6464   simple = G_SIMPLE_ASYNC_RESULT (res);
6465
6466   if (g_simple_async_result_propagate_error (simple, error))
6467     return FALSE;
6468   
6469   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_load_contents_async);
6470   
6471   data = g_simple_async_result_get_op_res_gpointer (simple);
6472
6473   if (data->error)
6474     {
6475       g_propagate_error (error, data->error);
6476       data->error = NULL;
6477       *contents = NULL;
6478       if (length)
6479         *length = 0;
6480       return FALSE;
6481     }
6482
6483   if (length)
6484     *length = data->pos;
6485
6486   if (etag_out)
6487     {
6488       *etag_out = data->etag;
6489       data->etag = NULL;
6490     }
6491
6492   /* Zero terminate */
6493   g_byte_array_set_size (data->content, data->pos + 1);
6494   data->content->data[data->pos] = 0;
6495   
6496   *contents = (char *)g_byte_array_free (data->content, FALSE);
6497   data->content = NULL;
6498
6499   return TRUE;
6500 }
6501
6502 /**
6503  * g_file_load_contents_async:
6504  * @file: input #GFile.
6505  * @cancellable: optional #GCancellable object, %NULL to ignore.
6506  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
6507  * @user_data: the data to pass to callback function
6508  * 
6509  * Starts an asynchronous load of the @file's contents.
6510  *
6511  * For more details, see g_file_load_contents() which is
6512  * the synchronous version of this call.
6513  *
6514  * When the load operation has completed, @callback will be called 
6515  * with @user data. To finish the operation, call 
6516  * g_file_load_contents_finish() with the #GAsyncResult returned by 
6517  * the @callback.
6518  * 
6519  * If @cancellable is not %NULL, then the operation can be cancelled by
6520  * triggering the cancellable object from another thread. If the operation
6521  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
6522  **/
6523 void
6524 g_file_load_contents_async (GFile               *file,
6525                            GCancellable        *cancellable,
6526                            GAsyncReadyCallback  callback,
6527                            gpointer             user_data)
6528 {
6529   g_file_load_partial_contents_async (file,
6530                                       cancellable,
6531                                       NULL,
6532                                       callback, user_data);
6533 }
6534
6535 /**
6536  * g_file_load_contents_finish:
6537  * @file: input #GFile.
6538  * @res: a #GAsyncResult. 
6539  * @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file.
6540  * @length: (out) (allow-none): a location to place the length of the contents of the file,
6541  *     or %NULL if the length is not needed
6542  * @etag_out: (out) (allow-none): a location to place the current entity tag for the file,
6543  *     or %NULL if the entity tag is not needed
6544  * @error: a #GError, or %NULL
6545  * 
6546  * Finishes an asynchronous load of the @file's contents. 
6547  * The contents are placed in @contents, and @length is set to the 
6548  * size of the @contents string. The @content should be freed with
6549  * g_free() when no longer needed. If @etag_out is present, it will be 
6550  * set to the new entity tag for the @file.
6551  * 
6552  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
6553  * present, it will be set appropriately. 
6554  **/
6555 gboolean
6556 g_file_load_contents_finish (GFile         *file,
6557                              GAsyncResult  *res,
6558                              char         **contents,
6559                              gsize         *length,
6560                              char         **etag_out,
6561                              GError       **error)
6562 {
6563   return g_file_load_partial_contents_finish (file,
6564                                               res,
6565                                               contents,
6566                                               length,
6567                                               etag_out,
6568                                               error);
6569 }
6570   
6571 /**
6572  * g_file_replace_contents:
6573  * @file: input #GFile.
6574  * @contents: (element-type guint8) (array length=length): a string containing the new contents for @file.
6575  * @length: the length of @contents in bytes.
6576  * @etag: (allow-none): the old <link linkend="gfile-etag">entity tag</link> 
6577  *     for the document, or %NULL
6578  * @make_backup: %TRUE if a backup should be created.
6579  * @flags: a set of #GFileCreateFlags.
6580  * @new_etag: (allow-none) (out): a location to a new <link linkend="gfile-etag">entity tag</link>
6581  *      for the document. This should be freed with g_free() when no longer 
6582  *      needed, or %NULL
6583  * @cancellable: optional #GCancellable object, %NULL to ignore.
6584  * @error: a #GError, or %NULL
6585  *
6586  * Replaces the contents of @file with @contents of @length bytes.
6587  
6588  * If @etag is specified (not %NULL) any existing file must have that etag, or
6589  * the error %G_IO_ERROR_WRONG_ETAG will be returned.
6590  *
6591  * If @make_backup is %TRUE, this function will attempt to make a backup of @file.
6592  * 
6593  * If @cancellable is not %NULL, then the operation can be cancelled by
6594  * triggering the cancellable object from another thread. If the operation
6595  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
6596  *
6597  * The returned @new_etag can be used to verify that the file hasn't changed the
6598  * next time it is saved over.
6599  * 
6600  * Returns: %TRUE if successful. If an error
6601  * has occurred, this function will return %FALSE and set @error
6602  * appropriately if present.
6603  **/
6604 gboolean
6605 g_file_replace_contents (GFile             *file,
6606                          const char        *contents,
6607                          gsize              length,
6608                          const char        *etag,
6609                          gboolean           make_backup,
6610                          GFileCreateFlags   flags,
6611                          char             **new_etag,
6612                          GCancellable      *cancellable,
6613                          GError           **error)
6614 {
6615   GFileOutputStream *out;
6616   gsize pos, remainder;
6617   gssize res;
6618   gboolean ret;
6619
6620   g_return_val_if_fail (G_IS_FILE (file), FALSE);
6621   g_return_val_if_fail (contents != NULL, FALSE);
6622
6623   out = g_file_replace (file, etag, make_backup, flags, cancellable, error);
6624   if (out == NULL)
6625     return FALSE;
6626
6627   pos = 0;
6628   remainder = length;
6629   while (remainder > 0 &&
6630          (res = g_output_stream_write (G_OUTPUT_STREAM (out),
6631                                        contents + pos,
6632                                        MIN (remainder, GET_CONTENT_BLOCK_SIZE),
6633                                        cancellable,
6634                                        error)) > 0)
6635     {
6636       pos += res;
6637       remainder -= res;
6638     }
6639   
6640   if (remainder > 0 && res < 0)
6641     {
6642       /* Ignore errors on close */
6643       g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, NULL);
6644       g_object_unref (out);
6645
6646       /* error is set already */
6647       return FALSE;
6648     }
6649   
6650   ret = g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, error);
6651
6652   if (new_etag)
6653     *new_etag = g_file_output_stream_get_etag (out);
6654
6655   g_object_unref (out);
6656
6657   return ret;
6658 }
6659
6660 typedef struct {
6661   GFile *file;
6662   GError *error;
6663   GCancellable *cancellable;
6664   GAsyncReadyCallback callback;
6665   gpointer user_data;
6666   const char *content;
6667   gsize length;
6668   gsize pos;
6669   char *etag;
6670 } ReplaceContentsData;
6671
6672 static void
6673 replace_contents_data_free (ReplaceContentsData *data)
6674 {
6675   if (data->error)
6676     g_error_free (data->error);
6677   if (data->cancellable)
6678     g_object_unref (data->cancellable);
6679   g_object_unref (data->file);
6680   g_free (data->etag);
6681   g_free (data);
6682 }
6683
6684 static void
6685 replace_contents_close_callback (GObject      *obj,
6686                                  GAsyncResult *close_res,
6687                                  gpointer      user_data)
6688 {
6689   GOutputStream *stream = G_OUTPUT_STREAM (obj);
6690   ReplaceContentsData *data = user_data;
6691   GSimpleAsyncResult *res;
6692
6693   /* Ignore errors here, we're only reading anyway */
6694   g_output_stream_close_finish (stream, close_res, NULL);
6695   g_object_unref (stream);
6696
6697   data->etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (stream));
6698   
6699   res = g_simple_async_result_new (G_OBJECT (data->file),
6700                                    data->callback,
6701                                    data->user_data,
6702                                    g_file_replace_contents_async);
6703   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_contents_data_free);
6704   g_simple_async_result_complete (res);
6705   g_object_unref (res);
6706 }
6707
6708 static void
6709 replace_contents_write_callback (GObject      *obj,
6710                                  GAsyncResult *read_res,
6711                                  gpointer      user_data)
6712 {
6713   GOutputStream *stream = G_OUTPUT_STREAM (obj);
6714   ReplaceContentsData *data = user_data;
6715   GError *error = NULL;
6716   gssize write_size;
6717   
6718   write_size = g_output_stream_write_finish (stream, read_res, &error);
6719
6720   if (write_size <= 0) 
6721     {
6722       /* Error or EOF, close the file */
6723       if (write_size < 0)
6724         data->error = error;
6725       g_output_stream_close_async (stream, 0,
6726                                    data->cancellable,
6727                                    replace_contents_close_callback, data);
6728     }
6729   else if (write_size > 0)
6730     {
6731       data->pos += write_size;
6732
6733       if (data->pos >= data->length)
6734         g_output_stream_close_async (stream, 0,
6735                                      data->cancellable,
6736                                      replace_contents_close_callback, data);
6737       else
6738         g_output_stream_write_async (stream,
6739                                      data->content + data->pos,
6740                                      data->length - data->pos,
6741                                      0,
6742                                      data->cancellable,
6743                                      replace_contents_write_callback,
6744                                      data);
6745     }
6746 }
6747
6748 static void
6749 replace_contents_open_callback (GObject      *obj,
6750                                 GAsyncResult *open_res,
6751                                 gpointer      user_data)
6752 {
6753   GFile *file = G_FILE (obj);
6754   GFileOutputStream *stream;
6755   ReplaceContentsData *data = user_data;
6756   GError *error = NULL;
6757   GSimpleAsyncResult *res;
6758
6759   stream = g_file_replace_finish (file, open_res, &error);
6760
6761   if (stream)
6762     {
6763       g_output_stream_write_async (G_OUTPUT_STREAM (stream),
6764                                    data->content + data->pos,
6765                                    data->length - data->pos,
6766                                    0,
6767                                    data->cancellable,
6768                                    replace_contents_write_callback,
6769                                    data);
6770       
6771     }
6772   else
6773     {
6774       res = g_simple_async_result_new_take_error (G_OBJECT (data->file),
6775                                                   data->callback,
6776                                                   data->user_data,
6777                                                   error);
6778       g_simple_async_result_complete (res);
6779       replace_contents_data_free (data);
6780       g_object_unref (res);
6781     }
6782 }
6783
6784 /**
6785  * g_file_replace_contents_async:
6786  * @file: input #GFile.
6787  * @contents: (element-type guint8) (array length=length): string of contents to replace the file with.
6788  * @length: the length of @contents in bytes.
6789  * @etag: (allow-none): a new <link linkend="gfile-etag">entity tag</link> for the @file, or %NULL
6790  * @make_backup: %TRUE if a backup should be created.
6791  * @flags: a set of #GFileCreateFlags.
6792  * @cancellable: optional #GCancellable object, %NULL to ignore.
6793  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
6794  * @user_data: the data to pass to callback function
6795  * 
6796  * Starts an asynchronous replacement of @file with the given 
6797  * @contents of @length bytes. @etag will replace the document's 
6798  * current entity tag.
6799  * 
6800  * When this operation has completed, @callback will be called with
6801  * @user_user data, and the operation can be finalized with 
6802  * g_file_replace_contents_finish().
6803  * 
6804  * If @cancellable is not %NULL, then the operation can be cancelled by
6805  * triggering the cancellable object from another thread. If the operation
6806  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
6807  * 
6808  * If @make_backup is %TRUE, this function will attempt to 
6809  * make a backup of @file.
6810  **/
6811 void
6812 g_file_replace_contents_async  (GFile               *file,
6813                                 const char          *contents,
6814                                 gsize                length,
6815                                 const char          *etag,
6816                                 gboolean             make_backup,
6817                                 GFileCreateFlags     flags,
6818                                 GCancellable        *cancellable,
6819                                 GAsyncReadyCallback  callback,
6820                                 gpointer             user_data)
6821 {
6822   ReplaceContentsData *data;
6823
6824   g_return_if_fail (G_IS_FILE (file));
6825   g_return_if_fail (contents != NULL);
6826
6827   data = g_new0 (ReplaceContentsData, 1);
6828
6829   if (cancellable)
6830     data->cancellable = g_object_ref (cancellable);
6831   data->callback = callback;
6832   data->user_data = user_data;
6833   data->content = contents;
6834   data->length = length;
6835   data->pos = 0;
6836   data->file = g_object_ref (file);
6837
6838   g_file_replace_async (file,
6839                         etag,
6840                         make_backup,
6841                         flags,
6842                         0,
6843                         cancellable,
6844                         replace_contents_open_callback,
6845                         data);
6846 }
6847   
6848 /**
6849  * g_file_replace_contents_finish:
6850  * @file: input #GFile.
6851  * @res: a #GAsyncResult. 
6852  * @new_etag: (out) (allow-none): a location of a new <link linkend="gfile-etag">entity tag</link> 
6853  *     for the document. This should be freed with g_free() when it is no 
6854  *     longer needed, or %NULL
6855  * @error: a #GError, or %NULL 
6856  * 
6857  * Finishes an asynchronous replace of the given @file. See
6858  * g_file_replace_contents_async(). Sets @new_etag to the new entity 
6859  * tag for the document, if present.
6860  * 
6861  * Returns: %TRUE on success, %FALSE on failure.
6862  **/
6863 gboolean
6864 g_file_replace_contents_finish (GFile         *file,
6865                                 GAsyncResult  *res,
6866                                 char         **new_etag,
6867                                 GError       **error)
6868 {
6869   GSimpleAsyncResult *simple;
6870   ReplaceContentsData *data;
6871
6872   g_return_val_if_fail (G_IS_FILE (file), FALSE);
6873   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
6874
6875   simple = G_SIMPLE_ASYNC_RESULT (res);
6876
6877   if (g_simple_async_result_propagate_error (simple, error))
6878     return FALSE;
6879   
6880   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_replace_contents_async);
6881   
6882   data = g_simple_async_result_get_op_res_gpointer (simple);
6883
6884   if (data->error)
6885     {
6886       g_propagate_error (error, data->error);
6887       data->error = NULL;
6888       return FALSE;
6889     }
6890
6891
6892   if (new_etag)
6893     {
6894       *new_etag = data->etag;
6895       data->etag = NULL; /* Take ownership */
6896     }
6897   
6898   return TRUE;
6899 }
6900
6901 /**
6902  * g_file_start_mountable:
6903  * @file: input #GFile.
6904  * @flags: flags affecting the operation
6905  * @start_operation: a #GMountOperation, or %NULL to avoid user interaction.
6906  * @cancellable: optional #GCancellable object, %NULL to ignore.
6907  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
6908  * @user_data: the data to pass to callback function
6909  *
6910  * Starts a file of type G_FILE_TYPE_MOUNTABLE.
6911  * Using @start_operation, you can request callbacks when, for instance,
6912  * passwords are needed during authentication.
6913  *
6914  * If @cancellable is not %NULL, then the operation can be cancelled by
6915  * triggering the cancellable object from another thread. If the operation
6916  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
6917  *
6918  * When the operation is finished, @callback will be called. You can then call
6919  * g_file_mount_mountable_finish() to get the result of the operation.
6920  *
6921  * Since: 2.22
6922  */
6923 void
6924 g_file_start_mountable (GFile                      *file,
6925                         GDriveStartFlags            flags,
6926                         GMountOperation            *start_operation,
6927                         GCancellable               *cancellable,
6928                         GAsyncReadyCallback         callback,
6929                         gpointer                    user_data)
6930 {
6931   GFileIface *iface;
6932
6933   g_return_if_fail (G_IS_FILE (file));
6934
6935   iface = G_FILE_GET_IFACE (file);
6936
6937   if (iface->start_mountable == NULL)
6938     {
6939       g_simple_async_report_error_in_idle (G_OBJECT (file),
6940                                            callback,
6941                                            user_data,
6942                                            G_IO_ERROR,
6943                                            G_IO_ERROR_NOT_SUPPORTED,
6944                                            _("Operation not supported"));
6945       return;
6946     }
6947
6948   (* iface->start_mountable) (file,
6949                               flags,
6950                               start_operation,
6951                               cancellable,
6952                               callback,
6953                               user_data);
6954 }
6955
6956 /**
6957  * g_file_start_mountable_finish:
6958  * @file: input #GFile.
6959  * @result: a #GAsyncResult.
6960  * @error: a #GError, or %NULL
6961  *
6962  * Finishes a start operation. See g_file_start_mountable() for details.
6963  *
6964  * Finish an asynchronous start operation that was started
6965  * with g_file_start_mountable().
6966  *
6967  * Returns: %TRUE if the operation finished successfully. %FALSE
6968  * otherwise.
6969  *
6970  * Since: 2.22
6971  */
6972 gboolean
6973 g_file_start_mountable_finish (GFile                      *file,
6974                                GAsyncResult               *result,
6975                                GError                    **error)
6976 {
6977   GFileIface *iface;
6978
6979   g_return_val_if_fail (G_IS_FILE (file), FALSE);
6980   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
6981
6982   if (G_IS_SIMPLE_ASYNC_RESULT (result))
6983     {
6984       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
6985       if (g_simple_async_result_propagate_error (simple, error))
6986         return FALSE;
6987     }
6988
6989   iface = G_FILE_GET_IFACE (file);
6990   return (* iface->start_mountable_finish) (file, result, error);
6991 }
6992
6993 /**
6994  * g_file_stop_mountable:
6995  * @file: input #GFile.
6996  * @flags: flags affecting the operation
6997  * @mount_operation: a #GMountOperation, or %NULL to avoid user interaction.
6998  * @cancellable: optional #GCancellable object, %NULL to ignore.
6999  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
7000  * @user_data: the data to pass to callback function
7001  *
7002  * Stops a file of type G_FILE_TYPE_MOUNTABLE.
7003  *
7004  * If @cancellable is not %NULL, then the operation can be cancelled by
7005  * triggering the cancellable object from another thread. If the operation
7006  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7007  *
7008  * When the operation is finished, @callback will be called. You can then call
7009  * g_file_stop_mountable_finish() to get the result of the operation.
7010  *
7011  * Since: 2.22
7012  */
7013 void
7014 g_file_stop_mountable (GFile                      *file,
7015                        GMountUnmountFlags          flags,
7016                        GMountOperation            *mount_operation,
7017                        GCancellable               *cancellable,
7018                        GAsyncReadyCallback         callback,
7019                        gpointer                    user_data)
7020 {
7021   GFileIface *iface;
7022
7023   g_return_if_fail (G_IS_FILE (file));
7024
7025   iface = G_FILE_GET_IFACE (file);
7026
7027   if (iface->stop_mountable == NULL)
7028     {
7029       g_simple_async_report_error_in_idle (G_OBJECT (file),
7030                                            callback,
7031                                            user_data,
7032                                            G_IO_ERROR,
7033                                            G_IO_ERROR_NOT_SUPPORTED,
7034                                            _("Operation not supported"));
7035       return;
7036     }
7037
7038   (* iface->stop_mountable) (file,
7039                              flags,
7040                              mount_operation,
7041                              cancellable,
7042                              callback,
7043                              user_data);
7044 }
7045
7046 /**
7047  * g_file_stop_mountable_finish:
7048  * @file: input #GFile.
7049  * @result: a #GAsyncResult.
7050  * @error: a #GError, or %NULL
7051  *
7052  * Finishes an stop operation, see g_file_stop_mountable() for details.
7053  *
7054  * Finish an asynchronous stop operation that was started
7055  * with g_file_stop_mountable().
7056  *
7057  * Returns: %TRUE if the operation finished successfully. %FALSE
7058  * otherwise.
7059  *
7060  * Since: 2.22
7061  */
7062 gboolean
7063 g_file_stop_mountable_finish (GFile                      *file,
7064                               GAsyncResult               *result,
7065                               GError                    **error)
7066 {
7067   GFileIface *iface;
7068
7069   g_return_val_if_fail (G_IS_FILE (file), FALSE);
7070   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
7071
7072   if (G_IS_SIMPLE_ASYNC_RESULT (result))
7073     {
7074       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
7075       if (g_simple_async_result_propagate_error (simple, error))
7076         return FALSE;
7077     }
7078
7079   iface = G_FILE_GET_IFACE (file);
7080   return (* iface->stop_mountable_finish) (file, result, error);
7081 }
7082
7083 /**
7084  * g_file_poll_mountable:
7085  * @file: input #GFile.
7086  * @cancellable: optional #GCancellable object, %NULL to ignore.
7087  * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
7088  * @user_data: the data to pass to callback function
7089  *
7090  * Polls a file of type G_FILE_TYPE_MOUNTABLE.
7091  *
7092  * If @cancellable is not %NULL, then the operation can be cancelled by
7093  * triggering the cancellable object from another thread. If the operation
7094  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
7095  *
7096  * When the operation is finished, @callback will be called. You can then call
7097  * g_file_mount_mountable_finish() to get the result of the operation.
7098  *
7099  * Since: 2.22
7100  */
7101 void
7102 g_file_poll_mountable (GFile                      *file,
7103                        GCancellable               *cancellable,
7104                        GAsyncReadyCallback         callback,
7105                        gpointer                    user_data)
7106 {
7107   GFileIface *iface;
7108
7109   g_return_if_fail (G_IS_FILE (file));
7110
7111   iface = G_FILE_GET_IFACE (file);
7112
7113   if (iface->poll_mountable == NULL)
7114     {
7115       g_simple_async_report_error_in_idle (G_OBJECT (file),
7116                                            callback,
7117                                            user_data,
7118                                            G_IO_ERROR,
7119                                            G_IO_ERROR_NOT_SUPPORTED,
7120                                            _("Operation not supported"));
7121       return;
7122     }
7123
7124   (* iface->poll_mountable) (file,
7125                              cancellable,
7126                              callback,
7127                              user_data);
7128 }
7129
7130 /**
7131  * g_file_poll_mountable_finish:
7132  * @file: input #GFile.
7133  * @result: a #GAsyncResult.
7134  * @error: a #GError, or %NULL
7135  *
7136  * Finishes a poll operation. See g_file_poll_mountable() for details.
7137  *
7138  * Finish an asynchronous poll operation that was polled
7139  * with g_file_poll_mountable().
7140  *
7141  * Returns: %TRUE if the operation finished successfully. %FALSE
7142  * otherwise.
7143  *
7144  * Since: 2.22
7145  */
7146 gboolean
7147 g_file_poll_mountable_finish (GFile                      *file,
7148                               GAsyncResult               *result,
7149                               GError                    **error)
7150 {
7151   GFileIface *iface;
7152
7153   g_return_val_if_fail (G_IS_FILE (file), FALSE);
7154   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
7155
7156   if (G_IS_SIMPLE_ASYNC_RESULT (result))
7157     {
7158       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
7159       if (g_simple_async_result_propagate_error (simple, error))
7160         return FALSE;
7161     }
7162
7163   iface = G_FILE_GET_IFACE (file);
7164   return (* iface->poll_mountable_finish) (file, result, error);
7165 }
7166
7167 /**
7168  * g_file_supports_thread_contexts:
7169  * @file: a #GFile.
7170  *
7171  * Checks if @file supports <link
7172  * linkend="g-main-context-push-thread-default-context">thread-default
7173  * contexts</link>. If this returns %FALSE, you cannot perform
7174  * asynchronous operations on @file in a thread that has a
7175  * thread-default context.
7176  *
7177  * Returns: Whether or not @file supports thread-default contexts.
7178  *
7179  * Since: 2.22
7180  */
7181 gboolean
7182 g_file_supports_thread_contexts (GFile *file)
7183 {
7184  GFileIface *iface;
7185
7186  g_return_val_if_fail (G_IS_FILE (file), FALSE);
7187
7188  iface = G_FILE_GET_IFACE (file);
7189  return iface->supports_thread_contexts;
7190 }