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