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