summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/lib/getline.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/lib/getline.c')
-rw-r--r--contrib/cvs/lib/getline.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/contrib/cvs/lib/getline.c b/contrib/cvs/lib/getline.c
index 5f4fba6..5b63fc1 100644
--- a/contrib/cvs/lib/getline.c
+++ b/contrib/cvs/lib/getline.c
@@ -21,6 +21,7 @@ General Public License for more details. */
#include <sys/types.h>
#include <stdio.h>
#include <assert.h>
+#include <errno.h>
#if STDC_HEADERS
#include <stdlib.h>
@@ -35,7 +36,9 @@ char *malloc (), *realloc ();
+ OFFSET (and null-terminate it). *LINEPTR is a pointer returned from
malloc (or NULL), pointing to *N characters of space. It is realloc'd
as necessary. Return the number of characters read (not including the
- null terminator), or -1 on error or EOF. */
+ null terminator), or -1 on error or EOF. On a -1 return, the caller
+ should check feof(), if not then errno has been set to indicate
+ the error. */
int
getstr (lineptr, n, stream, terminator, offset)
@@ -50,14 +53,20 @@ getstr (lineptr, n, stream, terminator, offset)
int ret;
if (!lineptr || !n || !stream)
- return -1;
+ {
+ errno = EINVAL;
+ return -1;
+ }
if (!*lineptr)
{
*n = MIN_CHUNK;
*lineptr = malloc (*n);
if (!*lineptr)
- return -1;
+ {
+ errno = ENOMEM;
+ return -1;
+ }
}
nchars_avail = *n - offset;
@@ -65,8 +74,11 @@ getstr (lineptr, n, stream, terminator, offset)
for (;;)
{
+ int save_errno;
register int c = getc (stream);
+ save_errno = errno;
+
/* We always want at least one char left in the buffer, since we
always (unless we get an error while reading the first char)
NUL-terminate the line buffer. */
@@ -82,12 +94,24 @@ getstr (lineptr, n, stream, terminator, offset)
nchars_avail = *n + *lineptr - read_pos;
*lineptr = realloc (*lineptr, *n);
if (!*lineptr)
- return -1;
+ {
+ errno = ENOMEM;
+ return -1;
+ }
read_pos = *n - nchars_avail + *lineptr;
assert((*lineptr + *n) == (read_pos + nchars_avail));
}
- if (c == EOF || ferror (stream))
+ if (ferror (stream))
+ {
+ /* Might like to return partial line, but there is no
+ place for us to store errno. And we don't want to just
+ lose errno. */
+ errno = save_errno;
+ return -1;
+ }
+
+ if (c == EOF)
{
/* Return partial line, if any. */
if (read_pos == *lineptr)
OpenPOWER on IntegriCloud