Commit 2bd9d1b8 authored by Niels Möller's avatar Niels Möller

Reorganized read_file loop.

parent 3ead2b97
2012-09-10 Niels Möller <nisse@lysator.liu.se>
* examples/io.c (read_file): Explicitly treat an empty file as an
error. Rearrange loop, check for short fread return value.
* desdata.c: Don't declare printf, include <stdio.h> instead. Also
deleted casts of printf return value.
......
......@@ -71,8 +71,7 @@ werror(const char *format, ...)
unsigned
read_file(const char *name, unsigned max_size, char **contents)
{
unsigned size;
unsigned done;
unsigned size, done;
char *buffer;
FILE *f;
......@@ -82,21 +81,10 @@ read_file(const char *name, unsigned max_size, char **contents)
werror("Opening `%s' failed: %s\n", name, strerror(errno));
return 0;
}
buffer = NULL;
if (max_size && max_size < 100)
size = max_size;
else
size = 100;
/* FIXME: The use of feof and ferror in this loop is a bit confused
(but I think it is still correct). We should check the return
value of fread, and call feof and/or ferror when we get a short
item count. */
size = 100;
for (done = 0;
(!max_size || done < max_size) && !feof(f);
size *= 2)
for (buffer = NULL, done = 0;; size *= 2)
{
char *p;
......@@ -118,8 +106,25 @@ read_file(const char *name, unsigned max_size, char **contents)
buffer = p;
done += fread(buffer + done, 1, size - done, f);
if (ferror(f))
goto fail;
if (done < size)
{
/* Short count means EOF or read error */
if (ferror(f))
{
fprintf (stderr, "Reading `%s' failed: %s\n",
name, strerror(errno));
goto fail;
}
if (done == 0)
/* Treat empty file as error */
goto fail;
break;
}
if (size == max_size)
break;
}
fclose(f);
......
......@@ -39,8 +39,11 @@ xalloc(size_t size);
void
werror(const char *format, ...) PRINTF_STYLE(1, 2);
/* If size is > 0, read at most that many bytes. If size == 0,
* read until EOF. Allocates the buffer dynamically. */
/* If size is > 0, read at most that many bytes. If size == 0, read
* until EOF. Allocates the buffer dynamically. An empty file is
* treated as an error; return value is zero, and no space is
* allocated. The returned data is NUL-terminated, for convenience. */
unsigned
read_file(const char *name, unsigned size, char **buffer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment