--- stream.c.orig Mon Jul 11 16:54:05 2005 +++ stream.c Fri Jul 15 18:42:24 2005 @@ -83,6 +83,12 @@ STREAM_FLUSH_CLOSING } stream_flush_t; +/* Stream flags */ +#define STREAM_RD 0x01 +#define STREAM_WR 0x02 +#define STREAM_EOF 0x04 +#define STREAM_ERR 0x08 + /* * This is because buf_new() will always allocate size + 1 bytes, * so our buffer sizes will still be power of 2 values. @@ -98,6 +104,7 @@ struct stream { int id; + int flags; struct buf *rdbuf; struct buf *wrbuf; stream_readfn_t readfn; @@ -301,17 +308,20 @@ stream = malloc(sizeof(struct stream)); if (stream == NULL) err(1, "malloc"); + stream->flags = 0; if (readfn == NULL && writefn == NULL) { errno = EINVAL; return (NULL); } - if (readfn != NULL) + if (readfn != NULL) { stream->rdbuf = buf_new(STREAM_BUFSIZ); - else + stream->flags |= STREAM_RD; + } else stream->rdbuf = NULL; - if (writefn != NULL) + if (writefn != NULL) { stream->wrbuf = buf_new(STREAM_BUFSIZ); - else + stream->flags |= STREAM_WR; + } else stream->wrbuf = NULL; stream->id = id; stream->readfn = readfn; @@ -357,6 +367,8 @@ ssize_t ret; size_t n; + if ((stream->flags & STREAM_RD) == 0) + return (-1); rdbuf = stream->rdbuf; if (buf_count(rdbuf) == 0) { ret = stream_fill(stream); @@ -395,6 +407,8 @@ ssize_t n; size_t done, size; + if ((stream->flags & STREAM_RD) == 0) + return NULL; buf = stream->rdbuf; if (buf_count(buf) == 0) { n = stream_fill(stream); @@ -436,6 +450,8 @@ struct buf *buf; int error; + if ((stream->flags & STREAM_WR) == 0) + return (-1); buf = stream->wrbuf; if (nbytes > buf_size(buf)) buf_grow(buf, nbytes); @@ -457,6 +473,8 @@ va_list ap; int error, ret; + if ((stream->flags & STREAM_WR) == 0) + return (-1); buf = stream->wrbuf; again: va_start(ap, fmt); @@ -495,9 +513,13 @@ struct buf *buf; int error; + if ((stream->flags & STREAM_WR) == 0) + return (-1); buf = stream->wrbuf; error = (*stream->filter->flushfn)(stream, buf, how); assert(buf_count(buf) == 0); + if (error) + stream->flags |= STREAM_ERR; return (error); } @@ -569,9 +591,9 @@ { int error; - if (stream->rdbuf != NULL) + if (stream->flags & STREAM_RD) buf_less(stream->rdbuf, buf_count(stream->rdbuf)); - if (stream->wrbuf != NULL) { + if (stream->flags & STREAM_WR) { error = stream_flush_int(stream, STREAM_FLUSH_NORMAL); if (error) return (error); @@ -590,7 +612,7 @@ return (0); error = 0; - if (stream->wrbuf != NULL) + if (stream->flags & STREAM_WR) error = stream_flush_int(stream, STREAM_FLUSH_CLOSING); stream_filter_fini(stream); if (stream->closefn != NULL) @@ -600,9 +622,9 @@ * not, we need to close the file descriptor. */ error = (*stream->closefn)(stream->id); - if (stream->rdbuf != NULL) + if (stream->flags & STREAM_RD) buf_free(stream->rdbuf); - if (stream->wrbuf != NULL) + if (stream->flags & STREAM_WR) buf_free(stream->wrbuf); free(stream); return (error); @@ -647,6 +669,10 @@ n = (*filter->fillfn)(stream, buf); assert((n > 0 && n == (signed)(buf_count(buf) - oldcount)) || (n <= 0 && buf_count(buf) == oldcount)); + if (n == 0) + stream->flags |= STREAM_EOF; + if (n < 0) + stream->flags |= STREAM_ERR; return (n); } @@ -719,6 +745,28 @@ { stream_filter_start(stream, STREAM_FILTER_NULL, NULL); +} + +/* Checks the EOF flag */ +int +stream_eof(struct stream *stream) +{ + if (stream->flags & STREAM_EOF) { + stream->flags &= ~STREAM_EOF; + return 1; + } + return 0; +} + +/* Checks for error */ +int +stream_error(struct stream *stream) +{ + if (stream->flags & STREAM_ERR) { + stream->flags &= ~STREAM_ERR; + return 1; + } + return 0; } /* The zlib stream filter implementation. */