#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include "linebuffer.h"
#include "unlocked-io.h"
void
initbuffer (struct linebuffer *linebuffer)
{
- linebuffer->length = 0;
- linebuffer->size = 200;
- linebuffer->buffer = xmalloc (linebuffer->size);
+ memset (linebuffer, 0, sizeof *linebuffer);
}
/* Read an arbitrarily long line of text from STREAM into LINEBUFFER.
that ends in a non-newline character. Do not null terminate.
Therefore the stream can contain NUL bytes, and the length
(including the newline) is returned in linebuffer->length.
- Return NULL upon error, or when STREAM is empty.
+ Return NULL when stream is empty. Return NULL and set errno upon
+ error; callers can distinguish this case from the empty case by
+ invoking ferror (stream).
Otherwise, return LINEBUFFER. */
struct linebuffer *
readlinebuffer (struct linebuffer *linebuffer, FILE *stream)
char *p = linebuffer->buffer;
char *end = buffer + linebuffer->size; /* Sentinel. */
- if (feof (stream) || ferror (stream))
+ if (feof (stream))
return NULL;
do
c = getc (stream);
if (c == EOF)
{
- if (p == buffer)
+ if (p == buffer || ferror (stream))
return NULL;
if (p[-1] == '\n')
break;
}
if (p == end)
{
- linebuffer->size *= 2;
- buffer = xrealloc (buffer, linebuffer->size);
- p = p - linebuffer->buffer + buffer;
+ size_t oldsize = linebuffer->size;
+ buffer = x2realloc (buffer, &linebuffer->size);
+ p = buffer + oldsize;
linebuffer->buffer = buffer;
end = buffer + linebuffer->size;
}
return linebuffer;
}
-/* Free linebuffer LINEBUFFER and its data, all allocated with malloc. */
+/* Free the buffer that was allocated for linebuffer LINEBUFFER. */
void
freebuffer (struct linebuffer *linebuffer)
{
free (linebuffer->buffer);
- free (linebuffer);
}