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