1    	/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2    	 *
3    	 * Copyright (C) 2012 William Jon McCann <mccann@redhat.com>
4    	 * Copyright (C) 2012 Colin Walters <walters@verbum.org>
5    	 *
6    	 * This library is free software; you can redistribute it and/or
7    	 * modify it under the terms of the GNU Lesser General Public
8    	 * License as published by the Free Software Foundation; either
9    	 * version 2 of the License, or (at your option) any later version.
10   	 *
11   	 * This library is distributed in the hope that it will be useful,
12   	 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   	 * Lesser General Public License for more details.
15   	 *
16   	 * You should have received a copy of the GNU Lesser General Public
17   	 * License along with this library; if not, write to the
18   	 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19   	 * Boston, MA 02111-1307, USA.
20   	 */
21   	
22   	#include "config.h"
23   	
24   	#ifndef _GNU_SOURCE
25   	#define _GNU_SOURCE
26   	#endif
27   	
28   	#include <string.h>
29   	
30   	#define _GSYSTEM_NO_LOCAL_ALLOC
31   	#include "libgsystem.h"
32   	#include "gsystem-glib-compat.h"
33   	#include <glib/gstdio.h>
34   	#include <gio/gunixinputstream.h>
35   	#include <gio/gfiledescriptorbased.h>
36   	#include <gio/gunixoutputstream.h>
37   	#include <glib-unix.h>
38   	#include <limits.h>
39   	#include <dirent.h>
40   	
41   	static int
42   	close_nointr (int fd)
43   	{
44   	  int res;
45   	  /* Note this is NOT actually a retry loop.
46   	   * See: https://bugzilla.gnome.org/show_bug.cgi?id=682819
47   	   */
48   	  res = close (fd);
49   	  /* Just ignore EINTR...on Linux, retrying is wrong. */
50   	  if (res == EINTR)
51   	    res = 0;
52   	  return res;
53   	}
54   	
55   	static void
56   	close_nointr_noerror (int fd)
57   	{
58   	  (void) close_nointr (fd);
59   	}
60   	
61   	static int
62   	open_nointr (const char *path, int flags, mode_t mode)
63   	{
64   	  int res;
65   	  do
(1) Event open_fn: Returning handle opened by function "open(char const *, int, ...)".
(2) Event var_assign: Assigning: "res" = handle returned from "open(path, flags, mode)".
(8) Event loop_begin: Jumped back to beginning of loop
(9) Event overwrite_var: Overwriting handle "res" in "res = open(path, flags, mode)" leaks the handle.
66   	    res = open (path, flags, mode);
(3) Event cond_true: Condition "res != 0", taking true branch
(4) Event cond_true: Condition "*__errno_location() == 4", taking true branch
(5) Event if_fallthrough: Falling through to end of if statement
(6) Event if_end: End of if statement
(7) Event cond_true: Condition "({...})", taking true branch
67   	  while (G_UNLIKELY (res != 0 && errno == EINTR));
68   	  return res;
69   	}
70   	
71   	static int
72   	_open_fd_noatime (const char *path)
73   	{
74   	  int fd;
75   	
76   	#ifdef O_NOATIME
77   	  fd = open_nointr (path, O_RDONLY | O_NOATIME, 0);
78   	  /* Only the owner or superuser may use O_NOATIME; so we may get
79   	   * EPERM.  EINVAL may happen if the kernel is really old...
80   	   */
81   	  if (fd == -1 && (errno == EPERM || errno == EINVAL))
82   	#endif
83   	    fd = open_nointr (path, O_RDONLY, 0);
84   	  
85   	  return fd;
86   	}
87   	
88   	static inline void
89   	_set_error_from_errno (GError **error)
90   	{
91   	  int errsv = errno;
92   	  g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv),
93   	                       g_strerror (errsv));
94   	}
95   	
96   	/**
97   	 * gs_file_read_noatime:
98   	 * @file: a #GFile
99   	 * @cancellable: a #GCancellable
100  	 * @error: a #GError
101  	 *
102  	 * Like g_file_read(), but try to avoid updating the file's
103  	 * access time.  This should be used by background scanning
104  	 * components such as search indexers, antivirus programs, etc.
105  	 *
106  	 * Returns: (transfer full): A new input stream, or %NULL on error
107  	 */
108  	GInputStream *
109  	gs_file_read_noatime (GFile         *file,
110  	                      GCancellable  *cancellable,
111  	                      GError       **error)
112  	{
113  	  const char *path = NULL;
114  	  int fd;
115  	
116  	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
117  	    return NULL;
118  	
119  	  path = gs_file_get_path_cached (file);
120  	  if (path == NULL)
121  	    return NULL;
122  	
123  	  fd = _open_fd_noatime (path);
124  	  if (fd < 0)
125  	    {
126  	      _set_error_from_errno (error);
127  	      return NULL;
128  	    }
129  	
130  	  return g_unix_input_stream_new (fd, TRUE);
131  	}
132  	
133  	/**
134  	 * gs_stream_fstat:
135  	 * @stream: A stream containing a Unix file descriptor
136  	 * @stbuf: Memory location to write stat buffer
137  	 * @cancellable:
138  	 * @error:
139  	 *
140  	 * Some streams created via libgsystem are #GUnixInputStream; these do
141  	 * not support e.g. g_file_input_stream_query_info().  This function
142  	 * allows dropping to the raw unix fstat() call for these types of
143  	 * streams, while still conveniently wrapped with the normal GLib
144  	 * handling of @cancellable and @error.
145  	 */
146  	gboolean
147  	gs_stream_fstat (GFileDescriptorBased *stream,
148  	                 struct stat          *stbuf,
149  	                 GCancellable         *cancellable,
150  	                 GError              **error)
151  	{
152  	  gboolean ret = FALSE;
153  	  int fd;
154  	
155  	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
156  	    goto out;
157  	
158  	  fd = g_file_descriptor_based_get_fd (stream);
159  	
160  	  if (fstat (fd, stbuf) == -1)
161  	    {
162  	      _set_error_from_errno (error);
163  	      goto out;
164  	    }
165  	
166  	  ret = TRUE;
167  	 out:
168  	  return ret;
169  	}
170  	
171  	/**
172  	 * gs_file_map_noatime: (skip)
173  	 * @file: a #GFile
174  	 * @cancellable: a #GCancellable
175  	 * @error: a #GError
176  	 *
177  	 * Like g_mapped_file_new(), but try to avoid updating the file's
178  	 * access time.  This should be used by background scanning
179  	 * components such as search indexers, antivirus programs, etc.
180  	 *
181  	 * Returns: (transfer full): A new mapped file, or %NULL on error
182  	 */
183  	GMappedFile *
184  	gs_file_map_noatime (GFile         *file,
185  	                     GCancellable  *cancellable,
186  	                     GError       **error)
187  	{
188  	  const char *path;
189  	  int fd;
190  	  GMappedFile *ret;
191  	
192  	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
193  	    return NULL;
194  	
195  	  path = gs_file_get_path_cached (file);
196  	  if (path == NULL)
197  	    return NULL;
198  	
199  	  fd = _open_fd_noatime (path);
200  	  if (fd < 0)
201  	    {
202  	      _set_error_from_errno (error);
203  	      return NULL;
204  	    }
205  	  
206  	  ret = g_mapped_file_new_from_fd (fd, FALSE, error);
207  	  close_nointr_noerror (fd); /* Ignore errors - we always want to close */
208  	
209  	  return ret;
210  	}
211  	
212  	#if GLIB_CHECK_VERSION(2,34,0)
213  	/**
214  	 * gs_file_map_readonly:
215  	 * @file: a #GFile
216  	 * @cancellable:
217  	 * @error:
218  	 *
219  	 * Return a #GBytes which references a readonly view of the contents of
220  	 * @file.  This function uses #GMappedFile internally.
221  	 *
222  	 * Returns: (transfer full): a newly referenced #GBytes
223  	 */
224  	GBytes *
225  	gs_file_map_readonly (GFile         *file,
226  	                      GCancellable  *cancellable,
227  	                      GError       **error)
228  	{
229  	  GMappedFile *mfile;
230  	  GBytes *ret;
231  	
232  	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
233  	    return NULL;
234  	
235  	  mfile = g_mapped_file_new (gs_file_get_path_cached (file), FALSE, error);
236  	  if (!mfile)
237  	    return NULL;
238  	
239  	  ret = g_mapped_file_get_bytes (mfile);
240  	  g_mapped_file_unref (mfile);
241  	  return ret;
242  	}
243  	#endif
244  	
245  	/**
246  	 * gs_file_sync_data:
247  	 * @file: a #GFile
248  	 * @cancellable:
249  	 * @error:
250  	 *
251  	 * Wraps the UNIX fdatasync() function, which ensures that the data in
252  	 * @file is on non-volatile storage.
253  	 */
254  	gboolean
255  	gs_file_sync_data (GFile          *file,
256  	                   GCancellable   *cancellable,
257  	                   GError        **error)
258  	{
259  	  gboolean ret = FALSE;
260  	  int res;
261  	  int fd = -1; 
262  	
263  	  fd = _open_fd_noatime (gs_file_get_path_cached (file));
264  	  if (fd < 0)
265  	    {
266  	      _set_error_from_errno (error);
267  	      goto out;
268  	    }
269  	
270  	  do
271  	    res = fdatasync (fd);
272  	  while (G_UNLIKELY (res != 0 && errno == EINTR));
273  	  if (res != 0)
274  	    {
275  	      _set_error_from_errno (error);
276  	      goto out;
277  	    }
278  	
279  	  res = close_nointr (fd);
280  	  if (res != 0)
281  	    {
282  	      _set_error_from_errno (error);
283  	      goto out;
284  	    }
285  	  fd = -1;
286  	  
287  	  ret = TRUE;
288  	 out:
289  	  if (fd != -1)
290  	    close_nointr_noerror (fd);
291  	  return ret;
292  	}
293  	
294  	/**
295  	 * gs_file_create_with_uidgid:
296  	 * @file: Path of file to create
297  	 * @mode: Unix mode
298  	 * @uid: Unix uid
299  	 * @gid: Unix gid
300  	 * @out_stream: (out) (transfer full) (allow-none): Output stream connected to file descriptor
301  	 * @cancellable: a #GCancellable
302  	 * @error: a #GError
303  	 *
304  	 * Create @file exclusively; it must not exist already.  Ensure the
305  	 * returned file has mode @mode and has Unix owners corresponding to
306  	 * the parameters @uid and @gid.
307  	 *
308  	 * The parameter @out_stream if provided, will be filled in with a
309  	 * #GOutputStream connected to the file.
310  	 *
311  	 * Returns: %TRUE on success, %FALSE on error.
312  	 */
313  	gboolean
314  	gs_file_create_with_uidgid (GFile          *file,
315  	                            int             mode,
316  	                            uid_t           uid,
317  	                            gid_t           gid,
318  	                            GOutputStream **out_stream,
319  	                            GCancellable   *cancellable,
320  	                            GError        **error)
321  	{
322  	  gboolean ret = FALSE;
323  	  int fd;
324  	  GOutputStream *ret_stream = NULL;
325  	  static gsize uidgid_cached;
326  	  static uid_t myuid;
327  	  static uid_t mygid;
328  	
329  	  /* Ok yes this is lame, but calling these two over and over shows up
330  	   * in strace.  I like my straces to be clean, shoot me.
331  	   */
332  	  if (g_once_init_enter (&uidgid_cached))
333  	    {
334  	      myuid = getuid ();
335  	      mygid = getgid ();
336  	      g_once_init_leave (&uidgid_cached, 1);
337  	    }
338  	
339  	  fd = open_nointr (gs_file_get_path_cached (file), O_WRONLY | O_CREAT | O_EXCL, mode);
340  	  if (fd < 0)
341  	    {
342  	      _set_error_from_errno (error);
343  	      goto out;
344  	    }
345  	
346  	  if (uid != myuid || gid != mygid)
347  	    {
348  	      if (fchown (fd, uid, gid) < 0)
349  	        {
350  	          _set_error_from_errno (error);
351  	          goto out;
352  	        }
353  	    }
354  	
355  	  if (fchmod (fd, mode) < 0)
356  	    {
357  	      _set_error_from_errno (error);
358  	      goto out;
359  	    }
360  	  
361  	  ret_stream = g_unix_output_stream_new (fd, TRUE);
362  	  
363  	  ret = TRUE;
364  	  gs_transfer_out_value (out_stream, &ret_stream);
365  	 out:
366  	  g_clear_object (&ret_stream);
367  	  return ret;
368  	}
369  	
370  	/**
371  	 * gs_file_create:
372  	 * @file: Path to non-existent file
373  	 * @mode: Unix access permissions
374  	 * @out_stream: (out) (transfer full) (allow-none): Newly created output, or %NULL
375  	 * @cancellable: a #GCancellable
376  	 * @error: a #GError
377  	 *
378  	 * Like g_file_create(), except this function allows specifying the
379  	 * access mode.  This allows atomically creating private files.
380  	 */
381  	gboolean
382  	gs_file_create (GFile          *file,
383  	                int             mode,
384  	                GOutputStream **out_stream,
385  	                GCancellable   *cancellable,
386  	                GError        **error)
387  	{
388  	  gboolean ret = FALSE;
389  	  int fd;
390  	  GOutputStream *ret_stream = NULL;
391  	
392  	  fd = open_nointr (gs_file_get_path_cached (file), O_WRONLY | O_CREAT | O_EXCL, mode);
393  	  if (fd < 0)
394  	    {
395  	      _set_error_from_errno (error);
396  	      goto out;
397  	    }
398  	
399  	  if (fchmod (fd, mode) < 0)
400  	    {
401  	      _set_error_from_errno (error);
402  	      goto out;
403  	    }
404  	  
405  	  ret_stream = g_unix_output_stream_new (fd, TRUE);
406  	  
407  	  ret = TRUE;
408  	  gs_transfer_out_value (out_stream, &ret_stream);
409  	 out:
410  	  g_clear_object (&ret_stream);
411  	  return ret;
412  	}
413  	
414  	static const char *
415  	get_default_tmp_prefix (void)
416  	{
417  	  static char *tmpprefix = NULL;
418  	
419  	  if (g_once_init_enter (&tmpprefix))
420  	    {
421  	      const char *prgname = g_get_prgname ();
422  	      const char *p;
423  	      char *prefix;
424  	
425  	      p = strrchr (prgname, '/');
426  	      if (p)
427  	        prgname = p + 1;
428  	
429  	      prefix = g_strdup_printf ("tmp-%s%u-", prgname, getuid ());
430  	      
431  	      g_once_init_leave (&tmpprefix, prefix);
432  	    }
433  	
434  	  return tmpprefix;
435  	}
436  	
437  	/**
438  	 * gsystem_fileutil_gen_tmp_name:
439  	 * @prefix: (allow-none): String prepended to the result
440  	 * @suffix: (allow-none): String suffixed to the result
441  	 *
442  	 * Generate a name suitable for use as a temporary file.  This
443  	 * function does no I/O; it is not guaranteed that a file with that
444  	 * name does not exist.
445  	 */
446  	char *
447  	gsystem_fileutil_gen_tmp_name (const char *prefix,
448  	                               const char *suffix)
449  	{
450  	  static const char table[] = "ABCEDEFGHIJKLMNOPQRSTUVWXYZabcedefghijklmnopqrstuvwxyz0123456789";
451  	  GString *str = g_string_new ("");
452  	  guint i;
453  	
454  	  if (!prefix)
455  	    prefix = get_default_tmp_prefix ();
456  	  if (!suffix)
457  	    suffix = "tmp";
458  	
459  	  g_string_append (str, prefix);
460  	  for (i = 0; i < 8; i++)
461  	    {
462  	      int offset = g_random_int_range (0, sizeof (table) - 1);
463  	      g_string_append_c (str, (guint8)table[offset]);
464  	    }
465  	  g_string_append_c (str, '.');
466  	  g_string_append (str, suffix);
467  	
468  	  return g_string_free (str, FALSE);
469  	}
470  	
471  	/**
472  	 * gs_file_open_in_tmpdir:
473  	 * @tmpdir: Directory to place temporary file
474  	 * @mode: Default mode (will be affected by umask)
475  	 * @out_file: (out) (transfer full): Newly created file path
476  	 * @out_stream: (out) (transfer full) (allow-none): Newly created output stream
477  	 * @cancellable:
478  	 * @error:
479  	 *
480  	 * Like g_file_open_tmp(), except the file will be created in the
481  	 * provided @tmpdir, and allows specification of the Unix @mode, which
482  	 * means private files may be created.  Return values will be stored
483  	 * in @out_file, and optionally @out_stream.
484  	 */
485  	gboolean
486  	gs_file_open_in_tmpdir (GFile             *tmpdir,
487  	                        int                mode,
488  	                        GFile            **out_file,
489  	                        GOutputStream    **out_stream,
490  	                        GCancellable      *cancellable,
491  	                        GError           **error)
492  	{
493  	  gboolean ret = FALSE;
494  	  const int max_attempts = 128;
495  	  guint i;
496  	  DIR *d = NULL;
497  	  int dfd = -1;
498  	  char *tmp_name = NULL;
499  	  int fd;
500  	
501  	  d = opendir (gs_file_get_path_cached (tmpdir));
502  	  if (!d)
503  	    {
504  	      _set_error_from_errno (error);
505  	      goto out;
506  	    }
507  	  dfd = dirfd (d);
508  	  
509  	  /* 128 attempts seems reasonable... */
510  	  for (i = 0; i < max_attempts; i++)
511  	    {
512  	      g_free (tmp_name);
513  	      tmp_name = gsystem_fileutil_gen_tmp_name (NULL, NULL);
514  	
515  	      do
516  	        fd = openat (dfd, tmp_name, O_WRONLY | O_CREAT | O_EXCL, mode);
517  	      while (fd == -1 && errno == EINTR);
518  	      if (fd < 0 && errno != EEXIST)
519  	        {
520  	          _set_error_from_errno (error);
521  	          goto out;
522  	        }
523  	      break;
524  	    }
525  	  if (i == max_attempts)
526  	    {
527  	      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
528  	                   "Exhausted attempts to open temporary file");
529  	      goto out;
530  	    }
531  	
532  	  ret = TRUE;
533  	  *out_file = g_file_get_child (tmpdir, tmp_name);
534  	  if (out_stream)
535  	    *out_stream = g_unix_output_stream_new (fd, TRUE);
536  	 out:
537  	  if (d) (void) closedir (d);
538  	  return ret;
539  	}
540  	
541  	static gboolean
542  	linkcopy_internal_attempt (GFile          *src,
543  	                          GFile          *dest,
544  	                          GFile          *dest_parent,
545  	                          GFileCopyFlags  flags,
546  	                          gboolean        sync_data,
547  	                          gboolean        enable_guestfs_fuse_workaround,
548  	                          gboolean       *out_try_again,
549  	                          GCancellable   *cancellable,
550  	                          GError        **error)
551  	{
552  	  gboolean ret = FALSE;
553  	  int res;
554  	  char *tmp_name = NULL;
555  	  GFile *tmp_dest = NULL;
556  	
557  	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
558  	    goto out;
559  	
560  	  tmp_name = gsystem_fileutil_gen_tmp_name (NULL, NULL);
561  	  tmp_dest = g_file_get_child (dest_parent, tmp_name);
562  	
563  	  res = link (gs_file_get_path_cached (src), gs_file_get_path_cached (tmp_dest));
564  	  if (res == -1)
565  	    {
566  	      if (errno == EEXIST)
567  	        {
568  	          /* Nothing, fall through */
569  	          *out_try_again = TRUE;
570  	          ret = TRUE;
571  	          goto out;
572  	        }
573  	      else if (errno == EXDEV || errno == EMLINK || errno == EPERM
574  	               || (enable_guestfs_fuse_workaround && errno == ENOENT))
575  	        {
576  	          if (!g_file_copy (src, tmp_dest, flags,
577  	                            cancellable, NULL, NULL, error))
578  	            goto out;
579  	        }
580  	      else
581  	        {
582  	          _set_error_from_errno (error);
583  	          goto out;
584  	        }
585  	    }
586  	      
587  	  if (sync_data)
588  	    {
589  	      /* Now, we need to fdatasync */
590  	      if (!gs_file_sync_data (tmp_dest, cancellable, error))
591  	        goto out;
592  	    }
593  	
594  	  if (!gs_file_rename (tmp_dest, dest, cancellable, error))
595  	    goto out;
596  	
597  	  ret = TRUE;
598  	  *out_try_again = FALSE;
599  	 out:
600  	  g_clear_pointer (&tmp_name, g_free);
601  	  g_clear_object (&tmp_dest);
602  	  return ret;
603  	}
604  	
605  	static gboolean
606  	linkcopy_internal (GFile          *src,
607  	                   GFile          *dest,
608  	                   GFileCopyFlags  flags,
609  	                   gboolean        sync_data,
610  	                   GCancellable   *cancellable,
611  	                   GError        **error)
612  	{
613  	  gboolean ret = FALSE;
614  	  gboolean dest_exists;
615  	  int i;
616  	  gboolean enable_guestfs_fuse_workaround;
617  	  struct stat src_stat;
618  	  struct stat dest_stat;
619  	  GFile *dest_parent = NULL;
620  	
621  	  flags |= G_FILE_COPY_NOFOLLOW_SYMLINKS;
622  	
623  	  g_return_val_if_fail ((flags & (G_FILE_COPY_BACKUP | G_FILE_COPY_TARGET_DEFAULT_PERMS)) == 0, FALSE);
624  	
625  	  dest_parent = g_file_get_parent (dest);
626  	
627  	  if (lstat (gs_file_get_path_cached (src), &src_stat) == -1)
628  	    {
629  	      int errsv = errno;
630  	      g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno),
631  	                           g_strerror (errsv));
632  	      goto out;
633  	    }
634  	
635  	  if (lstat (gs_file_get_path_cached (dest), &dest_stat) == -1)
636  	    dest_exists = FALSE;
637  	  else
638  	    dest_exists = TRUE;
639  	  
640  	  if (((flags & G_FILE_COPY_OVERWRITE) == 0) && dest_exists)
641  	    {
642  	      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
643  	                           "File exists");
644  	      goto out;
645  	    }
646  	
647  	  /* Work around the behavior of link() where it's a no-op if src and
648  	   * dest are the same.
649  	   */
650  	  if (dest_exists &&
651  	      src_stat.st_dev == dest_stat.st_dev &&
652  	      src_stat.st_ino == dest_stat.st_ino)
653  	    {
654  	      ret = TRUE;
655  	      goto out;
656  	    }
657  	
658  	  enable_guestfs_fuse_workaround = getenv ("LIBGSYSTEM_ENABLE_GUESTFS_FUSE_WORKAROUND") != NULL;
659  	
660  	  /* 128 attempts seems reasonable... */
661  	  for (i = 0; i < 128; i++)
662  	    {
663  	      gboolean tryagain = FALSE;
664  	
665  	      if (!linkcopy_internal_attempt (src, dest, dest_parent,
666  	                                      flags, sync_data,
667  	                                      enable_guestfs_fuse_workaround,
668  	                                      &tryagain,
669  	                                      cancellable, error))
670  	        goto out;
671  	
672  	      if (!tryagain)
673  	        break;
674  	    }
675  	
676  	  ret = TRUE;
677  	 out:
678  	  g_clear_object (&dest_parent);
679  	  return ret;
680  	
681  	}
682  	
683  	/**
684  	 * gs_file_linkcopy:
685  	 * @src: Source file
686  	 * @dest: Destination file
687  	 * @flags: flags
688  	 * @cancellable:
689  	 * @error:
690  	 *
691  	 * First tries to use the UNIX link() call, but if the files are on
692  	 * separate devices, fall back to copying via g_file_copy().
693  	 *
694  	 * The given @flags have different semantics than those documented
695  	 * when hardlinking is used.  Specifically, both
696  	 * #G_FILE_COPY_TARGET_DEFAULT_PERMS and #G_FILE_COPY_BACKUP are not
697  	 * supported.  #G_FILE_COPY_NOFOLLOW_SYMLINKS treated as if it was
698  	 * always given - if you want to follow symbolic links, you will need
699  	 * to resolve them manually.
700  	 *
701  	 * Beware - do not use this function if @src may be modified, and it's
702  	 * undesirable for the changes to also be reflected in @dest.  The
703  	 * best use of this function is in the case where @src and @dest are
704  	 * read-only, or where @src is a temporary file, and you want to put
705  	 * it in the final place.
706  	 */
707  	gboolean
708  	gs_file_linkcopy (GFile          *src,
709  	                  GFile          *dest,
710  	                  GFileCopyFlags  flags,
711  	                  GCancellable   *cancellable,
712  	                  GError        **error)
713  	{
714  	  return linkcopy_internal (src, dest, flags, FALSE, cancellable, error);
715  	}
716  	
717  	/**
718  	 * gs_file_linkcopy_sync_data:
719  	 * @src: Source file
720  	 * @dest: Destination file
721  	 * @flags: flags
722  	 * @cancellable:
723  	 * @error:
724  	 *
725  	 * This function is similar to gs_file_linkcopy(), except it also uses
726  	 * gs_file_sync_data() to ensure that @dest is in stable storage
727  	 * before it is moved into place.
728  	 */
729  	gboolean
730  	gs_file_linkcopy_sync_data (GFile          *src,
731  	                            GFile          *dest,
732  	                            GFileCopyFlags  flags,
733  	                            GCancellable   *cancellable,
734  	                            GError        **error)
735  	{
736  	  return linkcopy_internal (src, dest, flags, TRUE, cancellable, error);
737  	}
738  	
739  	/**
740  	 * gs_file_get_path_cached:
741  	 *
742  	 * Like g_file_get_path(), but returns a constant copy so callers
743  	 * don't need to free the result.
744  	 */
745  	const char *
746  	gs_file_get_path_cached (GFile *file)
747  	{
748  	  const char *path;
749  	  static GQuark _file_path_quark = 0;
750  	
751  	  if (G_UNLIKELY (_file_path_quark) == 0)
752  	    _file_path_quark = g_quark_from_static_string ("gsystem-file-path");
753  	
754  	  path = g_object_get_qdata ((GObject*)file, _file_path_quark);
755  	  if (!path)
756  	    {
757  	      path = g_file_get_path (file);
758  	      g_assert (path != NULL);
759  	      g_object_set_qdata_full ((GObject*)file, _file_path_quark, (char*)path, (GDestroyNotify)g_free);
760  	    }
761  	  return path;
762  	}
763  	
764  	/**
765  	 * gs_file_get_basename_cached:
766  	 *
767  	 * Like g_file_get_basename(), but returns a constant copy so callers
768  	 * don't need to free the result.
769  	 */
770  	const char *
771  	gs_file_get_basename_cached (GFile *file)
772  	{
773  	  const char *name;
774  	  static GQuark _file_name_quark = 0;
775  	
776  	  if (G_UNLIKELY (_file_name_quark) == 0)
777  	    _file_name_quark = g_quark_from_static_string ("gsystem-file-name");
778  	
779  	  name = g_object_get_qdata ((GObject*)file, _file_name_quark);
780  	  if (!name)
781  	    {
782  	      name = g_file_get_basename (file);
783  	      g_object_set_qdata_full ((GObject*)file, _file_name_quark, (char*)name, (GDestroyNotify)g_free);
784  	    }
785  	  return name;
786  	}
787  	
788  	/**
789  	 * gs_file_enumerator_iterate:
790  	 * @direnum: an open #GFileEnumerator
791  	 * @out_info: (out) (transfer none) (allow-none): Output location for the next #GFileInfo
792  	 * @out_child: (out) (transfer none) (allow-none): Output location for the next #GFile, or %NULL
793  	 * @cancellable: a #GCancellable
794  	 * @error: a #GError
795  	 *
796  	 * This is a version of g_file_enumerator_next_file() that's easier to
797  	 * use correctly from C programs.  With g_file_enumerator_next_file(),
798  	 * the gboolean return value signifies "end of iteration or error", which
799  	 * requires allocation of a temporary #GError.
800  	 *
801  	 * In contrast, with this function, a %FALSE return from
802  	 * gs_file_enumerator_iterate() <emphasis>always</emphasis> means
803  	 * "error".  End of iteration is signaled by @out_info being %NULL.
804  	 *
805  	 * Another crucial difference is that the references for @out_info and
806  	 * @out_child are owned by @direnum (they are cached as hidden
807  	 * properties).  You must not unref them in your own code.  This makes
808  	 * memory management significantly easier for C code in combination
809  	 * with loops.
810  	 *
811  	 * Finally, this function optionally allows retrieving a #GFile as
812  	 * well.
813  	 *
814  	 * The code pattern for correctly using gs_file_enumerator_iterate() from C
815  	 * is:
816  	 *
817  	 * |[
818  	 * direnum = g_file_enumerate_children (file, ...);
819  	 * while (TRUE)
820  	 *   {
821  	 *     GFileInfo *info;
822  	 *     if (!gs_file_enumerator_iterate (direnum, &info, NULL, cancellable, error))
823  	 *       goto out;
824  	 *     if (!info)
825  	 *       break;
826  	 *     ... do stuff with "info"; do not unref it! ...
827  	 *   }
828  	 * 
829  	 * out:
830  	 *   g_object_unref (direnum); // Note: frees the last @info
831  	 * ]|
832  	 */
833  	gboolean
834  	gs_file_enumerator_iterate (GFileEnumerator  *direnum,
835  	                            GFileInfo       **out_info,
836  	                            GFile           **out_child,
837  	                            GCancellable     *cancellable,
838  	                            GError          **error)
839  	{
840  	  gboolean ret = FALSE;
841  	  GError *temp_error = NULL;
842  	
843  	  static GQuark cached_info_quark;
844  	  static GQuark cached_child_quark;
845  	  static gsize quarks_initialized;
846  	
847  	  g_return_val_if_fail (direnum != NULL, FALSE);
848  	  g_return_val_if_fail (out_info != NULL, FALSE);
849  	
850  	  if (g_once_init_enter (&quarks_initialized))
851  	    {
852  	      cached_info_quark = g_quark_from_static_string ("gsystem-cached-info");
853  	      cached_child_quark = g_quark_from_static_string ("gsystem-cached-child");
854  	      g_once_init_leave (&quarks_initialized, 1);
855  	    }
856  	
857  	  
858  	  *out_info = g_file_enumerator_next_file (direnum, cancellable, &temp_error);
859  	  if (out_child)
860  	    *out_child = NULL;
861  	  if (temp_error != NULL)
862  	    {
863  	      g_propagate_error (error, temp_error);
864  	      goto out;
865  	    }
866  	  else if (*out_info != NULL)
867  	    {
868  	      g_object_set_qdata_full ((GObject*)direnum, cached_info_quark, *out_info, (GDestroyNotify)g_object_unref);
869  	      if (out_child != NULL)
870  	        {
871  	          const char *name = g_file_info_get_name (*out_info);
872  	          *out_child = g_file_get_child (g_file_enumerator_get_container (direnum), name);
873  	          g_object_set_qdata_full ((GObject*)direnum, cached_child_quark, *out_child, (GDestroyNotify)g_object_unref);
874  	        }
875  	    }
876  	
877  	  ret = TRUE;
878  	 out:
879  	  return ret;
880  	}
881  	
882  	/**
883  	 * gs_file_rename:
884  	 * @from: Current path
885  	 * @to: New path
886  	 * @cancellable: a #GCancellable
887  	 * @error: a #GError
888  	 *
889  	 * This function wraps the raw Unix function rename().
890  	 *
891  	 * Returns: %TRUE on success, %FALSE on error
892  	 */
893  	gboolean
894  	gs_file_rename (GFile          *from,
895  	                GFile          *to,
896  	                GCancellable   *cancellable,
897  	                GError        **error)
898  	{
899  	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
900  	    return FALSE;
901  	
902  	  if (rename (gs_file_get_path_cached (from),
903  	              gs_file_get_path_cached (to)) < 0)
904  	    {
905  	      _set_error_from_errno (error);
906  	      return FALSE;
907  	    }
908  	  return TRUE;
909  	}
910  	
911  	/**
912  	 * gs_file_unlink:
913  	 * @path: Path to file
914  	 * @cancellable: a #GCancellable
915  	 * @error: a #GError
916  	 *
917  	 * Like g_file_delete(), except this function does not follow Unix
918  	 * symbolic links, and will delete a symbolic link even if it's
919  	 * pointing to a nonexistent file.  In other words, this function
920  	 * merely wraps the raw Unix function unlink().
921  	 *
922  	 * Returns: %TRUE on success, %FALSE on error
923  	 */
924  	gboolean
925  	gs_file_unlink (GFile          *path,
926  	                GCancellable   *cancellable,
927  	                GError        **error)
928  	{
929  	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
930  	    return FALSE;
931  	
932  	  if (unlink (gs_file_get_path_cached (path)) < 0)
933  	    {
934  	      _set_error_from_errno (error);
935  	      return FALSE;
936  	    }
937  	  return TRUE;
938  	}
939  	
940  	/**
941  	 * gs_file_chown:
942  	 * @path: Path to file
943  	 * @owner: UNIX owner
944  	 * @group: UNIX group
945  	 * @cancellable: a #GCancellable
946  	 * @error: a #GError
947  	 *
948  	 * Merely wraps UNIX chown().
949  	 *
950  	 * Returns: %TRUE on success, %FALSE on error
951  	 */
952  	gboolean
953  	gs_file_chown (GFile          *path,
954  	               guint32         owner,
955  	               guint32         group,
956  	               GCancellable   *cancellable,
957  	               GError        **error)
958  	{
959  	  gboolean ret = FALSE;
960  	  int res;
961  	
962  	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
963  	    return FALSE;
964  	
965  	  do
966  	    res = chown (gs_file_get_path_cached (path), owner, group);
967  	  while (G_UNLIKELY (res != 0 && errno == EINTR));
968  	
969  	  if (res < 0)
970  	    {
971  	      _set_error_from_errno (error);
972  	      goto out;
973  	    }
974  	
975  	  ret = TRUE;
976  	 out:
977  	  return ret;
978  	}
979  	
980  	/**
981  	 * gs_file_chmod:
982  	 * @path: Path to file
983  	 * @mode: UNIX mode
984  	 * @cancellable: a #GCancellable
985  	 * @error: a #GError
986  	 *
987  	 * Merely wraps UNIX chmod().
988  	 *
989  	 * Returns: %TRUE on success, %FALSE on error
990  	 */
991  	gboolean
992  	gs_file_chmod (GFile          *path,
993  	               guint           mode,
994  	               GCancellable   *cancellable,
995  	               GError        **error)
996  	{
997  	  gboolean ret = FALSE;
998  	  int res;
999  	
1000 	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1001 	    return FALSE;
1002 	
1003 	  do
1004 	    res = chmod (gs_file_get_path_cached (path), mode);
1005 	  while (G_UNLIKELY (res != 0 && errno == EINTR));
1006 	
1007 	  if (res < 0)
1008 	    {
1009 	      _set_error_from_errno (error);
1010 	      goto out;
1011 	    }
1012 	
1013 	  ret = TRUE;
1014 	 out:
1015 	  return ret;
1016 	}
1017 	
1018 	/**
1019 	 * gs_file_ensure_directory:
1020 	 * @dir: Path to create as directory
1021 	 * @with_parents: Also create parent directories
1022 	 * @cancellable: a #GCancellable
1023 	 * @error: a #GError
1024 	 *
1025 	 * Like g_file_make_directory(), except does not throw an error if the
1026 	 * directory already exists.
1027 	 */
1028 	gboolean
1029 	gs_file_ensure_directory (GFile         *dir,
1030 	                          gboolean       with_parents, 
1031 	                          GCancellable  *cancellable,
1032 	                          GError       **error)
1033 	{
1034 	  gboolean ret = FALSE;
1035 	  GError *temp_error = NULL;
1036 	  GFile *parent = NULL;
1037 	
1038 	  if (!g_file_make_directory (dir, cancellable, &temp_error))
1039 	    {
1040 	      if (with_parents &&
1041 	          g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
1042 	        {
1043 	          g_clear_error (&temp_error);
1044 	
1045 	          parent = g_file_get_parent (dir);
1046 	          if (parent)
1047 	            {
1048 	              if (!gs_file_ensure_directory (parent, TRUE, cancellable, error))
1049 	                goto out;
1050 	            }
1051 	          if (!gs_file_ensure_directory (dir, FALSE, cancellable, error))
1052 	            goto out;
1053 	        }
1054 	      else if (!g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
1055 	        {
1056 	          g_propagate_error (error, temp_error);
1057 	          goto out;
1058 	        }
1059 	      else
1060 	        g_clear_error (&temp_error);
1061 	    }
1062 	
1063 	  ret = TRUE;
1064 	 out:
1065 	  g_clear_object (&parent);
1066 	  return ret;
1067 	}
1068 	
1069 	/**
1070 	 * gs_file_ensure_directory_mode:
1071 	 * @dir: Path to create as directory
1072 	 * @mode: Create directory with these permissions
1073 	 * @cancellable: a #GCancellable
1074 	 * @error: a #GError
1075 	 *
1076 	 * Wraps UNIX mkdir() function with support for @cancellable, and
1077 	 * uses @error instead of errno.
1078 	 */
1079 	gboolean
1080 	gs_file_ensure_directory_mode (GFile         *dir,
1081 	                               guint          mode,
1082 	                               GCancellable  *cancellable,
1083 	                               GError       **error)
1084 	{
1085 	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
1086 	    return FALSE;
1087 	
1088 	  if (mkdir (gs_file_get_path_cached (dir), mode) == -1 && errno != EEXIST)
1089 	    {
1090 	      _set_error_from_errno (error);
1091 	      return FALSE;
1092 	    }
1093 	  return TRUE;
1094 	}
1095 	
1096 	/**
1097 	 * gs_file_load_contents_utf8:
1098 	 * @file: Path to file whose contents must be UTF-8
1099 	 * @cancellable:
1100 	 * @error:
1101 	 *
1102 	 * Like g_file_load_contents(), except validates the contents are
1103 	 * UTF-8.
1104 	 */
1105 	gchar *
1106 	gs_file_load_contents_utf8 (GFile         *file,
1107 	                            GCancellable  *cancellable,
1108 	                            GError       **error)
1109 	{
1110 	  gboolean ret = FALSE;
1111 	  gsize len;
1112 	  char *ret_contents = NULL;
1113 	
1114 	  if (!g_file_load_contents (file, cancellable, &ret_contents, &len,
1115 	                             NULL, error))
1116 	    goto out;
1117 	  if (!g_utf8_validate (ret_contents, len, NULL))
1118 	    {
1119 	      g_set_error (error,
1120 	                   G_IO_ERROR,
1121 	                   G_IO_ERROR_INVALID_DATA,
1122 	                   "Invalid UTF-8");
1123 	      goto out;
1124 	    }
1125 	
1126 	  ret = TRUE;
1127 	 out:
1128 	  if (!ret)
1129 	    {
1130 	      g_free (ret_contents);
1131 	      return NULL;
1132 	    }
1133 	  return ret_contents;
1134 	}
1135 	
1136 	static int
1137 	path_common_directory (char *one,
1138 	                       char *two)
1139 	{
1140 	  int dir_index = 0;
1141 	  int i = 0;
1142 	
1143 	  while (*one && *two)
1144 	    {
1145 	      if (*one != *two)
1146 	        break;
1147 	      if (*one == '/')
1148 	        dir_index = i + 1;
1149 	
1150 	      one++;
1151 	      two++;
1152 	      i++;
1153 	    }
1154 	
1155 	  return dir_index;
1156 	}
1157 	
1158 	/**
1159 	 * gs_file_get_relpath:
1160 	 * @one: The first #GFile
1161 	 * @two: The second #GFile
1162 	 *
1163 	 * Like gs_file_get_relative_path(), but does not mandate that
1164 	 * the two files have any parent in common. This function will
1165 	 * instead insert "../" where appropriate.
1166 	 *
1167 	 * Returns: (transfer full): The relative path between the two.
1168 	 */
1169 	gchar *
1170 	gs_file_get_relpath (GFile *one,
1171 	                     GFile *two)
1172 	{
1173 	  gchar *simple_path;
1174 	  gchar *one_path, *one_suffix;
1175 	  gchar *two_path, *two_suffix;
1176 	  GString *path;
1177 	  int i;
1178 	
1179 	  simple_path = g_file_get_relative_path (one, two);
1180 	  if (simple_path)
1181 	    return simple_path;
1182 	
1183 	  one_path = g_file_get_path (one);
1184 	  two_path = g_file_get_path (two);
1185 	
1186 	  i = path_common_directory (one_path, two_path);
1187 	  one_suffix = one_path + i;
1188 	  two_suffix = two_path + i;
1189 	
1190 	  path = g_string_new ("");
1191 	
1192 	  /* For every leftover path segment one has, append "../" so
1193 	   * that we reach the same directory. */
1194 	  while (*one_suffix)
1195 	    {
1196 	      g_string_append (path, "../");
1197 	      one_suffix = strchr (one_suffix, '/');
1198 	      if (one_suffix == NULL)
1199 	        break;
1200 	      one_suffix++;
1201 	    }
1202 	
1203 	  /* And now append the leftover stuff on two's side. */
1204 	  g_string_append (path, two_suffix);
1205 	
1206 	  g_free (one_path);
1207 	  g_free (two_path);
1208 	
1209 	  return g_string_free (path, FALSE);
1210 	}
1211 	
1212 	/**
1213 	 * gs_file_realpath:
1214 	 * @file: A #GFile
1215 	 *
1216 	 * Return a #GFile that contains the same path with symlinks
1217 	 * followed. That is, it's a #GFile whose path is the result
1218 	 * of calling realpath() on @file.
1219 	 *
1220 	 * Returns: (allow-none) (transfer full): A new #GFile or %NULL if @file is invalid
1221 	 */
1222 	GFile *
1223 	gs_file_realpath (GFile *file)
1224 	{
1225 	  gchar *path;
1226 	  gchar path_real[PATH_MAX];
1227 	
1228 	  path = g_file_get_path (file);
1229 	
1230 	  if (realpath ((const char *) path, path_real) == NULL)
1231 	    {
1232 	      g_free (path);
1233 	      return NULL;
1234 	    }
1235 	
1236 	  g_free (path);
1237 	  return g_file_new_for_path (path_real);
1238 	}
1239