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.
unsigned
read_file(const char *name, unsigned max_size, char **contents)
{
- unsigned size;
- unsigned done;
+ unsigned size, done;
char *buffer;
FILE *f;
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;
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);
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);