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

Reorganized read_file loop.

parent 3ead2b97
2012-09-10 Niels Möller <nisse@lysator.liu.se> 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 * desdata.c: Don't declare printf, include <stdio.h> instead. Also
deleted casts of printf return value. deleted casts of printf return value.
......
...@@ -71,8 +71,7 @@ werror(const char *format, ...) ...@@ -71,8 +71,7 @@ werror(const char *format, ...)
unsigned unsigned
read_file(const char *name, unsigned max_size, char **contents) read_file(const char *name, unsigned max_size, char **contents)
{ {
unsigned size; unsigned size, done;
unsigned done;
char *buffer; char *buffer;
FILE *f; FILE *f;
...@@ -82,21 +81,10 @@ read_file(const char *name, unsigned max_size, char **contents) ...@@ -82,21 +81,10 @@ read_file(const char *name, unsigned max_size, char **contents)
werror("Opening `%s' failed: %s\n", name, strerror(errno)); werror("Opening `%s' failed: %s\n", name, strerror(errno));
return 0; return 0;
} }
buffer = NULL;
if (max_size && max_size < 100) 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. */
for (done = 0; for (buffer = NULL, done = 0;; size *= 2)
(!max_size || done < max_size) && !feof(f);
size *= 2)
{ {
char *p; char *p;
...@@ -118,8 +106,25 @@ read_file(const char *name, unsigned max_size, char **contents) ...@@ -118,8 +106,25 @@ read_file(const char *name, unsigned max_size, char **contents)
buffer = p; buffer = p;
done += fread(buffer + done, 1, size - done, f); done += fread(buffer + done, 1, size - done, f);
if (ferror(f)) if (done < size)
goto fail; {
/* 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); fclose(f);
......
...@@ -39,8 +39,11 @@ xalloc(size_t size); ...@@ -39,8 +39,11 @@ xalloc(size_t size);
void void
werror(const char *format, ...) PRINTF_STYLE(1, 2); werror(const char *format, ...) PRINTF_STYLE(1, 2);
/* If size is > 0, read at most that many bytes. If size == 0, /* If size is > 0, read at most that many bytes. If size == 0, read
* read until EOF. Allocates the buffer dynamically. */ * 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 unsigned
read_file(const char *name, unsigned size, char **buffer); 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