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