Cosmetics.
[glib.git] / gfileutils.c
blob20a8d370a72319fb567ab8912c8cbe7764b8830f
1 /* gfileutils.c - File utility functions
3 * Copyright 2000 Red Hat, Inc.
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.
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.
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.
21 #include "config.h"
23 #include "glib.h"
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>
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 */
45 #ifndef S_ISREG
46 #define S_ISREG(mode) ((mode)&_S_IFREG)
47 #endif
49 #ifndef S_ISDIR
50 #define S_ISDIR(mode) ((mode)&_S_IFDIR)
51 #endif
53 #endif /* G_OS_WIN32 */
55 #ifndef S_ISLNK
56 #define S_ISLNK(x) 0
57 #endif
59 #define _(x) x
61 /**
62 * g_file_test:
63 * @filename: a filename to test
64 * @test: bitfield of #GFileTest flags
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.
73 * Return value: whether a test was TRUE
74 **/
75 gboolean
76 g_file_test (const gchar *filename,
77 GFileTest test)
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
85 struct stat s;
87 if (stat (filename, &s) < 0)
88 return FALSE;
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;
104 GQuark
105 g_file_error_quark (void)
107 static GQuark q = 0;
108 if (q == 0)
109 q = g_quark_from_static_string ("g-file-error-quark");
111 return q;
114 GFileError
115 g_file_error_from_errno (gint en)
117 switch (en)
119 #ifdef EEXIST
120 case EEXIST:
121 return G_FILE_ERROR_EXIST;
122 break;
123 #endif
125 #ifdef EISDIR
126 case EISDIR:
127 return G_FILE_ERROR_ISDIR;
128 break;
129 #endif
131 #ifdef EACCES
132 case EACCES:
133 return G_FILE_ERROR_ACCES;
134 break;
135 #endif
137 #ifdef ENAMETOOLONG
138 case ENAMETOOLONG:
139 return G_FILE_ERROR_NAMETOOLONG;
140 break;
141 #endif
143 #ifdef ENOENT
144 case ENOENT:
145 return G_FILE_ERROR_NOENT;
146 break;
147 #endif
149 #ifdef ENOTDIR
150 case ENOTDIR:
151 return G_FILE_ERROR_NOTDIR;
152 break;
153 #endif
155 #ifdef ENXIO
156 case ENXIO:
157 return G_FILE_ERROR_NXIO;
158 break;
159 #endif
161 #ifdef ENODEV
162 case ENODEV:
163 return G_FILE_ERROR_NODEV;
164 break;
165 #endif
167 #ifdef EROFS
168 case EROFS:
169 return G_FILE_ERROR_ROFS;
170 break;
171 #endif
173 #ifdef ETXTBSY
174 case ETXTBSY:
175 return G_FILE_ERROR_TXTBSY;
176 break;
177 #endif
179 #ifdef EFAULT
180 case EFAULT:
181 return G_FILE_ERROR_FAULT;
182 break;
183 #endif
185 #ifdef ELOOP
186 case ELOOP:
187 return G_FILE_ERROR_LOOP;
188 break;
189 #endif
191 #ifdef ENOSPC
192 case ENOSPC:
193 return G_FILE_ERROR_NOSPC;
194 break;
195 #endif
197 #ifdef ENOMEM
198 case ENOMEM:
199 return G_FILE_ERROR_NOMEM;
200 break;
201 #endif
203 #ifdef EMFILE
204 case EMFILE:
205 return G_FILE_ERROR_MFILE;
206 break;
207 #endif
209 #ifdef ENFILE
210 case ENFILE:
211 return G_FILE_ERROR_NFILE;
212 break;
213 #endif
215 #ifdef EBADF
216 case EBADF:
217 return G_FILE_ERROR_BADF;
218 break;
219 #endif
221 #ifdef EINVAL
222 case EINVAL:
223 return G_FILE_ERROR_INVAL;
224 break;
225 #endif
227 #ifdef EPIPE
228 case EPIPE:
229 return G_FILE_ERROR_PIPE;
230 break;
231 #endif
233 #ifdef EAGAIN
234 case EAGAIN:
235 return G_FILE_ERROR_AGAIN;
236 break;
237 #endif
239 #ifdef EINTR
240 case EINTR:
241 return G_FILE_ERROR_INTR;
242 break;
243 #endif
245 #ifdef EIO
246 case EIO:
247 return G_FILE_ERROR_IO;
248 break;
249 #endif
251 #ifdef EPERM
252 case EPERM:
253 return G_FILE_ERROR_PERM;
254 break;
255 #endif
257 default:
258 return G_FILE_ERROR_FAILED;
259 break;
263 static gboolean
264 get_contents_stdio (const gchar *filename,
265 FILE *f,
266 gchar **contents,
267 guint *length,
268 GError **error)
270 gchar buf[2048];
271 size_t bytes;
272 GString *str;
274 g_assert (f != NULL);
276 str = g_string_new ("");
278 while (!feof (f))
280 bytes = fread (buf, 1, 2048, f);
282 if (ferror (f))
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));
290 g_string_free (str, TRUE);
292 return FALSE;
295 g_string_append_len (str, buf, bytes);
298 fclose (f);
300 if (length)
301 *length = str->len;
303 *contents = g_string_free (str, FALSE);
305 return TRUE;
308 #ifndef G_OS_WIN32
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)
318 gchar *buf;
319 size_t bytes_read;
320 size_t size;
322 size = stat_buf->st_size;
324 buf = g_new (gchar, size + 1);
326 bytes_read = 0;
327 while (bytes_read < size)
329 gint rc;
331 rc = read (fd, buf + bytes_read, size - bytes_read);
333 if (rc < 0)
335 if (errno != EINTR)
337 close (fd);
339 g_free (buf);
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));
347 return FALSE;
350 else if (rc == 0)
351 break;
352 else
353 bytes_read += rc;
356 buf[bytes_read] = '\0';
358 if (length)
359 *length = bytes_read;
361 *contents = buf;
363 return TRUE;
366 static gboolean
367 get_contents_posix (const gchar *filename,
368 gchar **contents,
369 guint *length,
370 GError **error)
372 struct stat stat_buf;
373 gint fd;
375 fd = open (filename, O_RDONLY);
377 if (fd < 0)
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));
385 return FALSE;
388 /* I don't think this will ever fail, aside from ENOMEM, but. */
389 if (fstat (fd, &stat_buf) < 0)
391 close (fd);
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));
399 return FALSE;
402 if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
404 return get_contents_regfile (filename,
405 &stat_buf,
407 contents,
408 length,
409 error);
411 else
413 FILE *f;
415 f = fdopen (fd, "r");
417 if (f == NULL)
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));
425 return FALSE;
428 return get_contents_stdio (filename, f, contents, length, error);
432 #else /* G_OS_WIN32 */
434 static gboolean
435 get_contents_win32 (const gchar *filename,
436 gchar **contents,
437 guint *length,
438 GError **error)
440 FILE *f;
442 /* I guess you want binary mode; maybe you want text sometimes? */
443 f = fopen (filename, "rb");
445 if (f == NULL)
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));
453 return FALSE;
456 return get_contents_stdio (filename, f, contents, length, error);
459 #endif
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
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.
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.
479 * Return value: TRUE on success, FALSE if error is set
481 gboolean
482 g_file_get_contents (const gchar *filename,
483 gchar **contents,
484 guint *length,
485 GError **error)
487 g_return_val_if_fail (filename != NULL, FALSE);
488 g_return_val_if_fail (contents != NULL, FALSE);
490 *contents = NULL;
491 if (length)
492 *length = 0;
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