publically define GSignalInvocationHint structure that gets passed in 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 <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 #define _(x) x
60
61 /**
62  * g_file_test:
63  * @filename: a filename to test
64  * @test: bitfield of #GFileTest flags
65  * 
66  * Returns TRUE if any of the tests in the bitfield @test are
67  * TRUE. For example, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)
68  * will return TRUE if the file exists; the check whether it's
69  * a directory doesn't matter since the existence test is TRUE.
70  * With the current set of available tests, there's no point
71  * passing in more than one test at a time.
72  *
73  * Return value: whether a test was TRUE
74  **/
75 gboolean
76 g_file_test (const gchar *filename,
77              GFileTest    test)
78 {
79   if (test & G_FILE_TEST_EXISTS)
80     return (access (filename, F_OK) == 0);
81   else if (test & G_FILE_TEST_IS_EXECUTABLE)
82     return (access (filename, X_OK) == 0);
83   else
84     {
85       struct stat s;
86       
87       if (stat (filename, &s) < 0)
88         return FALSE;
89
90       if ((test & G_FILE_TEST_IS_REGULAR) &&
91           S_ISREG (s.st_mode))
92         return TRUE;
93       else if ((test & G_FILE_TEST_IS_DIR) &&
94                S_ISDIR (s.st_mode))
95         return TRUE;
96       else if ((test & G_FILE_TEST_IS_SYMLINK) &&
97                S_ISLNK (s.st_mode))
98         return TRUE;
99       else
100         return FALSE;
101     }
102 }
103
104 GQuark
105 g_file_error_quark (void)
106 {
107   static GQuark q = 0;
108   if (q == 0)
109     q = g_quark_from_static_string ("g-file-error-quark");
110
111   return q;
112 }
113
114 GFileError
115 g_file_error_from_errno (gint en)
116 {
117   switch (en)
118     {
119 #ifdef EEXIST
120     case EEXIST:
121       return G_FILE_ERROR_EXIST;
122       break;
123 #endif
124
125 #ifdef EISDIR
126     case EISDIR:
127       return G_FILE_ERROR_ISDIR;
128       break;
129 #endif
130
131 #ifdef EACCES
132     case EACCES:
133       return G_FILE_ERROR_ACCES;
134       break;
135 #endif
136
137 #ifdef ENAMETOOLONG
138     case ENAMETOOLONG:
139       return G_FILE_ERROR_NAMETOOLONG;
140       break;
141 #endif
142
143 #ifdef ENOENT
144     case ENOENT:
145       return G_FILE_ERROR_NOENT;
146       break;
147 #endif
148
149 #ifdef ENOTDIR
150     case ENOTDIR:
151       return G_FILE_ERROR_NOTDIR;
152       break;
153 #endif
154
155 #ifdef ENXIO
156     case ENXIO:
157       return G_FILE_ERROR_NXIO;
158       break;
159 #endif
160
161 #ifdef ENODEV
162     case ENODEV:
163       return G_FILE_ERROR_NODEV;
164       break;
165 #endif
166
167 #ifdef EROFS
168     case EROFS:
169       return G_FILE_ERROR_ROFS;
170       break;
171 #endif
172
173 #ifdef ETXTBSY
174     case ETXTBSY:
175       return G_FILE_ERROR_TXTBSY;
176       break;
177 #endif
178
179 #ifdef EFAULT
180     case EFAULT:
181       return G_FILE_ERROR_FAULT;
182       break;
183 #endif
184
185 #ifdef ELOOP
186     case ELOOP:
187       return G_FILE_ERROR_LOOP;
188       break;
189 #endif
190
191 #ifdef ENOSPC
192     case ENOSPC:
193       return G_FILE_ERROR_NOSPC;
194       break;
195 #endif
196
197 #ifdef ENOMEM
198     case ENOMEM:
199       return G_FILE_ERROR_NOMEM;
200       break;
201 #endif
202
203 #ifdef EMFILE
204     case EMFILE:
205       return G_FILE_ERROR_MFILE;
206       break;
207 #endif
208
209 #ifdef ENFILE
210     case ENFILE:
211       return G_FILE_ERROR_NFILE;
212       break;
213 #endif
214
215 #ifdef EBADF
216     case EBADF:
217       return G_FILE_ERROR_BADF;
218       break;
219 #endif
220
221 #ifdef EINVAL
222     case EINVAL:
223       return G_FILE_ERROR_INVAL;
224       break;
225 #endif
226
227 #ifdef EPIPE
228     case EPIPE:
229       return G_FILE_ERROR_PIPE;
230       break;
231 #endif
232
233 #ifdef EAGAIN
234     case EAGAIN:
235       return G_FILE_ERROR_AGAIN;
236       break;
237 #endif
238
239 #ifdef EINTR
240     case EINTR:
241       return G_FILE_ERROR_INTR;
242       break;
243 #endif
244
245 #ifdef EIO
246     case EIO:
247       return G_FILE_ERROR_IO;
248       break;
249 #endif
250
251 #ifdef EPERM
252     case EPERM:
253       return G_FILE_ERROR_PERM;
254       break;
255 #endif
256       
257     default:
258       return G_FILE_ERROR_FAILED;
259       break;
260     }
261 }
262
263 static gboolean
264 get_contents_stdio (const gchar *filename,
265                     FILE        *f,
266                     gchar      **contents,
267                     guint       *length,
268                     GError     **error)
269 {
270   gchar buf[2048];
271   size_t bytes;
272   GString *str;
273
274   g_assert (f != NULL);
275   
276   str = g_string_new ("");
277   
278   while (!feof (f))
279     {
280       bytes = fread (buf, 1, 2048, f);
281       
282       if (ferror (f))
283         {
284           g_set_error (error,
285                        G_FILE_ERROR,
286                        g_file_error_from_errno (errno),
287                        _("Error reading file '%s': %s"),
288                        filename, strerror (errno));
289
290           g_string_free (str, TRUE);
291           
292           return FALSE;
293         }
294
295       g_string_append_len (str, buf, bytes);
296     }
297
298   fclose (f);
299
300   if (length)
301     *length = str->len;
302   
303   *contents = g_string_free (str, FALSE);
304
305   return TRUE;  
306 }
307
308 #ifndef G_OS_WIN32
309
310 static gboolean
311 get_contents_regfile (const gchar *filename,
312                       struct stat *stat_buf,
313                       gint         fd,
314                       gchar      **contents,
315                       guint       *length,
316                       GError     **error)
317 {
318   gchar *buf;
319   size_t bytes_read;
320   size_t size;
321       
322   size = stat_buf->st_size;
323
324   buf = g_new (gchar, size + 1);
325       
326   bytes_read = 0;
327   while (bytes_read < size)
328     {
329       gint rc;
330           
331       rc = read (fd, buf + bytes_read, size - bytes_read);
332
333       if (rc < 0)
334         {
335           if (errno != EINTR) 
336             {
337               close (fd);
338
339               g_free (buf);
340                   
341               g_set_error (error,
342                            G_FILE_ERROR,
343                            g_file_error_from_errno (errno),
344                            _("Failed to read from file '%s': %s"),
345                            filename, strerror (errno));
346
347               return FALSE;
348             }
349         }
350       else if (rc == 0)
351         break;
352       else
353         bytes_read += rc;
354     }
355       
356   buf[bytes_read] = '\0';
357
358   if (length)
359     *length = bytes_read;
360   
361   *contents = buf;
362
363   return TRUE;
364 }
365
366 static gboolean
367 get_contents_posix (const gchar *filename,
368                     gchar      **contents,
369                     guint       *length,
370                     GError     **error)
371 {
372   struct stat stat_buf;
373   gint fd;
374   
375   fd = open (filename, O_RDONLY);
376
377   if (fd < 0)
378     {
379       g_set_error (error,
380                    G_FILE_ERROR,
381                    g_file_error_from_errno (errno),
382                    _("Failed to open file '%s': %s"),
383                    filename, strerror (errno));
384
385       return FALSE;
386     }
387
388   /* I don't think this will ever fail, aside from ENOMEM, but. */
389   if (fstat (fd, &stat_buf) < 0)
390     {
391       close (fd);
392       
393       g_set_error (error,
394                    G_FILE_ERROR,
395                    g_file_error_from_errno (errno),
396                    _("Failed to get attributes of file '%s': fstat() failed: %s"),
397                    filename, strerror (errno));
398
399       return FALSE;
400     }
401
402   if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
403     {
404       return get_contents_regfile (filename,
405                                    &stat_buf,
406                                    fd,
407                                    contents,
408                                    length,
409                                    error);
410     }
411   else
412     {
413       FILE *f;
414
415       f = fdopen (fd, "r");
416       
417       if (f == NULL)
418         {
419           g_set_error (error,
420                        G_FILE_ERROR,
421                        g_file_error_from_errno (errno),
422                        _("Failed to open file '%s': fdopen() failed: %s"),
423                        filename, strerror (errno));
424           
425           return FALSE;
426         }
427   
428       return get_contents_stdio (filename, f, contents, length, error);
429     }
430 }
431
432 #else  /* G_OS_WIN32 */
433
434 static gboolean
435 get_contents_win32 (const gchar *filename,
436                     gchar      **contents,
437                     guint       *length,
438                     GError     **error)
439 {
440   FILE *f;
441
442   /* I guess you want binary mode; maybe you want text sometimes? */
443   f = fopen (filename, "rb");
444
445   if (f == NULL)
446     {
447       g_set_error (error,
448                    G_FILE_ERROR,
449                    g_file_error_from_errno (errno),
450                    _("Failed to open file '%s': %s"),
451                    filename, strerror (errno));
452       
453       return FALSE;
454     }
455   
456   return get_contents_stdio (filename, f, contents, length, error);
457 }
458
459 #endif
460
461 /**
462  * g_file_get_contents:
463  * @filename: a file to read contents from
464  * @contents: location to store an allocated string
465  * @length: location to store length in bytes of the contents
466  * @error: return location for a #GError
467  * 
468  * Reads an entire file into allocated memory, with good error
469  * checking. If @error is set, FALSE is returned, and @contents is set
470  * to NULL. If TRUE is returned, @error will not be set, and @contents
471  * will be set to the file contents.  The string stored in @contents
472  * will be nul-terminated, so for text files you can pass NULL for the
473  * @length argument.  The error domain is #G_FILE_ERROR. Possible
474  * error codes are those in the #GFileError enumeration.
475  *
476  * FIXME currently crashes if the file is too big to fit in memory;
477  * should probably use g_try_malloc() when we have that function.
478  * 
479  * Return value: TRUE on success, FALSE if error is set
480  **/
481 gboolean
482 g_file_get_contents (const gchar *filename,
483                      gchar      **contents,
484                      guint       *length,
485                      GError     **error)
486 {  
487   g_return_val_if_fail (filename != NULL, FALSE);
488   g_return_val_if_fail (contents != NULL, FALSE);
489
490   *contents = NULL;
491   if (length)
492     *length = 0;
493
494 #ifdef G_OS_WIN32
495   return get_contents_win32 (filename, contents, length, error);
496 #else
497   return get_contents_posix (filename, contents, length, error);
498 #endif
499 }