autoupdate
[gnulib.git] / lib / read-file.c
index ac53dd4..6b655db 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -16,9 +16,7 @@
    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 *
@@ -92,7 +88,6 @@ internal_read_file (const char *filename, size_t * length, const char *mode)
   FILE *stream = fopen (filename, mode);
   char *out;
   int save_errno;
-  int rc;
 
   if (!stream)
     return NULL;
@@ -104,10 +99,10 @@ internal_read_file (const char *filename, size_t * length, const char *mode)
   if (fclose (stream) != 0)
     {
       if (out)
-       {
-         save_errno = errno;
-         free (out);
-       }
+        {
+          save_errno = errno;
+          free (out);
+        }
       errno = save_errno;
       return NULL;
     }