Use <envar>, not <envvar>.
[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, <literal>(G_FILE_TEST_EXISTS | 
75  * G_FILE_TEST_IS_DIR)</literal> will return %TRUE if the file exists; 
76  * the check whether it's a directory doesn't matter since the existence 
77  * test is %TRUE. 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  * Opens a temporary file. See the <function>mkstemp()</function> documentation
534  * on most UNIX-like systems. This is a portability wrapper, which simply calls 
535  * <function>mkstemp()</function> on systems that have it, and implements 
536  * it in GLib otherwise.
537  *
538  * The parameter is a string that should match the rules for
539  * <function>mkstemp()</function>, i.e. end in "XXXXXX". The X string will 
540  * be modified to form the name of a file that didn't exist.
541  *
542  * Return value: A file handle (as from <function>open()</function>) to the file
543  * opened for reading and writing. The file is opened in binary mode
544  * on platforms where there is a difference. The file handle should be
545  * closed with <function>close()</function>. In case of errors, -1 is returned.
546  */
547 int
548 g_mkstemp (char *tmpl)
549 {
550 #ifdef HAVE_MKSTEMP
551   return mkstemp (tmpl);
552 #else
553   int len;
554   char *XXXXXX;
555   int count, fd;
556   static const char letters[] =
557     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
558   static const int NLETTERS = sizeof (letters) - 1;
559   glong value;
560   GTimeVal tv;
561   static int counter = 0;
562
563   len = strlen (tmpl);
564   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
565     return -1;
566
567   /* This is where the Xs start.  */
568   XXXXXX = &tmpl[len - 6];
569
570   /* Get some more or less random data.  */
571   g_get_current_time (&tv);
572   value = (tv.tv_usec ^ tv.tv_sec) + counter++;
573
574   for (count = 0; count < 100; value += 7777, ++count)
575     {
576       glong v = value;
577
578       /* Fill in the random bits.  */
579       XXXXXX[0] = letters[v % NLETTERS];
580       v /= NLETTERS;
581       XXXXXX[1] = letters[v % NLETTERS];
582       v /= NLETTERS;
583       XXXXXX[2] = letters[v % NLETTERS];
584       v /= NLETTERS;
585       XXXXXX[3] = letters[v % NLETTERS];
586       v /= NLETTERS;
587       XXXXXX[4] = letters[v % NLETTERS];
588       v /= NLETTERS;
589       XXXXXX[5] = letters[v % NLETTERS];
590
591       fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
592
593       if (fd >= 0)
594         return fd;
595       else if (errno != EEXIST)
596         /* Any other error will apply also to other names we might
597          *  try, and there are 2^32 or so of them, so give up now.
598          */
599         return -1;
600     }
601
602   /* We got out of the loop because we ran out of combinations to try.  */
603   return -1;
604 #endif
605 }
606
607 /**
608  * g_file_open_tmp:
609  * @tmpl: Template for file name, as in g_mkstemp(), basename only
610  * @name_used: location to store actual name used
611  * @error: return location for a #GError
612  *
613  * Opens a file for writing in the preferred directory for temporary
614  * files (as returned by g_get_tmp_dir()). 
615  *
616  * @tmpl should be a string ending with six 'X' characters, as the
617  * parameter to g_mkstemp() (or <function>mkstemp()</function>). 
618  * However, unlike these functions, the template should only be a 
619  * basename, no directory components are allowed. If template is %NULL, 
620  * a default template is used.
621  *
622  * Note that in contrast to g_mkstemp() (and <function>mkstemp()</function>) 
623  * @tmpl is not modified, and might thus be a read-only literal string.
624  *
625  * The actual name used is returned in @name_used if non-%NULL. This
626  * string should be freed with g_free() when not needed any longer.
627  *
628  * Return value: A file handle (as from <function>open()</function>) to 
629  * the file opened for reading and writing. The file is opened in binary 
630  * mode on platforms where there is a difference. The file handle should be
631  * closed with <function>close()</function>. In case of errors, -1 is returned 
632  * and @error will be set.
633  **/
634 int
635 g_file_open_tmp (const char *tmpl,
636                  char      **name_used,
637                  GError    **error)
638 {
639   int retval;
640   const char *tmpdir;
641   char *sep;
642   char *fulltemplate;
643
644   if (tmpl == NULL)
645     tmpl = ".XXXXXX";
646
647   if (strchr (tmpl, G_DIR_SEPARATOR)
648 #ifdef G_OS_WIN32
649       || strchr (tmpl, '/')
650 #endif
651                                     )
652     {
653       g_set_error (error,
654                    G_FILE_ERROR,
655                    G_FILE_ERROR_FAILED,
656                    _("Template '%s' invalid, should not contain a '%s'"),
657                    tmpl, G_DIR_SEPARATOR_S);
658
659       return -1;
660     }
661   
662   if (strlen (tmpl) < 6 ||
663       strcmp (tmpl + strlen (tmpl) - 6, "XXXXXX") != 0)
664     {
665       g_set_error (error,
666                    G_FILE_ERROR,
667                    G_FILE_ERROR_FAILED,
668                    _("Template '%s' doesn't end with XXXXXX"),
669                    tmpl);
670       return -1;
671     }
672
673   tmpdir = g_get_tmp_dir ();
674
675   if (tmpdir [strlen (tmpdir) - 1] == G_DIR_SEPARATOR)
676     sep = "";
677   else
678     sep = G_DIR_SEPARATOR_S;
679
680   fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);
681
682   retval = g_mkstemp (fulltemplate);
683
684   if (retval == -1)
685     {
686       g_set_error (error,
687                    G_FILE_ERROR,
688                    g_file_error_from_errno (errno),
689                    _("Failed to create file '%s': %s"),
690                    fulltemplate, strerror (errno));
691       g_free (fulltemplate);
692       return -1;
693     }
694
695   if (name_used)
696     *name_used = fulltemplate;
697   else
698     g_free (fulltemplate);
699
700   return retval;
701 }
702
703 static gchar *
704 g_build_pathv (const gchar *separator,
705                const gchar *first_element,
706                va_list      args)
707 {
708   GString *result;
709   gint separator_len = strlen (separator);
710   gboolean is_first = TRUE;
711   const gchar *next_element;
712
713   result = g_string_new (NULL);
714
715   next_element = first_element;
716
717   while (TRUE)
718     {
719       const gchar *element;
720       const gchar *start;
721       const gchar *end;
722
723       if (next_element)
724         {
725           element = next_element;
726           next_element = va_arg (args, gchar *);
727         }
728       else
729         break;
730
731       start = element;
732       
733       if (is_first)
734         is_first = FALSE;
735       else if (separator_len)
736         {
737           while (start &&
738                  strncmp (start, separator, separator_len) == 0)
739             start += separator_len;
740         }
741
742       end = start + strlen (start);
743       
744       if (next_element && separator_len)
745         {
746           while (end > start + separator_len &&
747                  strncmp (end - separator_len, separator, separator_len) == 0)
748             end -= separator_len;
749         }
750
751       if (end > start)
752         {
753           if (result->len > 0)
754             g_string_append (result, separator);
755
756           g_string_append_len (result, start, end - start);
757         }
758     }
759   
760   return g_string_free (result, FALSE);
761 }
762
763 /**
764  * g_build_path:
765  * @separator: a string used to separator the elements of the path.
766  * @first_element: the first element in the path
767  * @Varargs: remaining elements in path
768  * 
769  * Creates a path from a series of elements using @separator as the
770  * separator between elements. At the boundary between two elements,
771  * any trailing occurrences of separator in the first element, or
772  * leading occurrences of separator in the second element are removed
773  * and exactly one copy of the separator is inserted.
774  * 
775  * Return value: a newly-allocated string that must be freed with g_free().
776  **/
777 gchar *
778 g_build_path (const gchar *separator,
779               const gchar *first_element,
780               ...)
781 {
782   gchar *str;
783   va_list args;
784
785   g_return_val_if_fail (separator != NULL, NULL);
786
787   va_start (args, first_element);
788   str = g_build_pathv (separator, first_element, args);
789   va_end (args);
790
791   return str;
792 }
793
794 /**
795  * g_build_filename:
796  * @first_element: the first element in the path
797  * @Varargs: remaining elements in path
798  * 
799  * Creates a filename from a series of elements using the correct
800  * separator for filenames. This function behaves identically
801  * to <literal>g_build_path (G_DIR_SEPARATOR_S, first_element, ....)</literal>.
802  *
803  * No attempt is made to force the resulting filename to be an absolute
804  * path. If the first element is a relative path, the result will
805  * be a relative path. 
806  * 
807  * Return value: a newly-allocated string that must be freed with g_free().
808  **/
809 gchar *
810 g_build_filename (const gchar *first_element, 
811                   ...)
812 {
813   gchar *str;
814   va_list args;
815
816   va_start (args, first_element);
817   str = g_build_pathv (G_DIR_SEPARATOR_S, first_element, args);
818   va_end (args);
819
820   return str;
821 }