iostream.c: Fix ast_iostream_gets() needlessly returning failure.

Providing a buffer larger than the internal buffer of ast_iostream_gets()
fails to get lines longer than the internal buffer.

* Made ast_iostream_gets() fill the supplied buffer with read data until
either a '\n' is found or the supplied buffer is filled just like fgets().

Change-Id: If18b3f6ee500e22f0633a68779ed09f7e0f305ed
This commit is contained in:
Richard Mudgett 2018-08-29 16:14:46 -05:00
parent b07da4b472
commit f657793ee4
1 changed files with 36 additions and 23 deletions

View File

@ -285,46 +285,59 @@ ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t coun
ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buffer, size_t size) ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buffer, size_t size)
{ {
ssize_t r; size_t remaining = size;
ssize_t accum_size = 0;
ssize_t len;
char *newline; char *newline;
do { for (;;) {
/* Search for newline */ /* Search for newline */
newline = memchr(stream->rbufhead, '\n', stream->rbuflen); newline = memchr(stream->rbufhead, '\n', stream->rbuflen);
if (newline) { if (newline) {
r = newline - stream->rbufhead + 1; len = newline - stream->rbufhead + 1;
if (r > size-1) { if (len > remaining - 1) {
r = size-1; len = remaining - 1;
} }
break; break;
} }
/* Enough data? */ /* Enough buffered line data to fill request buffer? */
if (stream->rbuflen >= size - 1) { if (stream->rbuflen >= remaining - 1) {
r = size - 1; len = remaining - 1;
break; break;
} }
if (stream->rbuflen) {
/* Try to fill in line buffer */ /* Put leftover buffered line data into request buffer */
if (stream->rbuflen && stream->rbuf != stream->rbufhead) { memcpy(buffer + accum_size, stream->rbufhead, stream->rbuflen);
memmove(&stream->rbuf, stream->rbufhead, stream->rbuflen); remaining -= stream->rbuflen;
accum_size += stream->rbuflen;
stream->rbuflen = 0;
} }
stream->rbufhead = stream->rbuf; stream->rbufhead = stream->rbuf;
r = iostream_read(stream, stream->rbufhead + stream->rbuflen, sizeof(stream->rbuf) - stream->rbuflen); len = iostream_read(stream, stream->rbuf, sizeof(stream->rbuf));
if (r <= 0) { if (len == 0) {
return r; /* Nothing new was read. Return whatever we have accumulated. */
break;
} }
stream->rbuflen += r; if (len < 0) {
} while (1); if (accum_size) {
/* We have an accumulated buffer so return that instead. */
len = 0;
break;
}
return len;
}
stream->rbuflen += len;
}
/* Return r bytes with termination byte */ /* Return read buffer string length */
memcpy(buffer, stream->rbufhead, r); memcpy(buffer + accum_size, stream->rbufhead, len);
buffer[r] = 0; buffer[accum_size + len] = 0;
stream->rbuflen -= r; stream->rbuflen -= len;
stream->rbufhead += r; stream->rbufhead += len;
return r; return accum_size + len;
} }
ssize_t ast_iostream_discard(struct ast_iostream *stream, size_t size) ssize_t ast_iostream_discard(struct ast_iostream *stream, size_t size)