Take a va_list*, not a va_list, to avoid compiler warnings about
[platform/upstream/glib.git] / glib / gfileutils.c
1 /* gfileutils.c - File utility functions
2  *
3  *  Copyright 2000 Red Hat, Inc.
4  *
5  * GLib is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * GLib is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with GLib; see the file COPYING.LIB.  If not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  *   Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22
23 #include "glib.h"
24
25 #include <sys/stat.h>
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #ifndef G_OS_WIN32
37 #include <sys/wait.h>
38 #endif
39 #include <fcntl.h>
40 #include <stdlib.h>
41
42 #ifdef G_OS_WIN32
43 #include <windows.h>
44 #include <io.h>
45 #endif /* G_OS_WIN32 */
46
47 #ifndef S_ISLNK
48 #define S_ISLNK(x) 0
49 #endif
50
51 #ifndef O_BINARY
52 #define O_BINARY 0
53 #endif
54
55 #include "gstdio.h"
56 #include "glibintl.h"
57
58 #include "galias.h"
59
60 /**
61  * g_mkdir_with_parents:
62  * @pathname: a pathname in the GLib file name encoding
63  * @mode: permissions to use for newly created directories
64  *
65  * Create a directory if it doesn't already exist. Create intermediate
66  * parent directories as needed, too.
67  *
68  * Returns: 0 if the directory already exists, or was successfully
69  * created. Returns -1 if an error occurred, with errno set.
70  *
71  * Since: 2.8
72  */
73 int
74 g_mkdir_with_parents (const gchar *pathname,
75                       int          mode)
76 {
77   gchar *fn, *p;
78
79   if (pathname == NULL || *pathname == '\0')
80     {
81       errno = EINVAL;
82       return -1;
83     }
84
85   fn = g_strdup (pathname);
86
87   if (g_path_is_absolute (fn))
88     p = (gchar *) g_path_skip_root (fn);
89   else
90     p = fn;
91
92   do
93     {
94       while (*p && !G_IS_DIR_SEPARATOR (*p))
95         p++;
96       
97       if (!*p)
98         p = NULL;
99       else
100         *p = '\0';
101       
102       if (!g_file_test (fn, G_FILE_TEST_EXISTS))
103         {
104           if (g_mkdir (fn, mode) == -1)
105             {
106               int errno_save = errno;
107               g_free (fn);
108               errno = errno_save;
109               return -1;
110             }
111         }
112       else if (!g_file_test (fn, G_FILE_TEST_IS_DIR))
113         {
114           g_free (fn);
115           errno = ENOTDIR;
116           return -1;
117         }
118       if (p)
119         {
120           *p++ = G_DIR_SEPARATOR;
121           while (*p && G_IS_DIR_SEPARATOR (*p))
122             p++;
123         }
124     }
125   while (p);
126
127   g_free (fn);
128
129   return 0;
130 }
131
132 /**
133  * g_file_test:
134  * @filename: a filename to test in the GLib file name encoding
135  * @test: bitfield of #GFileTest flags
136  * 
137  * Returns %TRUE if any of the tests in the bitfield @test are
138  * %TRUE. For example, <literal>(G_FILE_TEST_EXISTS | 
139  * G_FILE_TEST_IS_DIR)</literal> will return %TRUE if the file exists; 
140  * the check whether it's a directory doesn't matter since the existence 
141  * test is %TRUE. With the current set of available tests, there's no point
142  * passing in more than one test at a time.
143  * 
144  * Apart from %G_FILE_TEST_IS_SYMLINK all tests follow symbolic links,
145  * so for a symbolic link to a regular file g_file_test() will return
146  * %TRUE for both %G_FILE_TEST_IS_SYMLINK and %G_FILE_TEST_IS_REGULAR.
147  *
148  * Note, that for a dangling symbolic link g_file_test() will return
149  * %TRUE for %G_FILE_TEST_IS_SYMLINK and %FALSE for all other flags.
150  *
151  * You should never use g_file_test() to test whether it is safe
152  * to perform an operation, because there is always the possibility
153  * of the condition changing before you actually perform the operation.
154  * For example, you might think you could use %G_FILE_TEST_IS_SYMLINK
155  * to know whether it is is safe to write to a file without being
156  * tricked into writing into a different location. It doesn't work!
157  *
158  * <informalexample><programlisting>
159  * /&ast; DON'T DO THIS &ast;/
160  *  if (!g_file_test (filename, G_FILE_TEST_IS_SYMLINK)) {
161  *    fd = g_open (filename, O_WRONLY);
162  *    /&ast; write to fd &ast;/
163  *  }
164  * </programlisting></informalexample>
165  *
166  * Another thing to note is that %G_FILE_TEST_EXISTS and
167  * %G_FILE_TEST_IS_EXECUTABLE are implemented using the access()
168  * system call. This usually doesn't matter, but if your program
169  * is setuid or setgid it means that these tests will give you
170  * the answer for the real user ID and group ID, rather than the
171  * effective user ID and group ID.
172  *
173  * On Windows, there are no symlinks, so testing for
174  * %G_FILE_TEST_IS_SYMLINK will always return %FALSE. Testing for
175  * %G_FILE_TEST_IS_EXECUTABLE will just check that the file exists and
176  * its name indicates that it is executable, checking for well-known
177  * extensions and those listed in the %PATHEXT environment variable.
178  *
179  * Return value: whether a test was %TRUE
180  **/
181 gboolean
182 g_file_test (const gchar *filename,
183              GFileTest    test)
184 {
185 #ifdef G_OS_WIN32
186 /* stuff missing in std vc6 api */
187 #  ifndef INVALID_FILE_ATTRIBUTES
188 #    define INVALID_FILE_ATTRIBUTES -1
189 #  endif
190 #  ifndef FILE_ATTRIBUTE_DEVICE
191 #    define FILE_ATTRIBUTE_DEVICE 64
192 #  endif
193   int attributes;
194
195   if (G_WIN32_HAVE_WIDECHAR_API ())
196     {
197       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
198
199       if (wfilename == NULL)
200         return FALSE;
201
202       attributes = GetFileAttributesW (wfilename);
203
204       g_free (wfilename);
205     }
206   else
207     {
208       gchar *cpfilename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
209
210       if (cpfilename == NULL)
211         return FALSE;
212       
213       attributes = GetFileAttributesA (cpfilename);
214       
215       g_free (cpfilename);
216     }
217
218   if (attributes == INVALID_FILE_ATTRIBUTES)
219     return FALSE;
220
221   if (test & G_FILE_TEST_EXISTS)
222     return TRUE;
223       
224   if (test & G_FILE_TEST_IS_REGULAR)
225     return (attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0;
226
227   if (test & G_FILE_TEST_IS_DIR)
228     return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
229
230   if (test & G_FILE_TEST_IS_EXECUTABLE)
231     {
232       const gchar *lastdot = strrchr (filename, '.');
233       const gchar *pathext = NULL, *p;
234       int extlen;
235
236       if (lastdot == NULL)
237         return FALSE;
238
239       if (stricmp (lastdot, ".exe") == 0 ||
240           stricmp (lastdot, ".cmd") == 0 ||
241           stricmp (lastdot, ".bat") == 0 ||
242           stricmp (lastdot, ".com") == 0)
243         return TRUE;
244
245       /* Check if it is one of the types listed in %PATHEXT% */
246
247       pathext = g_getenv ("PATHEXT");
248       if (pathext == NULL)
249         return FALSE;
250
251       pathext = g_utf8_casefold (pathext, -1);
252
253       lastdot = g_utf8_casefold (lastdot, -1);
254       extlen = strlen (lastdot);
255
256       p = pathext;
257       while (TRUE)
258         {
259           const gchar *q = strchr (p, ';');
260           if (q == NULL)
261             q = p + strlen (p);
262           if (extlen == q - p &&
263               memcmp (lastdot, p, extlen) == 0)
264             {
265               g_free ((gchar *) pathext);
266               g_free ((gchar *) lastdot);
267               return TRUE;
268             }
269           if (*q)
270             p = q + 1;
271           else
272             break;
273         }
274
275       g_free ((gchar *) pathext);
276       g_free ((gchar *) lastdot);
277       return FALSE;
278     }
279
280   return FALSE;
281 #else
282   if ((test & G_FILE_TEST_EXISTS) && (access (filename, F_OK) == 0))
283     return TRUE;
284   
285   if ((test & G_FILE_TEST_IS_EXECUTABLE) && (access (filename, X_OK) == 0))
286     {
287       if (getuid () != 0)
288         return TRUE;
289
290       /* For root, on some POSIX systems, access (filename, X_OK)
291        * will succeed even if no executable bits are set on the
292        * file. We fall through to a stat test to avoid that.
293        */
294     }
295   else
296     test &= ~G_FILE_TEST_IS_EXECUTABLE;
297
298   if (test & G_FILE_TEST_IS_SYMLINK)
299     {
300       struct stat s;
301
302       if ((lstat (filename, &s) == 0) && S_ISLNK (s.st_mode))
303         return TRUE;
304     }
305   
306   if (test & (G_FILE_TEST_IS_REGULAR |
307               G_FILE_TEST_IS_DIR |
308               G_FILE_TEST_IS_EXECUTABLE))
309     {
310       struct stat s;
311       
312       if (stat (filename, &s) == 0)
313         {
314           if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (s.st_mode))
315             return TRUE;
316           
317           if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (s.st_mode))
318             return TRUE;
319
320           /* The extra test for root when access (file, X_OK) succeeds.
321            */
322           if ((test & G_FILE_TEST_IS_EXECUTABLE) &&
323               ((s.st_mode & S_IXOTH) ||
324                (s.st_mode & S_IXUSR) ||
325                (s.st_mode & S_IXGRP)))
326             return TRUE;
327         }
328     }
329
330   return FALSE;
331 #endif
332 }
333
334 #ifdef G_OS_WIN32
335
336 #undef g_file_test
337
338 /* Binary compatibility version. Not for newly compiled code. */
339
340 gboolean
341 g_file_test (const gchar *filename,
342              GFileTest    test)
343 {
344   gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL);
345   gboolean retval;
346
347   if (utf8_filename == NULL)
348     return FALSE;
349
350   retval = g_file_test_utf8 (utf8_filename, test);
351
352   g_free (utf8_filename);
353
354   return retval;
355 }
356
357 #endif
358
359 GQuark
360 g_file_error_quark (void)
361 {
362   static GQuark q = 0;
363   if (q == 0)
364     q = g_quark_from_static_string ("g-file-error-quark");
365
366   return q;
367 }
368
369 /**
370  * g_file_error_from_errno:
371  * @err_no: an "errno" value
372  * 
373  * Gets a #GFileError constant based on the passed-in @errno.
374  * For example, if you pass in %EEXIST this function returns
375  * #G_FILE_ERROR_EXIST. Unlike @errno values, you can portably
376  * assume that all #GFileError values will exist.
377  *
378  * Normally a #GFileError value goes into a #GError returned
379  * from a function that manipulates files. So you would use
380  * g_file_error_from_errno() when constructing a #GError.
381  * 
382  * Return value: #GFileError corresponding to the given @errno
383  **/
384 GFileError
385 g_file_error_from_errno (gint err_no)
386 {
387   switch (err_no)
388     {
389 #ifdef EEXIST
390     case EEXIST:
391       return G_FILE_ERROR_EXIST;
392       break;
393 #endif
394
395 #ifdef EISDIR
396     case EISDIR:
397       return G_FILE_ERROR_ISDIR;
398       break;
399 #endif
400
401 #ifdef EACCES
402     case EACCES:
403       return G_FILE_ERROR_ACCES;
404       break;
405 #endif
406
407 #ifdef ENAMETOOLONG
408     case ENAMETOOLONG:
409       return G_FILE_ERROR_NAMETOOLONG;
410       break;
411 #endif
412
413 #ifdef ENOENT
414     case ENOENT:
415       return G_FILE_ERROR_NOENT;
416       break;
417 #endif
418
419 #ifdef ENOTDIR
420     case ENOTDIR:
421       return G_FILE_ERROR_NOTDIR;
422       break;
423 #endif
424
425 #ifdef ENXIO
426     case ENXIO:
427       return G_FILE_ERROR_NXIO;
428       break;
429 #endif
430
431 #ifdef ENODEV
432     case ENODEV:
433       return G_FILE_ERROR_NODEV;
434       break;
435 #endif
436
437 #ifdef EROFS
438     case EROFS:
439       return G_FILE_ERROR_ROFS;
440       break;
441 #endif
442
443 #ifdef ETXTBSY
444     case ETXTBSY:
445       return G_FILE_ERROR_TXTBSY;
446       break;
447 #endif
448
449 #ifdef EFAULT
450     case EFAULT:
451       return G_FILE_ERROR_FAULT;
452       break;
453 #endif
454
455 #ifdef ELOOP
456     case ELOOP:
457       return G_FILE_ERROR_LOOP;
458       break;
459 #endif
460
461 #ifdef ENOSPC
462     case ENOSPC:
463       return G_FILE_ERROR_NOSPC;
464       break;
465 #endif
466
467 #ifdef ENOMEM
468     case ENOMEM:
469       return G_FILE_ERROR_NOMEM;
470       break;
471 #endif
472
473 #ifdef EMFILE
474     case EMFILE:
475       return G_FILE_ERROR_MFILE;
476       break;
477 #endif
478
479 #ifdef ENFILE
480     case ENFILE:
481       return G_FILE_ERROR_NFILE;
482       break;
483 #endif
484
485 #ifdef EBADF
486     case EBADF:
487       return G_FILE_ERROR_BADF;
488       break;
489 #endif
490
491 #ifdef EINVAL
492     case EINVAL:
493       return G_FILE_ERROR_INVAL;
494       break;
495 #endif
496
497 #ifdef EPIPE
498     case EPIPE:
499       return G_FILE_ERROR_PIPE;
500       break;
501 #endif
502
503 #ifdef EAGAIN
504     case EAGAIN:
505       return G_FILE_ERROR_AGAIN;
506       break;
507 #endif
508
509 #ifdef EINTR
510     case EINTR:
511       return G_FILE_ERROR_INTR;
512       break;
513 #endif
514
515 #ifdef EIO
516     case EIO:
517       return G_FILE_ERROR_IO;
518       break;
519 #endif
520
521 #ifdef EPERM
522     case EPERM:
523       return G_FILE_ERROR_PERM;
524       break;
525 #endif
526
527 #ifdef ENOSYS
528     case ENOSYS:
529       return G_FILE_ERROR_NOSYS;
530       break;
531 #endif
532
533     default:
534       return G_FILE_ERROR_FAILED;
535       break;
536     }
537 }
538
539 static gboolean
540 get_contents_stdio (const gchar *display_filename,
541                     FILE        *f,
542                     gchar      **contents,
543                     gsize       *length,
544                     GError     **error)
545 {
546   gchar buf[4096];
547   size_t bytes;
548   gchar *str = NULL;
549   size_t total_bytes = 0;
550   size_t total_allocated = 0;
551   gchar *tmp;
552
553   g_assert (f != NULL);
554
555   while (!feof (f))
556     {
557       gint save_errno;
558
559       bytes = fread (buf, 1, sizeof (buf), f);
560       save_errno = errno;
561
562       while ((total_bytes + bytes + 1) > total_allocated)
563         {
564           if (str)
565             total_allocated *= 2;
566           else
567             total_allocated = MIN (bytes + 1, sizeof (buf));
568
569           tmp = g_try_realloc (str, total_allocated);
570
571           if (tmp == NULL)
572             {
573               g_set_error (error,
574                            G_FILE_ERROR,
575                            G_FILE_ERROR_NOMEM,
576                            _("Could not allocate %lu bytes to read file \"%s\""),
577                            (gulong) total_allocated,
578                            display_filename);
579
580               goto error;
581             }
582
583           str = tmp;
584         }
585
586       if (ferror (f))
587         {
588           g_set_error (error,
589                        G_FILE_ERROR,
590                        g_file_error_from_errno (save_errno),
591                        _("Error reading file '%s': %s"),
592                        display_filename,
593                        g_strerror (save_errno));
594
595           goto error;
596         }
597
598       memcpy (str + total_bytes, buf, bytes);
599       total_bytes += bytes;
600     }
601
602   fclose (f);
603
604   if (total_allocated == 0)
605     str = g_new (gchar, 1);
606
607   str[total_bytes] = '\0';
608
609   if (length)
610     *length = total_bytes;
611
612   *contents = str;
613
614   return TRUE;
615
616  error:
617
618   g_free (str);
619   fclose (f);
620
621   return FALSE;
622 }
623
624 #ifndef G_OS_WIN32
625
626 static gboolean
627 get_contents_regfile (const gchar *display_filename,
628                       struct stat *stat_buf,
629                       gint         fd,
630                       gchar      **contents,
631                       gsize       *length,
632                       GError     **error)
633 {
634   gchar *buf;
635   size_t bytes_read;
636   size_t size;
637   size_t alloc_size;
638   
639   size = stat_buf->st_size;
640
641   alloc_size = size + 1;
642   buf = g_try_malloc (alloc_size);
643
644   if (buf == NULL)
645     {
646       g_set_error (error,
647                    G_FILE_ERROR,
648                    G_FILE_ERROR_NOMEM,
649                    _("Could not allocate %lu bytes to read file \"%s\""),
650                    (gulong) alloc_size, 
651                    display_filename);
652
653       goto error;
654     }
655   
656   bytes_read = 0;
657   while (bytes_read < size)
658     {
659       gssize rc;
660           
661       rc = read (fd, buf + bytes_read, size - bytes_read);
662
663       if (rc < 0)
664         {
665           if (errno != EINTR) 
666             {
667               int save_errno = errno;
668
669               g_free (buf);
670               g_set_error (error,
671                            G_FILE_ERROR,
672                            g_file_error_from_errno (save_errno),
673                            _("Failed to read from file '%s': %s"),
674                            display_filename, 
675                            g_strerror (save_errno));
676
677               goto error;
678             }
679         }
680       else if (rc == 0)
681         break;
682       else
683         bytes_read += rc;
684     }
685       
686   buf[bytes_read] = '\0';
687
688   if (length)
689     *length = bytes_read;
690   
691   *contents = buf;
692
693   close (fd);
694
695   return TRUE;
696
697  error:
698
699   close (fd);
700   
701   return FALSE;
702 }
703
704 static gboolean
705 get_contents_posix (const gchar *filename,
706                     gchar      **contents,
707                     gsize       *length,
708                     GError     **error)
709 {
710   struct stat stat_buf;
711   gint fd;
712   gchar *display_filename = g_filename_display_name (filename);
713
714   /* O_BINARY useful on Cygwin */
715   fd = open (filename, O_RDONLY|O_BINARY);
716
717   if (fd < 0)
718     {
719       int save_errno = errno;
720
721       g_set_error (error,
722                    G_FILE_ERROR,
723                    g_file_error_from_errno (save_errno),
724                    _("Failed to open file '%s': %s"),
725                    display_filename, 
726                    g_strerror (save_errno));
727       g_free (display_filename);
728
729       return FALSE;
730     }
731
732   /* I don't think this will ever fail, aside from ENOMEM, but. */
733   if (fstat (fd, &stat_buf) < 0)
734     {
735       int save_errno = errno;
736
737       close (fd);
738       g_set_error (error,
739                    G_FILE_ERROR,
740                    g_file_error_from_errno (save_errno),
741                    _("Failed to get attributes of file '%s': fstat() failed: %s"),
742                    display_filename, 
743                    g_strerror (save_errno));
744       g_free (display_filename);
745
746       return FALSE;
747     }
748
749   if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
750     {
751       gboolean retval = get_contents_regfile (display_filename,
752                                               &stat_buf,
753                                               fd,
754                                               contents,
755                                               length,
756                                               error);
757       g_free (display_filename);
758
759       return retval;
760     }
761   else
762     {
763       FILE *f;
764       gboolean retval;
765
766       f = fdopen (fd, "r");
767       
768       if (f == NULL)
769         {
770           int save_errno = errno;
771
772           g_set_error (error,
773                        G_FILE_ERROR,
774                        g_file_error_from_errno (save_errno),
775                        _("Failed to open file '%s': fdopen() failed: %s"),
776                        display_filename, 
777                        g_strerror (save_errno));
778           g_free (display_filename);
779
780           return FALSE;
781         }
782   
783       retval = get_contents_stdio (display_filename, f, contents, length, error);
784       g_free (display_filename);
785
786       return retval;
787     }
788 }
789
790 #else  /* G_OS_WIN32 */
791
792 static gboolean
793 get_contents_win32 (const gchar *filename,
794                     gchar      **contents,
795                     gsize       *length,
796                     GError     **error)
797 {
798   FILE *f;
799   gboolean retval;
800   gchar *display_filename = g_filename_display_name (filename);
801   int save_errno;
802   
803   f = g_fopen (filename, "rb");
804   save_errno = errno;
805
806   if (f == NULL)
807     {
808       g_set_error (error,
809                    G_FILE_ERROR,
810                    g_file_error_from_errno (save_errno),
811                    _("Failed to open file '%s': %s"),
812                    display_filename,
813                    g_strerror (save_errno));
814       g_free (display_filename);
815
816       return FALSE;
817     }
818   
819   retval = get_contents_stdio (display_filename, f, contents, length, error);
820   g_free (display_filename);
821
822   return retval;
823 }
824
825 #endif
826
827 /**
828  * g_file_get_contents:
829  * @filename: name of a file to read contents from, in the GLib file name encoding
830  * @contents: location to store an allocated string
831  * @length: location to store length in bytes of the contents, or %NULL
832  * @error: return location for a #GError, or %NULL
833  * 
834  * Reads an entire file into allocated memory, with good error
835  * checking. 
836  *
837  * If the call was successful, it returns %TRUE and sets @contents to the file 
838  * contents and @length to the length of the file contents in bytes. The string 
839  * stored in @contents will be nul-terminated, so for text files you can pass 
840  * %NULL for the @length argument. If the call was not successful, it returns 
841  * %FALSE and sets @error. The error domain is #G_FILE_ERROR. Possible error  
842  * codes are those in the #GFileError enumeration. In the error case, 
843  * @contents is set to %NULL and @length is set to zero.
844  *
845  * Return value: %TRUE on success, %FALSE if an error occurred
846  **/
847 gboolean
848 g_file_get_contents (const gchar *filename,
849                      gchar      **contents,
850                      gsize       *length,
851                      GError     **error)
852 {  
853   g_return_val_if_fail (filename != NULL, FALSE);
854   g_return_val_if_fail (contents != NULL, FALSE);
855
856   *contents = NULL;
857   if (length)
858     *length = 0;
859
860 #ifdef G_OS_WIN32
861   return get_contents_win32 (filename, contents, length, error);
862 #else
863   return get_contents_posix (filename, contents, length, error);
864 #endif
865 }
866
867 #ifdef G_OS_WIN32
868
869 #undef g_file_get_contents
870
871 /* Binary compatibility version. Not for newly compiled code. */
872
873 gboolean
874 g_file_get_contents (const gchar *filename,
875                      gchar      **contents,
876                      gsize       *length,
877                      GError     **error)
878 {
879   gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
880   gboolean retval;
881
882   if (utf8_filename == NULL)
883     return FALSE;
884
885   retval = g_file_get_contents_utf8 (utf8_filename, contents, length, error);
886
887   g_free (utf8_filename);
888
889   return retval;
890 }
891
892 #endif
893
894 static gboolean
895 rename_file (const char *old_name,
896              const char *new_name,
897              GError **err)
898 {
899   errno = 0;
900   if (g_rename (old_name, new_name) == -1)
901     {
902       int save_errno = errno;
903       gchar *display_old_name = g_filename_display_name (old_name);
904       gchar *display_new_name = g_filename_display_name (new_name);
905
906       g_set_error (err,
907                    G_FILE_ERROR,
908                    g_file_error_from_errno (save_errno),
909                    _("Failed to rename file '%s' to '%s': g_rename() failed: %s"),
910                    display_old_name,
911                    display_new_name,
912                    g_strerror (save_errno));
913
914       g_free (display_old_name);
915       g_free (display_new_name);
916       
917       return FALSE;
918     }
919   
920   return TRUE;
921 }
922
923 static gboolean
924 set_umask_permissions (int           fd,
925                        GError      **err)
926 {
927 #ifdef G_OS_WIN32
928
929   return TRUE;
930
931 #else
932   /* All of this function is just to work around the fact that
933    * there is no way to get the umask without changing it.
934    *
935    * We can't just change-and-reset the umask because that would
936    * lead to a race condition if another thread tried to change
937    * the umask in between the getting and the setting of the umask.
938    * So we have to do the whole thing in a child process.
939    */
940
941   int save_errno;
942   pid_t pid;
943
944   pid = fork ();
945   
946   if (pid == -1)
947     {
948       save_errno = errno;
949       g_set_error (err,
950                    G_FILE_ERROR,
951                    g_file_error_from_errno (save_errno),
952                    _("Could not change file mode: fork() failed: %s"),
953                    g_strerror (save_errno));
954       
955       return FALSE;
956     }
957   else if (pid == 0)
958     {
959       /* child */
960       mode_t mask = umask (0666);
961
962       errno = 0;
963       if (fchmod (fd, 0666 & ~mask) == -1)
964         _exit (errno);
965       else
966         _exit (0);
967
968       return TRUE; /* To quiet gcc */
969     }
970   else
971     { 
972       /* parent */
973       int status;
974
975       errno = 0;
976       if (waitpid (pid, &status, 0) == -1)
977         {
978           save_errno = errno;
979
980           g_set_error (err,
981                        G_FILE_ERROR,
982                        g_file_error_from_errno (save_errno),
983                        _("Could not change file mode: waitpid() failed: %s"),
984                        g_strerror (save_errno));
985
986           return FALSE;
987         }
988
989       if (WIFEXITED (status))
990         {
991           save_errno = WEXITSTATUS (status);
992
993           if (save_errno == 0)
994             {
995               return TRUE;
996             }
997           else
998             {
999               g_set_error (err,
1000                            G_FILE_ERROR,
1001                            g_file_error_from_errno (save_errno),
1002                            _("Could not change file mode: chmod() failed: %s"),
1003                            g_strerror (save_errno));
1004       
1005               return FALSE;
1006             }
1007         }
1008       else if (WIFSIGNALED (status))
1009         {
1010           g_set_error (err,
1011                        G_FILE_ERROR,
1012                        G_FILE_ERROR_FAILED,
1013                        _("Could not change file mode: Child terminated by signal: %s"),
1014                        g_strsignal (WTERMSIG (status)));
1015                        
1016           return FALSE;
1017         }
1018       else
1019         {
1020           /* This shouldn't happen */
1021           g_set_error (err,
1022                        G_FILE_ERROR,
1023                        G_FILE_ERROR_FAILED,
1024                        _("Could not change file mode: Child terminated abnormally"));
1025           return FALSE;
1026         }
1027     }
1028 #endif
1029 }
1030
1031 static gchar *
1032 write_to_temp_file (const gchar *contents,
1033                     gssize length,
1034                     const gchar *template,
1035                     GError **err)
1036 {
1037   gchar *tmp_name;
1038   gchar *display_name;
1039   gchar *retval;
1040   FILE *file;
1041   gint fd;
1042   int save_errno;
1043
1044   retval = NULL;
1045   
1046   tmp_name = g_strdup_printf ("%s.XXXXXX", template);
1047
1048   errno = 0;
1049   fd = g_mkstemp (tmp_name);
1050   display_name = g_filename_display_name (tmp_name);
1051       
1052   if (fd == -1)
1053     {
1054       save_errno = errno;
1055       g_set_error (err,
1056                    G_FILE_ERROR,
1057                    g_file_error_from_errno (save_errno),
1058                    _("Failed to create file '%s': %s"),
1059                    display_name, g_strerror (save_errno));
1060       
1061       goto out;
1062     }
1063
1064   if (!set_umask_permissions (fd, err))
1065     {
1066       close (fd);
1067       g_unlink (tmp_name);
1068
1069       goto out;
1070     }
1071   
1072   errno = 0;
1073   file = fdopen (fd, "wb");
1074   if (!file)
1075     {
1076       save_errno = errno;
1077       g_set_error (err,
1078                    G_FILE_ERROR,
1079                    g_file_error_from_errno (save_errno),
1080                    _("Failed to open file '%s' for writing: fdopen() failed: %s"),
1081                    display_name,
1082                    g_strerror (save_errno));
1083
1084       close (fd);
1085       g_unlink (tmp_name);
1086       
1087       goto out;
1088     }
1089
1090   if (length > 0)
1091     {
1092       size_t n_written;
1093       
1094       errno = 0;
1095
1096       n_written = fwrite (contents, 1, length, file);
1097
1098       if (n_written < length)
1099         {
1100           save_errno = errno;
1101       
1102           g_set_error (err,
1103                        G_FILE_ERROR,
1104                        g_file_error_from_errno (save_errno),
1105                        _("Failed to write file '%s': fwrite() failed: %s"),
1106                        display_name,
1107                        g_strerror (save_errno));
1108
1109           fclose (file);
1110           g_unlink (tmp_name);
1111           
1112           goto out;
1113         }
1114     }
1115    
1116   errno = 0;
1117   if (fclose (file) == EOF)
1118     { 
1119       save_errno = 0;
1120       
1121       g_set_error (err,
1122                    G_FILE_ERROR,
1123                    g_file_error_from_errno (save_errno),
1124                    _("Failed to close file '%s': fclose() failed: %s"),
1125                    display_name, 
1126                    g_strerror (save_errno));
1127
1128       g_unlink (tmp_name);
1129       
1130       goto out;
1131     }
1132
1133   retval = g_strdup (tmp_name);
1134   
1135  out:
1136   g_free (tmp_name);
1137   g_free (display_name);
1138   
1139   return retval;
1140 }
1141
1142 /**
1143  * g_file_set_contents:
1144  * @filename: name of a file to write @contents to, in the GLib file name
1145  *   encoding
1146  * @contents: string to write to the file
1147  * @length: length of @contents, or -1 if @contents is a nul-terminated string
1148  * @error: return location for a #GError, or %NULL
1149  *
1150  * Writes all of @contents to a file named @filename, with good error checking.
1151  * If a file called @filename already exists it will be overwritten.
1152  *
1153  * This write is atomic in the sense that it is first written to a temporary
1154  * file which is then renamed to the final name. Notes:
1155  * <itemizedlist>
1156  * <listitem>
1157  *    On Unix, if @filename already exists hard links to @filename will break.
1158  *    Also since the file is recreated, existing permissions, access control
1159  *    lists, metadata etc. may be lost. If @filename is a symbolic link,
1160  *    the link itself will be replaced, not the linked file.
1161  * </listitem>
1162  * <listitem>
1163  *   On Windows renaming a file will not remove an existing file with the
1164  *   new name, so on Windows there is a race condition between the existing
1165  *   file being removed and the temporary file being renamed.
1166  * </listitem>
1167  * <listitem>
1168  *   On Windows there is no way to remove a file that is open to some
1169  *   process, or mapped into memory. Thus, this function will fail if
1170  *   @filename already exists and is open.
1171  * </listitem>
1172  * </itemizedlist>
1173  *
1174  * If the call was sucessful, it returns %TRUE. If the call was not successful,
1175  * it returns %FALSE and sets @error. The error domain is #G_FILE_ERROR.
1176  * Possible error codes are those in the #GFileError enumeration.
1177  *
1178  * Return value: %TRUE on success, %FALSE if an error occurred
1179  *
1180  * Since: 2.8
1181  **/
1182 gboolean
1183 g_file_set_contents (const gchar *filename,
1184                      const gchar *contents,
1185                      gssize          length,
1186                      GError        **error)
1187 {
1188   gchar *tmp_filename;
1189   gboolean retval;
1190   GError *rename_error = NULL;
1191   
1192   g_return_val_if_fail (filename != NULL, FALSE);
1193   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1194   g_return_val_if_fail (contents != NULL || length == 0, FALSE);
1195   g_return_val_if_fail (length >= -1, FALSE);
1196   
1197   if (length == -1)
1198     length = strlen (contents);
1199
1200   tmp_filename = write_to_temp_file (contents, length, filename, error);
1201   
1202   if (!tmp_filename)
1203     {
1204       retval = FALSE;
1205       goto out;
1206     }
1207
1208   if (!rename_file (tmp_filename, filename, &rename_error))
1209     {
1210 #ifndef G_OS_WIN32
1211
1212       g_unlink (tmp_filename);
1213       g_propagate_error (error, rename_error);
1214       retval = FALSE;
1215       goto out;
1216
1217 #else /* G_OS_WIN32 */
1218       
1219       /* Renaming failed, but on Windows this may just mean
1220        * the file already exists. So if the target file
1221        * exists, try deleting it and do the rename again.
1222        */
1223       if (!g_file_test (filename, G_FILE_TEST_EXISTS))
1224         {
1225           g_unlink (tmp_filename);
1226           g_propagate_error (error, rename_error);
1227           retval = FALSE;
1228           goto out;
1229         }
1230
1231       g_error_free (rename_error);
1232       
1233       if (g_unlink (filename) == -1)
1234         {
1235           gchar *display_filename = g_filename_display_name (filename);
1236
1237           int save_errno = errno;
1238           
1239           g_set_error (error,
1240                        G_FILE_ERROR,
1241                        g_file_error_from_errno (save_errno),
1242                        _("Existing file '%s' could not be removed: g_unlink() failed: %s"),
1243                        display_filename,
1244                        g_strerror (save_errno));
1245
1246           g_free (display_filename);
1247           g_unlink (tmp_filename);
1248           retval = FALSE;
1249           goto out;
1250         }
1251       
1252       if (!rename_file (tmp_filename, filename, error))
1253         {
1254           g_unlink (tmp_filename);
1255           retval = FALSE;
1256           goto out;
1257         }
1258
1259 #endif
1260     }
1261
1262   retval = TRUE;
1263   
1264  out:
1265   g_free (tmp_filename);
1266   return retval;
1267 }
1268
1269 /*
1270  * mkstemp() implementation is from the GNU C library.
1271  * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
1272  */
1273 /**
1274  * g_mkstemp:
1275  * @tmpl: template filename
1276  *
1277  * Opens a temporary file. See the mkstemp() documentation
1278  * on most UNIX-like systems. This is a portability wrapper, which simply calls 
1279  * mkstemp() on systems that have it, and implements 
1280  * it in GLib otherwise.
1281  *
1282  * The parameter is a string that should match the rules for
1283  * mkstemp(), i.e. end in "XXXXXX". The X string will 
1284  * be modified to form the name of a file that didn't exist.
1285  * The string should be in the GLib file name encoding. Most importantly, 
1286  * on Windows it should be in UTF-8.
1287  *
1288  * Return value: A file handle (as from open()) to the file
1289  * opened for reading and writing. The file is opened in binary mode
1290  * on platforms where there is a difference. The file handle should be
1291  * closed with close(). In case of errors, -1 is returned.
1292  */
1293 gint
1294 g_mkstemp (gchar *tmpl)
1295 {
1296 #ifdef HAVE_MKSTEMP
1297   return mkstemp (tmpl);
1298 #else
1299   int len;
1300   char *XXXXXX;
1301   int count, fd;
1302   static const char letters[] =
1303     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
1304   static const int NLETTERS = sizeof (letters) - 1;
1305   glong value;
1306   GTimeVal tv;
1307   static int counter = 0;
1308
1309   len = strlen (tmpl);
1310   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
1311     {
1312       errno = EINVAL;
1313       return -1;
1314     }
1315
1316   /* This is where the Xs start.  */
1317   XXXXXX = &tmpl[len - 6];
1318
1319   /* Get some more or less random data.  */
1320   g_get_current_time (&tv);
1321   value = (tv.tv_usec ^ tv.tv_sec) + counter++;
1322
1323   for (count = 0; count < 100; value += 7777, ++count)
1324     {
1325       glong v = value;
1326
1327       /* Fill in the random bits.  */
1328       XXXXXX[0] = letters[v % NLETTERS];
1329       v /= NLETTERS;
1330       XXXXXX[1] = letters[v % NLETTERS];
1331       v /= NLETTERS;
1332       XXXXXX[2] = letters[v % NLETTERS];
1333       v /= NLETTERS;
1334       XXXXXX[3] = letters[v % NLETTERS];
1335       v /= NLETTERS;
1336       XXXXXX[4] = letters[v % NLETTERS];
1337       v /= NLETTERS;
1338       XXXXXX[5] = letters[v % NLETTERS];
1339
1340       /* tmpl is in UTF-8 on Windows, thus use g_open() */
1341       fd = g_open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
1342
1343       if (fd >= 0)
1344         return fd;
1345       else if (errno != EEXIST)
1346         /* Any other error will apply also to other names we might
1347          *  try, and there are 2^32 or so of them, so give up now.
1348          */
1349         return -1;
1350     }
1351
1352   /* We got out of the loop because we ran out of combinations to try.  */
1353   errno = EEXIST;
1354   return -1;
1355 #endif
1356 }
1357
1358 #ifdef G_OS_WIN32
1359
1360 #undef g_mkstemp
1361
1362 /* Binary compatibility version. Not for newly compiled code. */
1363
1364 gint
1365 g_mkstemp (gchar *tmpl)
1366 {
1367   int len;
1368   char *XXXXXX;
1369   int count, fd;
1370   static const char letters[] =
1371     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
1372   static const int NLETTERS = sizeof (letters) - 1;
1373   glong value;
1374   GTimeVal tv;
1375   static int counter = 0;
1376
1377   len = strlen (tmpl);
1378   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
1379     {
1380       errno = EINVAL;
1381       return -1;
1382     }
1383
1384   /* This is where the Xs start.  */
1385   XXXXXX = &tmpl[len - 6];
1386
1387   /* Get some more or less random data.  */
1388   g_get_current_time (&tv);
1389   value = (tv.tv_usec ^ tv.tv_sec) + counter++;
1390
1391   for (count = 0; count < 100; value += 7777, ++count)
1392     {
1393       glong v = value;
1394
1395       /* Fill in the random bits.  */
1396       XXXXXX[0] = letters[v % NLETTERS];
1397       v /= NLETTERS;
1398       XXXXXX[1] = letters[v % NLETTERS];
1399       v /= NLETTERS;
1400       XXXXXX[2] = letters[v % NLETTERS];
1401       v /= NLETTERS;
1402       XXXXXX[3] = letters[v % NLETTERS];
1403       v /= NLETTERS;
1404       XXXXXX[4] = letters[v % NLETTERS];
1405       v /= NLETTERS;
1406       XXXXXX[5] = letters[v % NLETTERS];
1407
1408       /* This is the backward compatibility system codepage version,
1409        * thus use normal open().
1410        */
1411       fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
1412
1413       if (fd >= 0)
1414         return fd;
1415       else if (errno != EEXIST)
1416         /* Any other error will apply also to other names we might
1417          *  try, and there are 2^32 or so of them, so give up now.
1418          */
1419         return -1;
1420     }
1421
1422   /* We got out of the loop because we ran out of combinations to try.  */
1423   errno = EEXIST;
1424   return -1;
1425 }
1426
1427 #endif
1428
1429 /**
1430  * g_file_open_tmp:
1431  * @tmpl: Template for file name, as in g_mkstemp(), basename only
1432  * @name_used: location to store actual name used
1433  * @error: return location for a #GError
1434  *
1435  * Opens a file for writing in the preferred directory for temporary
1436  * files (as returned by g_get_tmp_dir()). 
1437  *
1438  * @tmpl should be a string in the GLib file name encoding ending with
1439  * six 'X' characters, as the parameter to g_mkstemp() (or mkstemp()).
1440  * However, unlike these functions, the template should only be a
1441  * basename, no directory components are allowed. If template is
1442  * %NULL, a default template is used.
1443  *
1444  * Note that in contrast to g_mkstemp() (and mkstemp()) 
1445  * @tmpl is not modified, and might thus be a read-only literal string.
1446  *
1447  * The actual name used is returned in @name_used if non-%NULL. This
1448  * string should be freed with g_free() when not needed any longer.
1449  * The returned name is in the GLib file name encoding.
1450  *
1451  * Return value: A file handle (as from open()) to 
1452  * the file opened for reading and writing. The file is opened in binary 
1453  * mode on platforms where there is a difference. The file handle should be
1454  * closed with close(). In case of errors, -1 is returned 
1455  * and @error will be set.
1456  **/
1457 gint
1458 g_file_open_tmp (const gchar *tmpl,
1459                  gchar      **name_used,
1460                  GError     **error)
1461 {
1462   int retval;
1463   const char *tmpdir;
1464   char *sep;
1465   char *fulltemplate;
1466   const char *slash;
1467
1468   if (tmpl == NULL)
1469     tmpl = ".XXXXXX";
1470
1471   if ((slash = strchr (tmpl, G_DIR_SEPARATOR)) != NULL
1472 #ifdef G_OS_WIN32
1473       || (strchr (tmpl, '/') != NULL && (slash = "/"))
1474 #endif
1475       )
1476     {
1477       gchar *display_tmpl = g_filename_display_name (tmpl);
1478       char c[2];
1479       c[0] = *slash;
1480       c[1] = '\0';
1481
1482       g_set_error (error,
1483                    G_FILE_ERROR,
1484                    G_FILE_ERROR_FAILED,
1485                    _("Template '%s' invalid, should not contain a '%s'"),
1486                    display_tmpl, c);
1487       g_free (display_tmpl);
1488
1489       return -1;
1490     }
1491   
1492   if (strlen (tmpl) < 6 ||
1493       strcmp (tmpl + strlen (tmpl) - 6, "XXXXXX") != 0)
1494     {
1495       gchar *display_tmpl = g_filename_display_name (tmpl);
1496       g_set_error (error,
1497                    G_FILE_ERROR,
1498                    G_FILE_ERROR_FAILED,
1499                    _("Template '%s' doesn't end with XXXXXX"),
1500                    display_tmpl);
1501       g_free (display_tmpl);
1502       return -1;
1503     }
1504
1505   tmpdir = g_get_tmp_dir ();
1506
1507   if (G_IS_DIR_SEPARATOR (tmpdir [strlen (tmpdir) - 1]))
1508     sep = "";
1509   else
1510     sep = G_DIR_SEPARATOR_S;
1511
1512   fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);
1513
1514   retval = g_mkstemp (fulltemplate);
1515
1516   if (retval == -1)
1517     {
1518       int save_errno = errno;
1519       gchar *display_fulltemplate = g_filename_display_name (fulltemplate);
1520
1521       g_set_error (error,
1522                    G_FILE_ERROR,
1523                    g_file_error_from_errno (save_errno),
1524                    _("Failed to create file '%s': %s"),
1525                    display_fulltemplate, g_strerror (save_errno));
1526       g_free (display_fulltemplate);
1527       g_free (fulltemplate);
1528       return -1;
1529     }
1530
1531   if (name_used)
1532     *name_used = fulltemplate;
1533   else
1534     g_free (fulltemplate);
1535
1536   return retval;
1537 }
1538
1539 #ifdef G_OS_WIN32
1540
1541 #undef g_file_open_tmp
1542
1543 /* Binary compatibility version. Not for newly compiled code. */
1544
1545 gint
1546 g_file_open_tmp (const gchar *tmpl,
1547                  gchar      **name_used,
1548                  GError     **error)
1549 {
1550   gchar *utf8_tmpl = g_locale_to_utf8 (tmpl, -1, NULL, NULL, error);
1551   gchar *utf8_name_used;
1552   gint retval;
1553
1554   if (utf8_tmpl == NULL)
1555     return -1;
1556
1557   retval = g_file_open_tmp_utf8 (utf8_tmpl, &utf8_name_used, error);
1558   
1559   if (retval == -1)
1560     return -1;
1561
1562   if (name_used)
1563     *name_used = g_locale_from_utf8 (utf8_name_used, -1, NULL, NULL, NULL);
1564
1565   g_free (utf8_name_used);
1566
1567   return retval;
1568 }
1569
1570 #endif
1571
1572 static gchar *
1573 g_build_path_va (const gchar  *separator,
1574                  const gchar  *first_element,
1575                  va_list      *args,
1576                  gchar       **str_array)
1577 {
1578   GString *result;
1579   gint separator_len = strlen (separator);
1580   gboolean is_first = TRUE;
1581   gboolean have_leading = FALSE;
1582   const gchar *single_element = NULL;
1583   const gchar *next_element;
1584   const gchar *last_trailing = NULL;
1585   gint i = 0;
1586
1587   result = g_string_new (NULL);
1588
1589   if (str_array)
1590     next_element = str_array[i++];
1591   else
1592     next_element = first_element;
1593
1594   while (TRUE)
1595     {
1596       const gchar *element;
1597       const gchar *start;
1598       const gchar *end;
1599
1600       if (next_element)
1601         {
1602           element = next_element;
1603           if (str_array)
1604             next_element = str_array[i++];
1605           else
1606             next_element = va_arg (*args, gchar *);
1607         }
1608       else
1609         break;
1610
1611       /* Ignore empty elements */
1612       if (!*element)
1613         continue;
1614       
1615       start = element;
1616
1617       if (separator_len)
1618         {
1619           while (start &&
1620                  strncmp (start, separator, separator_len) == 0)
1621             start += separator_len;
1622         }
1623
1624       end = start + strlen (start);
1625       
1626       if (separator_len)
1627         {
1628           while (end >= start + separator_len &&
1629                  strncmp (end - separator_len, separator, separator_len) == 0)
1630             end -= separator_len;
1631           
1632           last_trailing = end;
1633           while (last_trailing >= element + separator_len &&
1634                  strncmp (last_trailing - separator_len, separator, separator_len) == 0)
1635             last_trailing -= separator_len;
1636
1637           if (!have_leading)
1638             {
1639               /* If the leading and trailing separator strings are in the
1640                * same element and overlap, the result is exactly that element
1641                */
1642               if (last_trailing <= start)
1643                 single_element = element;
1644                   
1645               g_string_append_len (result, element, start - element);
1646               have_leading = TRUE;
1647             }
1648           else
1649             single_element = NULL;
1650         }
1651
1652       if (end == start)
1653         continue;
1654
1655       if (!is_first)
1656         g_string_append (result, separator);
1657       
1658       g_string_append_len (result, start, end - start);
1659       is_first = FALSE;
1660     }
1661
1662   if (single_element)
1663     {
1664       g_string_free (result, TRUE);
1665       return g_strdup (single_element);
1666     }
1667   else
1668     {
1669       if (last_trailing)
1670         g_string_append (result, last_trailing);
1671   
1672       return g_string_free (result, FALSE);
1673     }
1674 }
1675
1676 /**
1677  * g_build_pathv:
1678  * @separator: a string used to separator the elements of the path.
1679  * @args: %NULL-terminated array of strings containing the path elements.
1680  * 
1681  * Behaves exactly like g_build_path(), but takes the path elements 
1682  * as a string array, instead of varargs. This function is mainly
1683  * meant for language bindings.
1684  *
1685  * Return value: a newly-allocated string that must be freed with g_free().
1686  *
1687  * Since: 2.8
1688  */
1689 gchar *
1690 g_build_pathv (const gchar  *separator,
1691                gchar       **args)
1692 {
1693   if (!args)
1694     return NULL;
1695
1696   return g_build_path_va (separator, NULL, NULL, args);
1697 }
1698
1699
1700 /**
1701  * g_build_path:
1702  * @separator: a string used to separator the elements of the path.
1703  * @first_element: the first element in the path
1704  * @Varargs: remaining elements in path, terminated by %NULL
1705  * 
1706  * Creates a path from a series of elements using @separator as the
1707  * separator between elements. At the boundary between two elements,
1708  * any trailing occurrences of separator in the first element, or
1709  * leading occurrences of separator in the second element are removed
1710  * and exactly one copy of the separator is inserted.
1711  *
1712  * Empty elements are ignored.
1713  *
1714  * The number of leading copies of the separator on the result is
1715  * the same as the number of leading copies of the separator on
1716  * the first non-empty element.
1717  *
1718  * The number of trailing copies of the separator on the result is
1719  * the same as the number of trailing copies of the separator on
1720  * the last non-empty element. (Determination of the number of
1721  * trailing copies is done without stripping leading copies, so
1722  * if the separator is <literal>ABA</literal>, <literal>ABABA</literal>
1723  * has 1 trailing copy.)
1724  *
1725  * However, if there is only a single non-empty element, and there
1726  * are no characters in that element not part of the leading or
1727  * trailing separators, then the result is exactly the original value
1728  * of that element.
1729  *
1730  * Other than for determination of the number of leading and trailing
1731  * copies of the separator, elements consisting only of copies
1732  * of the separator are ignored.
1733  * 
1734  * Return value: a newly-allocated string that must be freed with g_free().
1735  **/
1736 gchar *
1737 g_build_path (const gchar *separator,
1738               const gchar *first_element,
1739               ...)
1740 {
1741   gchar *str;
1742   va_list args;
1743
1744   g_return_val_if_fail (separator != NULL, NULL);
1745
1746   va_start (args, first_element);
1747   str = g_build_path_va (separator, first_element, &args, NULL);
1748   va_end (args);
1749
1750   return str;
1751 }
1752
1753 #ifdef G_OS_WIN32
1754
1755 static gchar *
1756 g_build_pathname_va (const gchar  *first_element,
1757                      va_list      *args,
1758                      gchar       **str_array)
1759 {
1760   /* Code copied from g_build_pathv(), and modified to use two
1761    * alternative single-character separators.
1762    */
1763   GString *result;
1764   gboolean is_first = TRUE;
1765   gboolean have_leading = FALSE;
1766   const gchar *single_element = NULL;
1767   const gchar *next_element;
1768   const gchar *last_trailing = NULL;
1769   gchar current_separator = '\\';
1770   gint i = 0;
1771
1772   result = g_string_new (NULL);
1773
1774   if (str_array)
1775     next_element = str_array[i++];
1776   else
1777     next_element = first_element;
1778   
1779   while (TRUE)
1780     {
1781       const gchar *element;
1782       const gchar *start;
1783       const gchar *end;
1784
1785       if (next_element)
1786         {
1787           element = next_element;
1788           if (str_array)
1789             next_element = str_array[i++];
1790           else
1791             next_element = va_arg (*args, gchar *);
1792         }
1793       else
1794         break;
1795
1796       /* Ignore empty elements */
1797       if (!*element)
1798         continue;
1799       
1800       start = element;
1801
1802       if (TRUE)
1803         {
1804           while (start &&
1805                  (*start == '\\' || *start == '/'))
1806             {
1807               current_separator = *start;
1808               start++;
1809             }
1810         }
1811
1812       end = start + strlen (start);
1813       
1814       if (TRUE)
1815         {
1816           while (end >= start + 1 &&
1817                  (end[-1] == '\\' || end[-1] == '/'))
1818             {
1819               current_separator = end[-1];
1820               end--;
1821             }
1822           
1823           last_trailing = end;
1824           while (last_trailing >= element + 1 &&
1825                  (last_trailing[-1] == '\\' || last_trailing[-1] == '/'))
1826             last_trailing--;
1827
1828           if (!have_leading)
1829             {
1830               /* If the leading and trailing separator strings are in the
1831                * same element and overlap, the result is exactly that element
1832                */
1833               if (last_trailing <= start)
1834                 single_element = element;
1835                   
1836               g_string_append_len (result, element, start - element);
1837               have_leading = TRUE;
1838             }
1839           else
1840             single_element = NULL;
1841         }
1842
1843       if (end == start)
1844         continue;
1845
1846       if (!is_first)
1847         g_string_append_len (result, &current_separator, 1);
1848       
1849       g_string_append_len (result, start, end - start);
1850       is_first = FALSE;
1851     }
1852
1853   if (single_element)
1854     {
1855       g_string_free (result, TRUE);
1856       return g_strdup (single_element);
1857     }
1858   else
1859     {
1860       if (last_trailing)
1861         g_string_append (result, last_trailing);
1862   
1863       return g_string_free (result, FALSE);
1864     }
1865 }
1866
1867 #endif
1868
1869 /**
1870  * g_build_filenamev:
1871  * @args: %NULL-terminated array of strings containing the path elements.
1872  * 
1873  * Behaves exactly like g_build_filename(), but takes the path elements 
1874  * as a string array, instead of varargs. This function is mainly
1875  * meant for language bindings.
1876  *
1877  * Return value: a newly-allocated string that must be freed with g_free().
1878  * 
1879  * Since: 2.8
1880  */
1881 gchar *
1882 g_build_filenamev (gchar **args)
1883 {
1884   gchar *str;
1885
1886 #ifndef G_OS_WIN32
1887   str = g_build_path_va (G_DIR_SEPARATOR_S, NULL, NULL, args);
1888 #else
1889   str = g_build_pathname_va (NULL, NULL, args);
1890 #endif
1891
1892   return str;
1893 }
1894
1895 /**
1896  * g_build_filename:
1897  * @first_element: the first element in the path
1898  * @Varargs: remaining elements in path, terminated by %NULL
1899  * 
1900  * Creates a filename from a series of elements using the correct
1901  * separator for filenames.
1902  *
1903  * On Unix, this function behaves identically to <literal>g_build_path
1904  * (G_DIR_SEPARATOR_S, first_element, ....)</literal>.
1905  *
1906  * On Windows, it takes into account that either the backslash
1907  * (<literal>\</literal> or slash (<literal>/</literal>) can be used
1908  * as separator in filenames, but otherwise behaves as on Unix. When
1909  * file pathname separators need to be inserted, the one that last
1910  * previously occurred in the parameters (reading from left to right)
1911  * is used.
1912  *
1913  * No attempt is made to force the resulting filename to be an absolute
1914  * path. If the first element is a relative path, the result will
1915  * be a relative path. 
1916  * 
1917  * Return value: a newly-allocated string that must be freed with g_free().
1918  **/
1919 gchar *
1920 g_build_filename (const gchar *first_element, 
1921                   ...)
1922 {
1923   gchar *str;
1924   va_list args;
1925
1926   va_start (args, first_element);
1927 #ifndef G_OS_WIN32
1928   str = g_build_path_va (G_DIR_SEPARATOR_S, first_element, &args, NULL);
1929 #else
1930   str = g_build_pathname_va (first_element, &args, NULL);
1931 #endif
1932   va_end (args);
1933
1934   return str;
1935 }
1936
1937 /**
1938  * g_file_read_link:
1939  * @filename: the symbolic link
1940  * @error: return location for a #GError
1941  *
1942  * Reads the contents of the symbolic link @filename like the POSIX
1943  * readlink() function.  The returned string is in the encoding used
1944  * for filenames. Use g_filename_to_utf8() to convert it to UTF-8.
1945  *
1946  * Returns: A newly allocated string with the contents of the symbolic link, 
1947  *          or %NULL if an error occurred.
1948  *
1949  * Since: 2.4
1950  */
1951 gchar *
1952 g_file_read_link (const gchar *filename,
1953                   GError     **error)
1954 {
1955 #ifdef HAVE_READLINK
1956   gchar *buffer;
1957   guint size;
1958   gint read_size;    
1959   
1960   size = 256; 
1961   buffer = g_malloc (size);
1962   
1963   while (TRUE) 
1964     {
1965       read_size = readlink (filename, buffer, size);
1966       if (read_size < 0) {
1967         int save_errno = errno;
1968         gchar *display_filename = g_filename_display_name (filename);
1969
1970         g_free (buffer);
1971         g_set_error (error,
1972                      G_FILE_ERROR,
1973                      g_file_error_from_errno (save_errno),
1974                      _("Failed to read the symbolic link '%s': %s"),
1975                      display_filename, 
1976                      g_strerror (save_errno));
1977         g_free (display_filename);
1978         
1979         return NULL;
1980       }
1981     
1982       if (read_size < size) 
1983         {
1984           buffer[read_size] = 0;
1985           return buffer;
1986         }
1987       
1988       size *= 2;
1989       buffer = g_realloc (buffer, size);
1990     }
1991 #else
1992   g_set_error (error,
1993                G_FILE_ERROR,
1994                G_FILE_ERROR_INVAL,
1995                _("Symbolic links not supported"));
1996         
1997   return NULL;
1998 #endif
1999 }
2000
2001 #define __G_FILEUTILS_C__
2002 #include "galiasdef.c"