aboutsummaryrefslogtreecommitdiffstats
path: root/common/iobuf.c
diff options
context:
space:
mode:
authorNeal H. Walfield <[email protected]>2015-08-12 20:57:58 +0000
committerNeal H. Walfield <[email protected]>2015-08-20 12:16:20 +0000
commita250f73783c06d7789ac65a395d9247f4ab44c26 (patch)
treea4e983ddf17be92588f11c73bf6a04873a5cf8b3 /common/iobuf.c
parentcommon/iobuf.c: When requested, fill the buffer even if it is not empty. (diff)
downloadgnupg-a250f73783c06d7789ac65a395d9247f4ab44c26.tar.gz
gnupg-a250f73783c06d7789ac65a395d9247f4ab44c26.zip
common/iobuf.c: Improve iobuf_peek.
* common/iobuf.c (underflow): Take additional parameter clear_pending_eof. If not set, don't clear a pending eof when returning EOF. Update callers. (iobuf_peek): Fill the internal buffer, if needed, to be able to better satisfy any request. -- Signed-off-by: Neal H. Walfield <[email protected]>.
Diffstat (limited to 'common/iobuf.c')
-rw-r--r--common/iobuf.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/common/iobuf.c b/common/iobuf.c
index fed98397a..4f098859d 100644
--- a/common/iobuf.c
+++ b/common/iobuf.c
@@ -161,7 +161,7 @@ block_filter_ctx_t;
static int special_names_enabled;
/* Local prototypes. */
-static int underflow (iobuf_t a);
+static int underflow (iobuf_t a, int clear_pending_eof);
static int translate_file_handle (int fd, int for_write);
@@ -1762,7 +1762,7 @@ pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
* the first byte or -1 on EOF.
*/
static int
-underflow (iobuf_t a)
+underflow (iobuf_t a, int clear_pending_eof)
{
size_t len;
int rc;
@@ -1792,6 +1792,9 @@ underflow (iobuf_t a)
if (DBG_IOBUF)
log_debug ("iobuf-%d.%d: underflow: eof (pending eof)\n",
a->no, a->subno);
+ if (! clear_pending_eof)
+ return -1;
+
if (a->chain)
/* A filter follows this one. Free this filter. */
{
@@ -1865,7 +1868,7 @@ underflow (iobuf_t a)
a->filter = NULL;
a->filter_eof = 1;
- if (a->d.len == 0 && a->chain)
+ if (clear_pending_eof && a->d.len == 0 && a->chain)
/* We don't need to keep this filter around at all:
- we got an EOF
@@ -1967,7 +1970,7 @@ iobuf_readbyte (iobuf_t a)
{
c = a->d.buf[a->d.start++];
}
- else if ((c = underflow (a)) == -1)
+ else if ((c = underflow (a, 1)) == -1)
return -1; /* EOF */
a->nbytes++;
@@ -2017,7 +2020,7 @@ iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
}
if (n < buflen)
{
- if ((c = underflow (a)) == -1)
+ if ((c = underflow (a, 1)) == -1)
{
a->nbytes += n;
return n ? n : -1 /*EOF*/;
@@ -2034,29 +2037,42 @@ iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
-/****************
- * Have a look at the iobuf.
- * NOTE: This only works in special cases.
- */
int
iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
{
int n = 0;
- if (a->filter_eof)
- return -1;
+ assert (buflen > 0);
+ assert (a->use == IOBUF_INPUT);
- if (!(a->d.start < a->d.len))
+ if (buflen > a->d.size)
+ /* We can't peek more than we can buffer. */
+ buflen = a->d.size;
+
+ /* Try to fill the internal buffer with enough data to satisfy the
+ request. */
+ while (buflen > a->d.len - a->d.start)
{
- if (underflow (a) == -1)
- return -1;
- /* And unget this character. */
+ if (underflow (a, 0) == -1)
+ /* EOF. We can't read any more. */
+ break;
+
+ /* Underflow consumes the first character (it's the return
+ value). unget() it by resetting the "file position". */
assert (a->d.start == 1);
a->d.start = 0;
}
- for (n = 0; n < buflen && (a->d.start + n) < a->d.len; n++, buf++)
- *buf = a->d.buf[n];
+ n = a->d.len - a->d.start;
+ if (n > buflen)
+ n = buflen;
+
+ if (n == 0)
+ /* EOF. */
+ return -1;
+
+ memcpy (buf, &a->d.buf[a->d.start], n);
+
return n;
}