Use the new GRealThread member "context" instead of a GStaticPrivate to
[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   /* O_BINARY useful on Cygwin */
382   fd = open (filename, O_RDONLY|O_BINARY);
383
384   if (fd < 0)
385     {
386       g_set_error (error,
387                    G_FILE_ERROR,
388                    g_file_error_from_errno (errno),
389                    _("Failed to open file '%s': %s"),
390                    filename, strerror (errno));
391
392       return FALSE;
393     }
394
395   /* I don't think this will ever fail, aside from ENOMEM, but. */
396   if (fstat (fd, &stat_buf) < 0)
397     {
398       close (fd);
399       
400       g_set_error (error,
401                    G_FILE_ERROR,
402                    g_file_error_from_errno (errno),
403                    _("Failed to get attributes of file '%s': fstat() failed: %s"),
404                    filename, strerror (errno));
405
406       return FALSE;
407     }
408
409   if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
410     {
411       return get_contents_regfile (filename,
412                                    &stat_buf,
413                                    fd,
414                                    contents,
415                                    length,
416                                    error);
417     }
418   else
419     {
420       FILE *f;
421
422       f = fdopen (fd, "r");
423       
424       if (f == NULL)
425         {
426           g_set_error (error,
427                        G_FILE_ERROR,
428                        g_file_error_from_errno (errno),
429                        _("Failed to open file '%s': fdopen() failed: %s"),
430                        filename, strerror (errno));
431           
432           return FALSE;
433         }
434   
435       return get_contents_stdio (filename, f, contents, length, error);
436     }
437 }
438
439 #else  /* G_OS_WIN32 */
440
441 static gboolean
442 get_contents_win32 (const gchar *filename,
443                     gchar      **contents,
444                     guint       *length,
445                     GError     **error)
446 {
447   FILE *f;
448
449   /* I guess you want binary mode; maybe you want text sometimes? */
450   f = fopen (filename, "rb");
451
452   if (f == NULL)
453     {
454       g_set_error (error,
455                    G_FILE_ERROR,
456                    g_file_error_from_errno (errno),
457                    _("Failed to open file '%s': %s"),
458                    filename, strerror (errno));
459       
460       return FALSE;
461     }
462   
463   return get_contents_stdio (filename, f, contents, length, error);
464 }
465
466 #endif
467
468 /**
469  * g_file_get_contents:
470  * @filename: a file to read contents from
471  * @contents: location to store an allocated string
472  * @length: location to store length in bytes of the contents
473  * @error: return location for a #GError
474  * 
475  * Reads an entire file into allocated memory, with good error
476  * checking. If @error is set, FALSE is returned, and @contents is set
477  * to NULL. If TRUE is returned, @error will not be set, and @contents
478  * will be set to the file contents.  The string stored in @contents
479  * will be nul-terminated, so for text files you can pass NULL for the
480  * @length argument.  The error domain is #G_FILE_ERROR. Possible
481  * error codes are those in the #GFileError enumeration.
482  *
483  * FIXME currently crashes if the file is too big to fit in memory;
484  * should probably use g_try_malloc() when we have that function.
485  * 
486  * Return value: TRUE on success, FALSE if error is set
487  **/
488 gboolean
489 g_file_get_contents (const gchar *filename,
490                      gchar      **contents,
491                      guint       *length,
492                      GError     **error)
493 {  
494   g_return_val_if_fail (filename != NULL, FALSE);
495   g_return_val_if_fail (contents != NULL, FALSE);
496
497   *contents = NULL;
498   if (length)
499     *length = 0;
500
501 #ifdef G_OS_WIN32
502   return get_contents_win32 (filename, contents, length, error);
503 #else
504   return get_contents_posix (filename, contents, length, error);
505 #endif
506 }
507
508 /*
509  * mkstemp() implementation is from the GNU C library.
510  * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
511  */
512 /**
513  * g_mkstemp:
514  * @tmpl: template filename
515  *
516  * Open a temporary file. See "man mkstemp" on most UNIX-like systems.
517  * This is a portability wrapper, which simply calls mkstemp() on systems
518  * that have it, and implements it in GLib otherwise.
519  *
520  * The parameter is a string that should match the rules for mktemp, i.e.
521  * end in "XXXXXX". The X string will be modified to form the name
522  * of a file that didn't exist.
523  *
524  * Return value: A file handle (as from open()) to the file
525  * opened for reading and writing. The file is opened in binary mode
526  * on platforms where there is a difference. The file handle should be
527  * closed with close(). In case of errors, -1 is returned.
528  */
529 int
530 g_mkstemp (char *tmpl)
531 {
532 #ifdef HAVE_MKSTEMP
533   return mkstemp (tmpl);
534 #else
535   int len;
536   char *XXXXXX;
537   int count, fd;
538   static const char letters[] =
539     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
540   static const int NLETTERS = sizeof (letters) - 1;
541   glong value;
542   GTimeVal tv;
543   static int counter = 0;
544
545   len = strlen (tmpl);
546   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
547     return -1;
548
549   /* This is where the Xs start.  */
550   XXXXXX = &tmpl[len - 6];
551
552   /* Get some more or less random data.  */
553   g_get_current_time (&tv);
554   value = (tv.tv_usec ^ tv.tv_sec) + counter++;
555
556   for (count = 0; count < 100; value += 7777, ++count)
557     {
558       glong v = value;
559
560       /* Fill in the random bits.  */
561       XXXXXX[0] = letters[v % NLETTERS];
562       v /= NLETTERS;
563       XXXXXX[1] = letters[v % NLETTERS];
564       v /= NLETTERS;
565       XXXXXX[2] = letters[v % NLETTERS];
566       v /= NLETTERS;
567       XXXXXX[3] = letters[v % NLETTERS];
568       v /= NLETTERS;
569       XXXXXX[4] = letters[v % NLETTERS];
570       v /= NLETTERS;
571       XXXXXX[5] = letters[v % NLETTERS];
572
573       fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
574
575       if (fd >= 0)
576         return fd;
577       else if (errno != EEXIST)
578         /* Any other error will apply also to other names we might
579          *  try, and there are 2^32 or so of them, so give up now.
580          */
581         return -1;
582     }
583
584   /* We got out of the loop because we ran out of combinations to try.  */
585   return -1;
586 #endif
587 }
588
589 /**
590  * g_file_open_tmp:
591  * @tmpl: Template for file name, as in g_mkstemp, basename only
592  * @name_used: location to store actual name used
593  * @error: return location for a #GError
594  *
595  * Opens a file for writing in the preferred directory for temporary
596  * files (as returned by g_get_tmp_dir()). 
597  *
598  * @tmpl should be a string ending with six 'X' characters, as the
599  * parameter to g_mkstemp() (or mkstemp()). However, unlike these
600  * functions, the template should only be a basename, no directory
601  * components are allowed. If template is NULL, a default template is
602  * used.
603  *
604  * Note that in contrast to g_mkstemp() (and mkstemp()) @tmpl is not
605  * modified, and might thus be a read-only literal string.
606  *
607  * The actual name used is returned in @name_used if non-NULL. This
608  * string should be freed with g_free when not needed any longer.
609  *
610  * Return value: A file handle (as from open()) to the file
611  * opened for reading and writing. The file is opened in binary mode
612  * on platforms where there is a difference. The file handle should be
613  * closed with close(). In case of errors, -1 is returned and
614  * @error will be set.
615  **/
616 int
617 g_file_open_tmp (const char *tmpl,
618                  char      **name_used,
619                  GError    **error)
620 {
621   int retval;
622   const char *tmpdir;
623   char *sep;
624   char *fulltemplate;
625
626   if (tmpl == NULL)
627     tmpl = ".XXXXXX";
628
629   if (strchr (tmpl, G_DIR_SEPARATOR)
630 #ifdef G_OS_WIN32
631       || strchr (tmpl, '/')
632 #endif
633                                     )
634     {
635       g_set_error (error,
636                    G_FILE_ERROR,
637                    G_FILE_ERROR_FAILED,
638                    _("Template '%s' illegal, should not contain a '%s'"),
639                    tmpl, G_DIR_SEPARATOR_S);
640
641       return -1;
642     }
643   
644   if (strlen (tmpl) < 6 ||
645       strcmp (tmpl + strlen (tmpl) - 6, "XXXXXX") != 0)
646     {
647       g_set_error (error,
648                    G_FILE_ERROR,
649                    G_FILE_ERROR_FAILED,
650                    _("Template '%s' doesn't end with XXXXXX"),
651                    tmpl);
652       return -1;
653     }
654
655   tmpdir = g_get_tmp_dir ();
656
657   if (tmpdir [strlen (tmpdir) - 1] == G_DIR_SEPARATOR)
658     sep = "";
659   else
660     sep = G_DIR_SEPARATOR_S;
661
662   fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);
663
664   retval = g_mkstemp (fulltemplate);
665
666   if (retval == -1)
667     {
668       g_set_error (error,
669                    G_FILE_ERROR,
670                    g_file_error_from_errno (errno),
671                    _("Failed to create file '%s': %s"),
672                    fulltemplate, strerror (errno));
673       g_free (fulltemplate);
674       return -1;
675     }
676
677   if (name_used)
678     *name_used = fulltemplate;
679   else
680     g_free (fulltemplate);
681
682   return retval;
683 }