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