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