/* read-file.c -- read file contents into a string
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2009, 2010 Free Software Foundation, Inc.
Written by Simon Josefsson and Bruno Haible.
This program is free software; you can redistribute it and/or modify
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include <config.h>
#include "read-file.h"
char *
fread_file (FILE * stream, size_t * length)
{
- char *buf = malloc (1);
- size_t alloc = 1;
+ char *buf = NULL;
+ size_t alloc = 0;
size_t size = 0;
+ int save_errno;
- if (!buf)
- return NULL;
-
- while (!feof (stream))
+ for (;;)
{
size_t count;
+ size_t requested;
if (size + BUFSIZ + 1 > alloc)
- {
- char *new_buf;
-
- alloc += alloc / 2;
- if (alloc < size + BUFSIZ + 1)
- alloc = size + BUFSIZ + 1;
-
- new_buf = realloc (buf, alloc);
- if (!new_buf)
- {
- int save_errno = errno;
- free (buf);
- errno = save_errno;
- return NULL;
- }
-
- buf = new_buf;
- }
-
- count = fread (buf + size, 1, alloc - size - 1, stream);
- size += count;
+ {
+ char *new_buf;
- if (ferror (stream))
- {
- int save_errno = errno;
- free (buf);
- errno = save_errno;
- return NULL;
- }
- }
+ alloc += alloc / 2;
+ if (alloc < size + BUFSIZ + 1)
+ alloc = size + BUFSIZ + 1;
- buf[size] = '\0';
+ new_buf = realloc (buf, alloc);
+ if (!new_buf)
+ {
+ save_errno = errno;
+ break;
+ }
- *length = size;
+ buf = new_buf;
+ }
+
+ requested = alloc - size - 1;
+ count = fread (buf + size, 1, requested, stream);
+ size += count;
+
+ if (count != requested)
+ {
+ save_errno = errno;
+ if (ferror (stream))
+ break;
+ buf[size] = '\0';
+ *length = size;
+ return buf;
+ }
+ }
- return buf;
+ free (buf);
+ errno = save_errno;
+ return NULL;
}
static char *
FILE *stream = fopen (filename, mode);
char *out;
int save_errno;
- int rc;
if (!stream)
return NULL;
if (fclose (stream) != 0)
{
if (out)
- {
- save_errno = errno;
- free (out);
- }
+ {
+ save_errno = errno;
+ free (out);
+ }
errno = save_errno;
return NULL;
}