Fixes for #58195, based on some ideas from Hidetosh Tajima.
[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 /**
69  * g_file_test:
70  * @filename: a filename to test
71  * @test: bitfield of #GFileTest flags
72  * 
73  * Returns TRUE if any of the tests in the bitfield @test are
74  * TRUE. For example, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)
75  * will return TRUE if the file exists; the check whether it's
76  * a directory doesn't matter since the existence test is TRUE.
77  * With the current set of available tests, there's no point
78  * passing in more than one test at a time.
79  *
80  * Return value: whether a test was TRUE
81  **/
82 gboolean
83 g_file_test (const gchar *filename,
84              GFileTest    test)
85 {
86   if (test & G_FILE_TEST_EXISTS)
87     return (access (filename, F_OK) == 0);
88   else if (test & G_FILE_TEST_IS_EXECUTABLE)
89     return (access (filename, X_OK) == 0);
90   else
91     {
92       struct stat s;
93       
94       if (stat (filename, &s) < 0)
95         return FALSE;
96
97       if ((test & G_FILE_TEST_IS_REGULAR) &&
98           S_ISREG (s.st_mode))
99         return TRUE;
100       else if ((test & G_FILE_TEST_IS_DIR) &&
101                S_ISDIR (s.st_mode))
102         return TRUE;
103       else if ((test & G_FILE_TEST_IS_SYMLINK) &&
104                S_ISLNK (s.st_mode))
105         return TRUE;
106       else
107         return FALSE;
108     }
109 }
110
111 GQuark
112 g_file_error_quark (void)
113 {
114   static GQuark q = 0;
115   if (q == 0)
116     q = g_quark_from_static_string ("g-file-error-quark");
117
118   return q;
119 }
120
121 /**
122  * g_file_error_from_errno:
123  * @err_no: an "errno" value
124  * 
125  * Gets a #GFileError constant based on the passed-in errno.
126  * For example, if you pass in EEXIST this function returns
127  * #G_FILE_ERROR_EXIST. Unlike errno values, you can portably
128  * assume that all #GFileError values will exist.
129  *
130  * Normally a #GFileError value goes into a #GError returned
131  * from a function that manipulates files. So you would use
132  * g_file_error_from_errno() when constructing a #GError.
133  * 
134  * Return value: #GFileError corresponding to the given errno
135  **/
136 GFileError
137 g_file_error_from_errno (gint err_no)
138 {
139   switch (err_no)
140     {
141 #ifdef EEXIST
142     case EEXIST:
143       return G_FILE_ERROR_EXIST;
144       break;
145 #endif
146
147 #ifdef EISDIR
148     case EISDIR:
149       return G_FILE_ERROR_ISDIR;
150       break;
151 #endif
152
153 #ifdef EACCES
154     case EACCES:
155       return G_FILE_ERROR_ACCES;
156       break;
157 #endif
158
159 #ifdef ENAMETOOLONG
160     case ENAMETOOLONG:
161       return G_FILE_ERROR_NAMETOOLONG;
162       break;
163 #endif
164
165 #ifdef ENOENT
166     case ENOENT:
167       return G_FILE_ERROR_NOENT;
168       break;
169 #endif
170
171 #ifdef ENOTDIR
172     case ENOTDIR:
173       return G_FILE_ERROR_NOTDIR;
174       break;
175 #endif
176
177 #ifdef ENXIO
178     case ENXIO:
179       return G_FILE_ERROR_NXIO;
180       break;
181 #endif
182
183 #ifdef ENODEV
184     case ENODEV:
185       return G_FILE_ERROR_NODEV;
186       break;
187 #endif
188
189 #ifdef EROFS
190     case EROFS:
191       return G_FILE_ERROR_ROFS;
192       break;
193 #endif
194
195 #ifdef ETXTBSY
196     case ETXTBSY:
197       return G_FILE_ERROR_TXTBSY;
198       break;
199 #endif
200
201 #ifdef EFAULT
202     case EFAULT:
203       return G_FILE_ERROR_FAULT;
204       break;
205 #endif
206
207 #ifdef ELOOP
208     case ELOOP:
209       return G_FILE_ERROR_LOOP;
210       break;
211 #endif
212
213 #ifdef ENOSPC
214     case ENOSPC:
215       return G_FILE_ERROR_NOSPC;
216       break;
217 #endif
218
219 #ifdef ENOMEM
220     case ENOMEM:
221       return G_FILE_ERROR_NOMEM;
222       break;
223 #endif
224
225 #ifdef EMFILE
226     case EMFILE:
227       return G_FILE_ERROR_MFILE;
228       break;
229 #endif
230
231 #ifdef ENFILE
232     case ENFILE:
233       return G_FILE_ERROR_NFILE;
234       break;
235 #endif
236
237 #ifdef EBADF
238     case EBADF:
239       return G_FILE_ERROR_BADF;
240       break;
241 #endif
242
243 #ifdef EINVAL
244     case EINVAL:
245       return G_FILE_ERROR_INVAL;
246       break;
247 #endif
248
249 #ifdef EPIPE
250     case EPIPE:
251       return G_FILE_ERROR_PIPE;
252       break;
253 #endif
254
255 #ifdef EAGAIN
256     case EAGAIN:
257       return G_FILE_ERROR_AGAIN;
258       break;
259 #endif
260
261 #ifdef EINTR
262     case EINTR:
263       return G_FILE_ERROR_INTR;
264       break;
265 #endif
266
267 #ifdef EIO
268     case EIO:
269       return G_FILE_ERROR_IO;
270       break;
271 #endif
272
273 #ifdef EPERM
274     case EPERM:
275       return G_FILE_ERROR_PERM;
276       break;
277 #endif
278       
279     default:
280       return G_FILE_ERROR_FAILED;
281       break;
282     }
283 }
284
285 static gboolean
286 get_contents_stdio (const gchar *filename,
287                     FILE        *f,
288                     gchar      **contents,
289                     gsize       *length, 
290                     GError     **error)
291 {
292   gchar buf[2048];
293   size_t bytes;
294   GString *str;
295
296   g_assert (f != NULL);
297   
298   str = g_string_new ("");
299   
300   while (!feof (f))
301     {
302       bytes = fread (buf, 1, 2048, f);
303       
304       if (ferror (f))
305         {
306           g_set_error (error,
307                        G_FILE_ERROR,
308                        g_file_error_from_errno (errno),
309                        _("Error reading file '%s': %s"),
310                        filename, strerror (errno));
311
312           g_string_free (str, TRUE);
313           fclose (f);
314           
315           return FALSE;
316         }
317
318       g_string_append_len (str, buf, bytes);
319     }
320
321   fclose (f);
322
323   if (length)
324     *length = str->len;
325   
326   *contents = g_string_free (str, FALSE);
327
328   return TRUE;  
329 }
330
331 #ifndef G_OS_WIN32
332
333 static gboolean
334 get_contents_regfile (const gchar *filename,
335                       struct stat *stat_buf,
336                       gint         fd,
337                       gchar      **contents,
338                       gsize       *length,
339                       GError     **error)
340 {
341   gchar *buf;
342   size_t bytes_read;
343   size_t size;
344       
345   size = stat_buf->st_size;
346
347   buf = g_new (gchar, size + 1);
348       
349   bytes_read = 0;
350   while (bytes_read < size)
351     {
352       gssize rc;
353           
354       rc = read (fd, buf + bytes_read, size - bytes_read);
355
356       if (rc < 0)
357         {
358           if (errno != EINTR) 
359             {
360               close (fd);
361
362               g_free (buf);
363                   
364               g_set_error (error,
365                            G_FILE_ERROR,
366                            g_file_error_from_errno (errno),
367                            _("Failed to read from file '%s': %s"),
368                            filename, strerror (errno));
369
370               return FALSE;
371             }
372         }
373       else if (rc == 0)
374         break;
375       else
376         bytes_read += rc;
377     }
378       
379   buf[bytes_read] = '\0';
380
381   if (length)
382     *length = bytes_read;
383   
384   *contents = buf;
385
386   return TRUE;
387 }
388
389 static gboolean
390 get_contents_posix (const gchar *filename,
391                     gchar      **contents,
392                     gsize       *length,
393                     GError     **error)
394 {
395   struct stat stat_buf;
396   gint fd;
397   
398   /* O_BINARY useful on Cygwin */
399   fd = open (filename, O_RDONLY|O_BINARY);
400
401   if (fd < 0)
402     {
403       g_set_error (error,
404                    G_FILE_ERROR,
405                    g_file_error_from_errno (errno),
406                    _("Failed to open file '%s': %s"),
407                    filename, strerror (errno));
408
409       return FALSE;
410     }
411
412   /* I don't think this will ever fail, aside from ENOMEM, but. */
413   if (fstat (fd, &stat_buf) < 0)
414     {
415       close (fd);
416       
417       g_set_error (error,
418                    G_FILE_ERROR,
419                    g_file_error_from_errno (errno),
420                    _("Failed to get attributes of file '%s': fstat() failed: %s"),
421                    filename, strerror (errno));
422
423       return FALSE;
424     }
425
426   if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
427     {
428       return get_contents_regfile (filename,
429                                    &stat_buf,
430                                    fd,
431                                    contents,
432                                    length,
433                                    error);
434     }
435   else
436     {
437       FILE *f;
438
439       f = fdopen (fd, "r");
440       
441       if (f == NULL)
442         {
443           g_set_error (error,
444                        G_FILE_ERROR,
445                        g_file_error_from_errno (errno),
446                        _("Failed to open file '%s': fdopen() failed: %s"),
447                        filename, strerror (errno));
448           
449           return FALSE;
450         }
451   
452       return get_contents_stdio (filename, f, contents, length, error);
453     }
454 }
455
456 #else  /* G_OS_WIN32 */
457
458 static gboolean
459 get_contents_win32 (const gchar *filename,
460                     gchar      **contents,
461                     gsize       *length,
462                     GError     **error)
463 {
464   FILE *f;
465
466   /* I guess you want binary mode; maybe you want text sometimes? */
467   f = fopen (filename, "rb");
468
469   if (f == NULL)
470     {
471       g_set_error (error,
472                    G_FILE_ERROR,
473                    g_file_error_from_errno (errno),
474                    _("Failed to open file '%s': %s"),
475                    filename, strerror (errno));
476       
477       return FALSE;
478     }
479   
480   return get_contents_stdio (filename, f, contents, length, error);
481 }
482
483 #endif
484
485 /**
486  * g_file_get_contents:
487  * @filename: a file to read contents from
488  * @contents: location to store an allocated string
489  * @length: location to store length in bytes of the contents
490  * @error: return location for a #GError
491  * 
492  * Reads an entire file into allocated memory, with good error
493  * checking. If @error is set, FALSE is returned, and @contents is set
494  * to NULL. If TRUE is returned, @error will not be set, and @contents
495  * will be set to the file contents.  The string stored in @contents
496  * will be nul-terminated, so for text files you can pass NULL for the
497  * @length argument.  The error domain is #G_FILE_ERROR. Possible
498  * error codes are those in the #GFileError enumeration.
499  *
500  * FIXME currently crashes if the file is too big to fit in memory;
501  * should probably use g_try_malloc() when we have that function.
502  * 
503  * Return value: TRUE on success, FALSE if error is set
504  **/
505 gboolean
506 g_file_get_contents (const gchar *filename,
507                      gchar      **contents,
508                      gsize       *length,
509                      GError     **error)
510 {  
511   g_return_val_if_fail (filename != NULL, FALSE);
512   g_return_val_if_fail (contents != NULL, FALSE);
513
514   *contents = NULL;
515   if (length)
516     *length = 0;
517
518 #ifdef G_OS_WIN32
519   return get_contents_win32 (filename, contents, length, error);
520 #else
521   return get_contents_posix (filename, contents, length, error);
522 #endif
523 }
524
525 /*
526  * mkstemp() implementation is from the GNU C library.
527  * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
528  */
529 /**
530  * g_mkstemp:
531  * @tmpl: template filename
532  *
533  * Open a temporary file. See "man mkstemp" on most UNIX-like systems.
534  * This is a portability wrapper, which simply calls mkstemp() on systems
535  * that have it, and implements it in GLib otherwise.
536  *
537  * The parameter is a string that should match the rules for mktemp, i.e.
538  * end in "XXXXXX". The X string will be modified to form the name
539  * of a file that didn't exist.
540  *
541  * Return value: A file handle (as from open()) to the file
542  * opened for reading and writing. The file is opened in binary mode
543  * on platforms where there is a difference. The file handle should be
544  * closed with close(). In case of errors, -1 is returned.
545  */
546 int
547 g_mkstemp (char *tmpl)
548 {
549 #ifdef HAVE_MKSTEMP
550   return mkstemp (tmpl);
551 #else
552   int len;
553   char *XXXXXX;
554   int count, fd;
555   static const char letters[] =
556     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
557   static const int NLETTERS = sizeof (letters) - 1;
558   glong value;
559   GTimeVal tv;
560   static int counter = 0;
561
562   len = strlen (tmpl);
563   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
564     return -1;
565
566   /* This is where the Xs start.  */
567   XXXXXX = &tmpl[len - 6];
568
569   /* Get some more or less random data.  */
570   g_get_current_time (&tv);
571   value = (tv.tv_usec ^ tv.tv_sec) + counter++;
572
573   for (count = 0; count < 100; value += 7777, ++count)
574     {
575       glong v = value;
576
577       /* Fill in the random bits.  */
578       XXXXXX[0] = letters[v % NLETTERS];
579       v /= NLETTERS;
580       XXXXXX[1] = letters[v % NLETTERS];
581       v /= NLETTERS;
582       XXXXXX[2] = letters[v % NLETTERS];
583       v /= NLETTERS;
584       XXXXXX[3] = letters[v % NLETTERS];
585       v /= NLETTERS;
586       XXXXXX[4] = letters[v % NLETTERS];
587       v /= NLETTERS;
588       XXXXXX[5] = letters[v % NLETTERS];
589
590       fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
591
592       if (fd >= 0)
593         return fd;
594       else if (errno != EEXIST)
595         /* Any other error will apply also to other names we might
596          *  try, and there are 2^32 or so of them, so give up now.
597          */
598         return -1;
599     }
600
601   /* We got out of the loop because we ran out of combinations to try.  */
602   return -1;
603 #endif
604 }
605
606 /**
607  * g_file_open_tmp:
608  * @tmpl: Template for file name, as in g_mkstemp, basename only
609  * @name_used: location to store actual name used
610  * @error: return location for a #GError
611  *
612  * Opens a file for writing in the preferred directory for temporary
613  * files (as returned by g_get_tmp_dir()). 
614  *
615  * @tmpl should be a string ending with six 'X' characters, as the
616  * parameter to g_mkstemp() (or mkstemp()). However, unlike these
617  * functions, the template should only be a basename, no directory
618  * components are allowed. If template is NULL, a default template is
619  * used.
620  *
621  * Note that in contrast to g_mkstemp() (and mkstemp()) @tmpl is not
622  * modified, and might thus be a read-only literal string.
623  *
624  * The actual name used is returned in @name_used if non-NULL. This
625  * string should be freed with g_free when not needed any longer.
626  *
627  * Return value: A file handle (as from open()) to the file
628  * opened for reading and writing. The file is opened in binary mode
629  * on platforms where there is a difference. The file handle should be
630  * closed with close(). In case of errors, -1 is returned and
631  * @error will be set.
632  **/
633 int
634 g_file_open_tmp (const char *tmpl,
635                  char      **name_used,
636                  GError    **error)
637 {
638   int retval;
639   const char *tmpdir;
640   char *sep;
641   char *fulltemplate;
642
643   if (tmpl == NULL)
644     tmpl = ".XXXXXX";
645
646   if (strchr (tmpl, G_DIR_SEPARATOR)
647 #ifdef G_OS_WIN32
648       || strchr (tmpl, '/')
649 #endif
650                                     )
651     {
652       g_set_error (error,
653                    G_FILE_ERROR,
654                    G_FILE_ERROR_FAILED,
655                    _("Template '%s' invalid, should not contain a '%s'"),
656                    tmpl, G_DIR_SEPARATOR_S);
657
658       return -1;
659     }
660   
661   if (strlen (tmpl) < 6 ||
662       strcmp (tmpl + strlen (tmpl) - 6, "XXXXXX") != 0)
663     {
664       g_set_error (error,
665                    G_FILE_ERROR,
666                    G_FILE_ERROR_FAILED,
667                    _("Template '%s' doesn't end with XXXXXX"),
668                    tmpl);
669       return -1;
670     }
671
672   tmpdir = g_get_tmp_dir ();
673
674   if (tmpdir [strlen (tmpdir) - 1] == G_DIR_SEPARATOR)
675     sep = "";
676   else
677     sep = G_DIR_SEPARATOR_S;
678
679   fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);
680
681   retval = g_mkstemp (fulltemplate);
682
683   if (retval == -1)
684     {
685       g_set_error (error,
686                    G_FILE_ERROR,
687                    g_file_error_from_errno (errno),
688                    _("Failed to create file '%s': %s"),
689                    fulltemplate, strerror (errno));
690       g_free (fulltemplate);
691       return -1;
692     }
693
694   if (name_used)
695     *name_used = fulltemplate;
696   else
697     g_free (fulltemplate);
698
699   return retval;
700 }
701
702 static gchar *
703 g_build_pathv (const gchar *separator,
704                const gchar *first_element,
705                va_list      args)
706 {
707   GString *result;
708   gint separator_len = strlen (separator);
709   gboolean is_first = TRUE;
710   const gchar *next_element;
711
712   result = g_string_new (NULL);
713
714   next_element = first_element;
715
716   while (TRUE)
717     {
718       const gchar *element;
719       const gchar *start;
720       const gchar *end;
721
722       if (next_element)
723         {
724           element = next_element;
725           next_element = va_arg (args, gchar *);
726         }
727       else
728         break;
729
730       start = element;
731       
732       if (is_first)
733         is_first = FALSE;
734       else if (separator_len)
735         {
736           while (start &&
737                  strncmp (start, separator, separator_len) == 0)
738             start += separator_len;
739         }
740
741       end = start + strlen (start);
742       
743       if (next_element && separator_len)
744         {
745           while (end > start + separator_len &&
746                  strncmp (end - separator_len, separator, separator_len) == 0)
747             end -= separator_len;
748         }
749
750       if (end > start)
751         {
752           if (result->len > 0)
753             g_string_append (result, separator);
754
755           g_string_append_len (result, start, end - start);
756         }
757     }
758   
759   return g_string_free (result, FALSE);
760 }
761
762 /**
763  * g_build_path:
764  * @separator: a string used to separator the elements of the path.
765  * @first_element: the first element in the path
766  * @Varargs: remaining elements in path
767  * 
768  * Create a path from a series of elements using @separator as the
769  * separator between elements. At the boundary between two elements,
770  * any trailing occurrences of separator in the first element, or
771  * leading occurrences of separator in the second element are removed
772  * and exactly one copy of the separator is inserted.
773  * 
774  * Return value: a newly allocated string that must be freed with g_free().
775  **/
776 gchar *
777 g_build_path (const gchar *separator,
778               const gchar *first_element,
779               ...)
780 {
781   gchar *str;
782   va_list args;
783
784   g_return_val_if_fail (separator != NULL, NULL);
785
786   va_start (args, first_element);
787   str = g_build_pathv (separator, first_element, args);
788   va_end (args);
789
790   return str;
791 }
792
793 /**
794  * g_build_filename:
795  * @first_element: the first element in the path
796  * @Varargs: remaining elements in path
797  * 
798  * Create a filename from a series of elements using the correct
799  * separator for filenames. This function behaves identically
800  * to g_build_path (G_DIR_SEPARATOR_S, first_element, ....)
801  *
802  * No attempt is made to force the resulting filename to be an absolute
803  * path. If the first element is a relative path, the result will
804  * be a relative path. 
805  * 
806  * Return value: a newly allocated string that must be freed with g_free().
807  **/
808 gchar *
809 g_build_filename (const gchar *first_element, 
810                   ...)
811 {
812   gchar *str;
813   va_list args;
814
815   va_start (args, first_element);
816   str = g_build_pathv (G_DIR_SEPARATOR_S, first_element, args);
817   va_end (args);
818
819   return str;
820 }