Fix #117925 (Dov Grobgeld):
[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 #include <fcntl.h>
37 #include <stdlib.h>
38
39 #ifdef G_OS_WIN32
40 #include <io.h>
41 #ifndef F_OK
42 #define F_OK 0
43 #define X_OK 1
44 #define W_OK 2
45 #define R_OK 4
46 #endif /* !F_OK */
47
48 #ifndef S_ISREG
49 #define S_ISREG(mode) ((mode)&_S_IFREG)
50 #endif
51
52 #ifndef S_ISDIR
53 #define S_ISDIR(mode) ((mode)&_S_IFDIR)
54 #endif
55
56 #endif /* G_OS_WIN32 */
57
58 #ifndef S_ISLNK
59 #define S_ISLNK(x) 0
60 #endif
61
62 #ifndef O_BINARY
63 #define O_BINARY 0
64 #endif
65
66 #include "glibintl.h"
67
68 #ifdef G_OS_WIN32
69 #define G_IS_DIR_SEPARATOR(c) (c == G_DIR_SEPARATOR || c == '/')
70 #else
71 #define G_IS_DIR_SEPARATOR(c) (c == G_DIR_SEPARATOR)
72 #endif
73
74 /**
75  * g_file_test:
76  * @filename: a filename to test
77  * @test: bitfield of #GFileTest flags
78  * 
79  * Returns %TRUE if any of the tests in the bitfield @test are
80  * %TRUE. For example, <literal>(G_FILE_TEST_EXISTS | 
81  * G_FILE_TEST_IS_DIR)</literal> will return %TRUE if the file exists; 
82  * the check whether it's a directory doesn't matter since the existence 
83  * test is %TRUE. With the current set of available tests, there's no point
84  * passing in more than one test at a time.
85  * 
86  * Apart from %G_FILE_TEST_IS_SYMLINK all tests follow symbolic links,
87  * so for a symbolic link to a regular file g_file_test() will return
88  * %TRUE for both %G_FILE_TEST_IS_SYMLINK and %G_FILE_TEST_IS_REGULAR.
89  *
90  * Note, that for a dangling symbolic link g_file_test() will return
91  * %TRUE for %G_FILE_TEST_IS_SYMLINK and %FALSE for all other flags.
92  *
93  * You should never use g_file_test() to test whether it is safe
94  * to perform an operaton, because there is always the possibility
95  * of the condition changing before you actually perform the operation.
96  * For example, you might think you could use %G_FILE_TEST_IS_SYMLINK
97  * to know whether it is is safe to write to a file without being
98  * tricked into writing into a different location. It doesn't work!
99  *
100  * <informalexample><programlisting>
101  * /&ast; DON'T DO THIS &ast;/
102  *  if (!g_file_test (filename, G_FILE_TEST_IS_SYMLINK)) {
103  *    fd = open (filename, O_WRONLY);
104  *    /&ast; write to fd &ast;/
105  *  }
106  * </programlisting></informalexample>
107  *
108  * Another thing to note is that %G_FILE_TEST_EXISTS and
109  * %G_FILE_TEST_IS_EXECUTABLE are implemented using the access()
110  * system call. This usually doesn't matter, but if your program
111  * is setuid or setgid it means that these tests will give you
112  * the answer for the real user ID and group ID , rather than the
113  * effective user ID and group ID.
114  *
115  * Return value: whether a test was %TRUE
116  **/
117 gboolean
118 g_file_test (const gchar *filename,
119              GFileTest    test)
120 {
121   if ((test & G_FILE_TEST_EXISTS) && (access (filename, F_OK) == 0))
122     return TRUE;
123   
124   if ((test & G_FILE_TEST_IS_EXECUTABLE) && (access (filename, X_OK) == 0))
125     {
126 #ifndef G_OS_WIN32
127       if (getuid () != 0)
128 #endif  
129         return TRUE;
130
131       /* For root, on some POSIX systems, access (filename, X_OK)
132        * will succeed even if no executable bits are set on the
133        * file. We fall through to a stat test to avoid that.
134        */
135     }
136   else
137     test &= ~G_FILE_TEST_IS_EXECUTABLE;
138
139   if (test & G_FILE_TEST_IS_SYMLINK)
140     {
141 #ifdef G_OS_WIN32
142       /* no sym links on win32, no lstat in msvcrt */
143 #else
144       struct stat s;
145
146       if ((lstat (filename, &s) == 0) && S_ISLNK (s.st_mode))
147         return TRUE;
148 #endif
149     }
150   
151   if (test & (G_FILE_TEST_IS_REGULAR |
152               G_FILE_TEST_IS_DIR |
153               G_FILE_TEST_IS_EXECUTABLE))
154     {
155       struct stat s;
156       
157       if (stat (filename, &s) == 0)
158         {
159           if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (s.st_mode))
160             return TRUE;
161           
162           if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (s.st_mode))
163             return TRUE;
164
165 #ifndef G_OS_WIN32
166           /* The extra test for root when access (file, X_OK) succeeds.
167            * Probably only makes sense on Unix.
168            */
169           if ((test & G_FILE_TEST_IS_EXECUTABLE) &&
170               ((s.st_mode & S_IXOTH) ||
171                (s.st_mode & S_IXUSR) ||
172                (s.st_mode & S_IXGRP)))
173             return TRUE;
174 #endif
175         }
176     }
177
178   return FALSE;
179 }
180
181 GQuark
182 g_file_error_quark (void)
183 {
184   static GQuark q = 0;
185   if (q == 0)
186     q = g_quark_from_static_string ("g-file-error-quark");
187
188   return q;
189 }
190
191 /**
192  * g_file_error_from_errno:
193  * @err_no: an "errno" value
194  * 
195  * Gets a #GFileError constant based on the passed-in @errno.
196  * For example, if you pass in %EEXIST this function returns
197  * #G_FILE_ERROR_EXIST. Unlike @errno values, you can portably
198  * assume that all #GFileError values will exist.
199  *
200  * Normally a #GFileError value goes into a #GError returned
201  * from a function that manipulates files. So you would use
202  * g_file_error_from_errno() when constructing a #GError.
203  * 
204  * Return value: #GFileError corresponding to the given @errno
205  **/
206 GFileError
207 g_file_error_from_errno (gint err_no)
208 {
209   switch (err_no)
210     {
211 #ifdef EEXIST
212     case EEXIST:
213       return G_FILE_ERROR_EXIST;
214       break;
215 #endif
216
217 #ifdef EISDIR
218     case EISDIR:
219       return G_FILE_ERROR_ISDIR;
220       break;
221 #endif
222
223 #ifdef EACCES
224     case EACCES:
225       return G_FILE_ERROR_ACCES;
226       break;
227 #endif
228
229 #ifdef ENAMETOOLONG
230     case ENAMETOOLONG:
231       return G_FILE_ERROR_NAMETOOLONG;
232       break;
233 #endif
234
235 #ifdef ENOENT
236     case ENOENT:
237       return G_FILE_ERROR_NOENT;
238       break;
239 #endif
240
241 #ifdef ENOTDIR
242     case ENOTDIR:
243       return G_FILE_ERROR_NOTDIR;
244       break;
245 #endif
246
247 #ifdef ENXIO
248     case ENXIO:
249       return G_FILE_ERROR_NXIO;
250       break;
251 #endif
252
253 #ifdef ENODEV
254     case ENODEV:
255       return G_FILE_ERROR_NODEV;
256       break;
257 #endif
258
259 #ifdef EROFS
260     case EROFS:
261       return G_FILE_ERROR_ROFS;
262       break;
263 #endif
264
265 #ifdef ETXTBSY
266     case ETXTBSY:
267       return G_FILE_ERROR_TXTBSY;
268       break;
269 #endif
270
271 #ifdef EFAULT
272     case EFAULT:
273       return G_FILE_ERROR_FAULT;
274       break;
275 #endif
276
277 #ifdef ELOOP
278     case ELOOP:
279       return G_FILE_ERROR_LOOP;
280       break;
281 #endif
282
283 #ifdef ENOSPC
284     case ENOSPC:
285       return G_FILE_ERROR_NOSPC;
286       break;
287 #endif
288
289 #ifdef ENOMEM
290     case ENOMEM:
291       return G_FILE_ERROR_NOMEM;
292       break;
293 #endif
294
295 #ifdef EMFILE
296     case EMFILE:
297       return G_FILE_ERROR_MFILE;
298       break;
299 #endif
300
301 #ifdef ENFILE
302     case ENFILE:
303       return G_FILE_ERROR_NFILE;
304       break;
305 #endif
306
307 #ifdef EBADF
308     case EBADF:
309       return G_FILE_ERROR_BADF;
310       break;
311 #endif
312
313 #ifdef EINVAL
314     case EINVAL:
315       return G_FILE_ERROR_INVAL;
316       break;
317 #endif
318
319 #ifdef EPIPE
320     case EPIPE:
321       return G_FILE_ERROR_PIPE;
322       break;
323 #endif
324
325 #ifdef EAGAIN
326     case EAGAIN:
327       return G_FILE_ERROR_AGAIN;
328       break;
329 #endif
330
331 #ifdef EINTR
332     case EINTR:
333       return G_FILE_ERROR_INTR;
334       break;
335 #endif
336
337 #ifdef EIO
338     case EIO:
339       return G_FILE_ERROR_IO;
340       break;
341 #endif
342
343 #ifdef EPERM
344     case EPERM:
345       return G_FILE_ERROR_PERM;
346       break;
347 #endif
348       
349     default:
350       return G_FILE_ERROR_FAILED;
351       break;
352     }
353 }
354
355 static gboolean
356 get_contents_stdio (const gchar *filename,
357                     FILE        *f,
358                     gchar      **contents,
359                     gsize       *length, 
360                     GError     **error)
361 {
362   gchar buf[2048];
363   size_t bytes;
364   char *str;
365   size_t total_bytes;
366   size_t total_allocated;
367   
368   g_assert (f != NULL);
369
370 #define STARTING_ALLOC 64
371   
372   total_bytes = 0;
373   total_allocated = STARTING_ALLOC;
374   str = g_malloc (STARTING_ALLOC);
375   
376   while (!feof (f))
377     {
378       bytes = fread (buf, 1, 2048, f);
379
380       while ((total_bytes + bytes + 1) > total_allocated)
381         {
382           total_allocated *= 2;
383           str = g_try_realloc (str, total_allocated);
384
385           if (str == NULL)
386             {
387               g_set_error (error,
388                            G_FILE_ERROR,
389                            G_FILE_ERROR_NOMEM,
390                            _("Could not allocate %lu bytes to read file \"%s\""),
391                            (gulong) total_allocated, filename);
392               goto error;
393             }
394         }
395       
396       if (ferror (f))
397         {
398           g_set_error (error,
399                        G_FILE_ERROR,
400                        g_file_error_from_errno (errno),
401                        _("Error reading file '%s': %s"),
402                        filename, g_strerror (errno));
403
404           goto error;
405         }
406
407       memcpy (str + total_bytes, buf, bytes);
408       total_bytes += bytes;
409     }
410
411   fclose (f);
412
413   str[total_bytes] = '\0';
414   
415   if (length)
416     *length = total_bytes;
417   
418   *contents = str;
419   
420   return TRUE;
421
422  error:
423
424   g_free (str);
425   fclose (f);
426   
427   return FALSE;  
428 }
429
430 #ifndef G_OS_WIN32
431
432 static gboolean
433 get_contents_regfile (const gchar *filename,
434                       struct stat *stat_buf,
435                       gint         fd,
436                       gchar      **contents,
437                       gsize       *length,
438                       GError     **error)
439 {
440   gchar *buf;
441   size_t bytes_read;
442   size_t size;
443   size_t alloc_size;
444   
445   size = stat_buf->st_size;
446
447   alloc_size = size + 1;
448   buf = g_try_malloc (alloc_size);
449
450   if (buf == NULL)
451     {
452       g_set_error (error,
453                    G_FILE_ERROR,
454                    G_FILE_ERROR_NOMEM,
455                    _("Could not allocate %lu bytes to read file \"%s\""),
456                    (gulong) alloc_size, filename);
457
458       goto error;
459     }
460   
461   bytes_read = 0;
462   while (bytes_read < size)
463     {
464       gssize rc;
465           
466       rc = read (fd, buf + bytes_read, size - bytes_read);
467
468       if (rc < 0)
469         {
470           if (errno != EINTR) 
471             {
472               g_free (buf);
473                   
474               g_set_error (error,
475                            G_FILE_ERROR,
476                            g_file_error_from_errno (errno),
477                            _("Failed to read from file '%s': %s"),
478                            filename, g_strerror (errno));
479
480               goto error;
481             }
482         }
483       else if (rc == 0)
484         break;
485       else
486         bytes_read += rc;
487     }
488       
489   buf[bytes_read] = '\0';
490
491   if (length)
492     *length = bytes_read;
493   
494   *contents = buf;
495
496   close (fd);
497
498   return TRUE;
499
500  error:
501
502   close (fd);
503   
504   return FALSE;
505 }
506
507 static gboolean
508 get_contents_posix (const gchar *filename,
509                     gchar      **contents,
510                     gsize       *length,
511                     GError     **error)
512 {
513   struct stat stat_buf;
514   gint fd;
515   
516   /* O_BINARY useful on Cygwin */
517   fd = open (filename, O_RDONLY|O_BINARY);
518
519   if (fd < 0)
520     {
521       g_set_error (error,
522                    G_FILE_ERROR,
523                    g_file_error_from_errno (errno),
524                    _("Failed to open file '%s': %s"),
525                    filename, g_strerror (errno));
526
527       return FALSE;
528     }
529
530   /* I don't think this will ever fail, aside from ENOMEM, but. */
531   if (fstat (fd, &stat_buf) < 0)
532     {
533       close (fd);
534       
535       g_set_error (error,
536                    G_FILE_ERROR,
537                    g_file_error_from_errno (errno),
538                    _("Failed to get attributes of file '%s': fstat() failed: %s"),
539                    filename, g_strerror (errno));
540
541       return FALSE;
542     }
543
544   if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
545     {
546       return get_contents_regfile (filename,
547                                    &stat_buf,
548                                    fd,
549                                    contents,
550                                    length,
551                                    error);
552     }
553   else
554     {
555       FILE *f;
556
557       f = fdopen (fd, "r");
558       
559       if (f == NULL)
560         {
561           g_set_error (error,
562                        G_FILE_ERROR,
563                        g_file_error_from_errno (errno),
564                        _("Failed to open file '%s': fdopen() failed: %s"),
565                        filename, g_strerror (errno));
566           
567           return FALSE;
568         }
569   
570       return get_contents_stdio (filename, f, contents, length, error);
571     }
572 }
573
574 #else  /* G_OS_WIN32 */
575
576 static gboolean
577 get_contents_win32 (const gchar *filename,
578                     gchar      **contents,
579                     gsize       *length,
580                     GError     **error)
581 {
582   FILE *f;
583
584   /* I guess you want binary mode; maybe you want text sometimes? */
585   f = fopen (filename, "rb");
586
587   if (f == NULL)
588     {
589       g_set_error (error,
590                    G_FILE_ERROR,
591                    g_file_error_from_errno (errno),
592                    _("Failed to open file '%s': %s"),
593                    filename, g_strerror (errno));
594       
595       return FALSE;
596     }
597   
598   return get_contents_stdio (filename, f, contents, length, error);
599 }
600
601 #endif
602
603 /**
604  * g_file_get_contents:
605  * @filename: a file to read contents from
606  * @contents: location to store an allocated string
607  * @length: location to store length in bytes of the contents
608  * @error: return location for a #GError
609  * 
610  * Reads an entire file into allocated memory, with good error
611  * checking. If @error is set, %FALSE is returned, and @contents is set
612  * to %NULL. If %TRUE is returned, @error will not be set, and @contents
613  * will be set to the file contents.  The string stored in @contents
614  * will be nul-terminated, so for text files you can pass %NULL for the
615  * @length argument.  The error domain is #G_FILE_ERROR. Possible
616  * error codes are those in the #GFileError enumeration.
617  *
618  * Return value: %TRUE on success, %FALSE if error is set
619  **/
620 gboolean
621 g_file_get_contents (const gchar *filename,
622                      gchar      **contents,
623                      gsize       *length,
624                      GError     **error)
625 {  
626   g_return_val_if_fail (filename != NULL, FALSE);
627   g_return_val_if_fail (contents != NULL, FALSE);
628
629   *contents = NULL;
630   if (length)
631     *length = 0;
632
633 #ifdef G_OS_WIN32
634   return get_contents_win32 (filename, contents, length, error);
635 #else
636   return get_contents_posix (filename, contents, length, error);
637 #endif
638 }
639
640 /*
641  * mkstemp() implementation is from the GNU C library.
642  * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
643  */
644 /**
645  * g_mkstemp:
646  * @tmpl: template filename
647  *
648  * Opens a temporary file. See the mkstemp() documentation
649  * on most UNIX-like systems. This is a portability wrapper, which simply calls 
650  * mkstemp() on systems that have it, and implements 
651  * it in GLib otherwise.
652  *
653  * The parameter is a string that should match the rules for
654  * mkstemp(), i.e. end in "XXXXXX". The X string will 
655  * be modified to form the name of a file that didn't exist.
656  *
657  * Return value: A file handle (as from open()) to the file
658  * opened for reading and writing. The file is opened in binary mode
659  * on platforms where there is a difference. The file handle should be
660  * closed with close(). In case of errors, -1 is returned.
661  */
662 gint
663 g_mkstemp (gchar *tmpl)
664 {
665 #ifdef HAVE_MKSTEMP
666   return mkstemp (tmpl);
667 #else
668   int len;
669   char *XXXXXX;
670   int count, fd;
671   static const char letters[] =
672     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
673   static const int NLETTERS = sizeof (letters) - 1;
674   glong value;
675   GTimeVal tv;
676   static int counter = 0;
677
678   len = strlen (tmpl);
679   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
680     return -1;
681
682   /* This is where the Xs start.  */
683   XXXXXX = &tmpl[len - 6];
684
685   /* Get some more or less random data.  */
686   g_get_current_time (&tv);
687   value = (tv.tv_usec ^ tv.tv_sec) + counter++;
688
689   for (count = 0; count < 100; value += 7777, ++count)
690     {
691       glong v = value;
692
693       /* Fill in the random bits.  */
694       XXXXXX[0] = letters[v % NLETTERS];
695       v /= NLETTERS;
696       XXXXXX[1] = letters[v % NLETTERS];
697       v /= NLETTERS;
698       XXXXXX[2] = letters[v % NLETTERS];
699       v /= NLETTERS;
700       XXXXXX[3] = letters[v % NLETTERS];
701       v /= NLETTERS;
702       XXXXXX[4] = letters[v % NLETTERS];
703       v /= NLETTERS;
704       XXXXXX[5] = letters[v % NLETTERS];
705
706       fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
707
708       if (fd >= 0)
709         return fd;
710       else if (errno != EEXIST)
711         /* Any other error will apply also to other names we might
712          *  try, and there are 2^32 or so of them, so give up now.
713          */
714         return -1;
715     }
716
717   /* We got out of the loop because we ran out of combinations to try.  */
718   return -1;
719 #endif
720 }
721
722 /**
723  * g_file_open_tmp:
724  * @tmpl: Template for file name, as in g_mkstemp(), basename only
725  * @name_used: location to store actual name used
726  * @error: return location for a #GError
727  *
728  * Opens a file for writing in the preferred directory for temporary
729  * files (as returned by g_get_tmp_dir()). 
730  *
731  * @tmpl should be a string ending with six 'X' characters, as the
732  * parameter to g_mkstemp() (or mkstemp()). 
733  * However, unlike these functions, the template should only be a 
734  * basename, no directory components are allowed. If template is %NULL, 
735  * a default template is used.
736  *
737  * Note that in contrast to g_mkstemp() (and mkstemp()) 
738  * @tmpl is not modified, and might thus be a read-only literal string.
739  *
740  * The actual name used is returned in @name_used if non-%NULL. This
741  * string should be freed with g_free() when not needed any longer.
742  *
743  * Return value: A file handle (as from open()) to 
744  * the file opened for reading and writing. The file is opened in binary 
745  * mode on platforms where there is a difference. The file handle should be
746  * closed with close(). In case of errors, -1 is returned 
747  * and @error will be set.
748  **/
749 gint
750 g_file_open_tmp (const gchar *tmpl,
751                  gchar      **name_used,
752                  GError     **error)
753 {
754   int retval;
755   const char *tmpdir;
756   char *sep;
757   char *fulltemplate;
758   const char *slash;
759
760   if (tmpl == NULL)
761     tmpl = ".XXXXXX";
762
763   if ((slash = strchr (tmpl, G_DIR_SEPARATOR)) != NULL
764 #ifdef G_OS_WIN32
765       || (strchr (tmpl, '/') != NULL && (slash = "/"))
766 #endif
767       )
768     {
769       char c[2];
770       c[0] = *slash;
771       c[1] = '\0';
772
773       g_set_error (error,
774                    G_FILE_ERROR,
775                    G_FILE_ERROR_FAILED,
776                    _("Template '%s' invalid, should not contain a '%s'"),
777                    tmpl, c);
778
779       return -1;
780     }
781   
782   if (strlen (tmpl) < 6 ||
783       strcmp (tmpl + strlen (tmpl) - 6, "XXXXXX") != 0)
784     {
785       g_set_error (error,
786                    G_FILE_ERROR,
787                    G_FILE_ERROR_FAILED,
788                    _("Template '%s' doesn't end with XXXXXX"),
789                    tmpl);
790       return -1;
791     }
792
793   tmpdir = g_get_tmp_dir ();
794
795   if (G_IS_DIR_SEPARATOR (tmpdir [strlen (tmpdir) - 1]))
796     sep = "";
797   else
798     sep = G_DIR_SEPARATOR_S;
799
800   fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);
801
802   retval = g_mkstemp (fulltemplate);
803
804   if (retval == -1)
805     {
806       g_set_error (error,
807                    G_FILE_ERROR,
808                    g_file_error_from_errno (errno),
809                    _("Failed to create file '%s': %s"),
810                    fulltemplate, g_strerror (errno));
811       g_free (fulltemplate);
812       return -1;
813     }
814
815   if (name_used)
816     *name_used = fulltemplate;
817   else
818     g_free (fulltemplate);
819
820   return retval;
821 }
822
823 static gchar *
824 g_build_pathv (const gchar *separator,
825                const gchar *first_element,
826                va_list      args)
827 {
828   GString *result;
829   gint separator_len = strlen (separator);
830   gboolean is_first = TRUE;
831   gboolean have_leading = FALSE;
832   const gchar *single_element = NULL;
833   const gchar *next_element;
834   const gchar *last_trailing = NULL;
835
836   result = g_string_new (NULL);
837
838   next_element = first_element;
839
840   while (TRUE)
841     {
842       const gchar *element;
843       const gchar *start;
844       const gchar *end;
845
846       if (next_element)
847         {
848           element = next_element;
849           next_element = va_arg (args, gchar *);
850         }
851       else
852         break;
853
854       /* Ignore empty elements */
855       if (!*element)
856         continue;
857       
858       start = element;
859
860       if (separator_len)
861         {
862           while (start &&
863                  strncmp (start, separator, separator_len) == 0)
864             start += separator_len;
865         }
866
867       end = start + strlen (start);
868       
869       if (separator_len)
870         {
871           while (end >= start + separator_len &&
872                  strncmp (end - separator_len, separator, separator_len) == 0)
873             end -= separator_len;
874           
875           last_trailing = end;
876           while (last_trailing >= element + separator_len &&
877                  strncmp (last_trailing - separator_len, separator, separator_len) == 0)
878             last_trailing -= separator_len;
879
880           if (!have_leading)
881             {
882               /* If the leading and trailing separator strings are in the
883                * same element and overlap, the result is exactly that element
884                */
885               if (last_trailing <= start)
886                 single_element = element;
887                   
888               g_string_append_len (result, element, start - element);
889               have_leading = TRUE;
890             }
891           else
892             single_element = NULL;
893         }
894
895       if (end == start)
896         continue;
897
898       if (!is_first)
899         g_string_append (result, separator);
900       
901       g_string_append_len (result, start, end - start);
902       is_first = FALSE;
903     }
904
905   if (single_element)
906     {
907       g_string_free (result, TRUE);
908       return g_strdup (single_element);
909     }
910   else
911     {
912       if (last_trailing)
913         g_string_append (result, last_trailing);
914   
915       return g_string_free (result, FALSE);
916     }
917 }
918
919 /**
920  * g_build_path:
921  * @separator: a string used to separator the elements of the path.
922  * @first_element: the first element in the path
923  * @Varargs: remaining elements in path, terminated by %NULL
924  * 
925  * Creates a path from a series of elements using @separator as the
926  * separator between elements. At the boundary between two elements,
927  * any trailing occurrences of separator in the first element, or
928  * leading occurrences of separator in the second element are removed
929  * and exactly one copy of the separator is inserted.
930  *
931  * Empty elements are ignored.
932  *
933  * The number of leading copies of the separator on the result is
934  * the same as the number of leading copies of the separator on
935  * the first non-empty element.
936  *
937  * The number of trailing copies of the separator on the result is
938  * the same as the number of trailing copies of the separator on
939  * the last non-empty element. (Determination of the number of
940  * trailing copies is done without stripping leading copies, so
941  * if the separator is <literal>ABA</literal>, <literal>ABABA</literal>
942  * has 1 trailing copy.)
943  *
944  * However, if there is only a single non-empty element, and there
945  * are no characters in that element not part of the leading or
946  * trailing separators, then the result is exactly the original value
947  * of that element.
948  *
949  * Other than for determination of the number of leading and trailing
950  * copies of the separator, elements consisting only of copies
951  * of the separator are ignored.
952  * 
953  * Return value: a newly-allocated string that must be freed with g_free().
954  **/
955 gchar *
956 g_build_path (const gchar *separator,
957               const gchar *first_element,
958               ...)
959 {
960   gchar *str;
961   va_list args;
962
963   g_return_val_if_fail (separator != NULL, NULL);
964
965   va_start (args, first_element);
966   str = g_build_pathv (separator, first_element, args);
967   va_end (args);
968
969   return str;
970 }
971
972 /**
973  * g_build_filename:
974  * @first_element: the first element in the path
975  * @Varargs: remaining elements in path, terminated by %NULL
976  * 
977  * Creates a filename from a series of elements using the correct
978  * separator for filenames.
979  *
980  * On Unix, this function behaves identically to <literal>g_build_path
981  * (G_DIR_SEPARATOR_S, first_element, ....)</literal>.
982  *
983  * On Windows, it takes into account that either the backslash
984  * (<literal>\</literal> or slash (<literal>/</literal>) can be used
985  * as separator in filenames, but otherwise behaves as on Unix. When
986  * file pathname separators need to be inserted, the one that last
987  * previously occurred in the parameters (reading from left to right)
988  * is used.
989  *
990  * No attempt is made to force the resulting filename to be an absolute
991  * path. If the first element is a relative path, the result will
992  * be a relative path. 
993  * 
994  * Return value: a newly-allocated string that must be freed with g_free().
995  **/
996 gchar *
997 g_build_filename (const gchar *first_element, 
998                   ...)
999 {
1000 #ifndef G_OS_WIN32
1001   gchar *str;
1002   va_list args;
1003
1004   va_start (args, first_element);
1005   str = g_build_pathv (G_DIR_SEPARATOR_S, first_element, args);
1006   va_end (args);
1007
1008   return str;
1009 #else
1010   /* Code copied from g_build_pathv(), and modifed to use two
1011    * alternative single-character separators.
1012    */
1013   va_list args;
1014   GString *result;
1015   gboolean is_first = TRUE;
1016   gboolean have_leading = FALSE;
1017   const gchar *single_element = NULL;
1018   const gchar *next_element;
1019   const gchar *last_trailing = NULL;
1020   gchar current_separator = '\\';
1021
1022   va_start (args, first_element);
1023
1024   result = g_string_new (NULL);
1025
1026   next_element = first_element;
1027
1028   while (TRUE)
1029     {
1030       const gchar *element;
1031       const gchar *start;
1032       const gchar *end;
1033
1034       if (next_element)
1035         {
1036           element = next_element;
1037           next_element = va_arg (args, gchar *);
1038         }
1039       else
1040         break;
1041
1042       /* Ignore empty elements */
1043       if (!*element)
1044         continue;
1045       
1046       start = element;
1047
1048       if (TRUE)
1049         {
1050           while (start &&
1051                  (*start == '\\' || *start == '/'))
1052             {
1053               current_separator = *start;
1054               start++;
1055             }
1056         }
1057
1058       end = start + strlen (start);
1059       
1060       if (TRUE)
1061         {
1062           while (end >= start + 1 &&
1063                  (end[-1] == '\\' || end[-1] == '/'))
1064             {
1065               current_separator = end[-1];
1066               end--;
1067             }
1068           
1069           last_trailing = end;
1070           while (last_trailing >= element + 1 &&
1071                  (last_trailing[-1] == '\\' || last_trailing[-1] == '/'))
1072             last_trailing--;
1073
1074           if (!have_leading)
1075             {
1076               /* If the leading and trailing separator strings are in the
1077                * same element and overlap, the result is exactly that element
1078                */
1079               if (last_trailing <= start)
1080                 single_element = element;
1081                   
1082               g_string_append_len (result, element, start - element);
1083               have_leading = TRUE;
1084             }
1085           else
1086             single_element = NULL;
1087         }
1088
1089       if (end == start)
1090         continue;
1091
1092       if (!is_first)
1093         g_string_append_len (result, &current_separator, 1);
1094       
1095       g_string_append_len (result, start, end - start);
1096       is_first = FALSE;
1097     }
1098
1099   va_end (args);
1100
1101   if (single_element)
1102     {
1103       g_string_free (result, TRUE);
1104       return g_strdup (single_element);
1105     }
1106   else
1107     {
1108       if (last_trailing)
1109         g_string_append (result, last_trailing);
1110   
1111       return g_string_free (result, FALSE);
1112     }
1113 #endif
1114 }
1115
1116 /**
1117  * g_file_read_link:
1118  * @filename: the symbolic link
1119  * @error: return location for a #GError
1120  *
1121  * Reads the contents of the symbolic link @filename like the POSIX readlink() function.
1122  * The returned string is in the encoding used for filenames. Use g_filename_to_utf8() to 
1123  * convert it to UTF-8.
1124  *
1125  * Returns: A newly allocated string with the contents of the symbolic link, 
1126  *          or %NULL if an error occurred.
1127  *
1128  * Since: 2.4
1129  */
1130 gchar *
1131 g_file_read_link (const gchar *filename,
1132                   GError     **error)
1133 {
1134 #ifdef HAVE_READLINK
1135   gchar *buffer;
1136   guint size;
1137   gint read_size;    
1138   
1139   size = 256; 
1140   buffer = g_malloc (size);
1141   
1142   while (TRUE) 
1143     {
1144       read_size = readlink (filename, buffer, size);
1145       if (read_size < 0) {
1146         g_free (buffer);
1147         g_set_error (error,
1148                      G_FILE_ERROR,
1149                      g_file_error_from_errno (errno),
1150                      _("Failed to read the symbolic link '%s': %s"),
1151                      filename, g_strerror (errno));
1152         
1153         return NULL;
1154       }
1155     
1156       if (read_size < size) 
1157         {
1158           buffer[read_size] = 0;
1159           return buffer;
1160         }
1161       
1162       size *= 2;
1163       buffer = g_realloc (buffer, size);
1164     }
1165 #else
1166   g_set_error (error,
1167                G_FILE_ERROR,
1168                G_FILE_ERROR_INVAL,
1169                _("Symbolic links not supported"));
1170         
1171   return NULL;
1172 #endif
1173 }