Index: stream.c =================================================================== RCS file: /home/ncvs/projects/csup/stream.c,v retrieving revision 1.53 diff -u -r1.53 stream.c --- stream.c 11 Feb 2006 01:17:04 -0000 1.53 +++ stream.c 17 Mar 2006 23:33:50 -0000 @@ -81,6 +81,14 @@ STREAM_FLUSH_CLOSING } stream_flush_t; +/* Internal error codes */ +#define STREAM_ERR_READ (-1) /* Error reading from stream */ +#define STREAM_ERR_WRITE (-2) /* Error writing to stream */ +#define STREAM_ERR_FLUSH (-3) /* Error flushing stream */ +#define STREAM_ERR_SYNC (-4) /* Error synchronizing stream */ +#define STREAM_ERR_TRUNCATE (-5) /* Error truncating stream */ +#define STREAM_ERR_SEEK (-6) /* Error seeking in stream */ + /* * This is because buf_new() will always allocate size + 1 bytes, * so our buffer sizes will still be power of 2 values. @@ -96,6 +104,7 @@ struct stream { void *cookie; + int error; int fd; struct buf *rdbuf; struct buf *wrbuf; @@ -300,6 +309,7 @@ else stream->wrbuf = NULL; stream->cookie = NULL; + stream->error = 0; stream->fd = -1; stream->readfn = readfn; stream->writefn = writefn; @@ -437,8 +447,11 @@ rdbuf = stream->rdbuf; if (buf_count(rdbuf) == 0) { ret = stream_fill(stream); - if (ret <= 0) + if (ret <= 0) { + if (ret < 0) + stream->error = STREAM_ERR_READ; return (-1); + } } n = min(size, buf_count(rdbuf)); memcpy(buf, rdbuf->buf + rdbuf->off, n); @@ -475,14 +488,19 @@ buf = stream->rdbuf; if (buf_count(buf) == 0) { n = stream_fill(stream); - if (n <= 0) + if (n <= 0) { + if (n < 0) + stream->error = STREAM_ERR_READ; return (NULL); + } } cp = memchr(buf->buf + buf->off, '\n', buf_count(buf)); for (done = buf_count(buf); cp == NULL; done += n) { n = stream_fill(stream); - if (n < 0) + if (n < 0) { + stream->error = STREAM_ERR_READ; return (NULL); + } if (n == 0) /* Last line of the stream. */ cp = buf->buf + buf->off + buf->in - 1; @@ -518,8 +536,10 @@ buf_grow(buf, nbytes); if (nbytes > buf_avail(buf)) { error = stream_flush_int(stream, STREAM_FLUSH_NORMAL); - if (error) - return (-1); + if (error) { + stream->error = STREAM_ERR_WRITE; + return (error); + } } memcpy(buf->buf + buf->off + buf->in, src, nbytes); buf_more(buf, nbytes); @@ -546,8 +566,10 @@ buf_grow(buf, ret + 1); if ((unsigned)ret >= buf_avail(buf)) { error = stream_flush_int(stream, STREAM_FLUSH_NORMAL); - if (error) - return (-1); + if (error) { + stream->error = STREAM_ERR_WRITE; + return (error); + } } goto again; } @@ -562,6 +584,8 @@ int error; error = stream_flush_int(stream, STREAM_FLUSH_NORMAL); + if (error) + stream->error = STREAM_ERR_FLUSH; return (error); } @@ -611,6 +635,8 @@ if (error) return (-1); error = fsync(stream->fd); + if (error) + stream->error = STREAM_ERR_SYNC; return (error); } @@ -628,6 +654,8 @@ if (error) return (-1); error = ftruncate(stream->fd, size); + if (error) + stream->error = STREAM_ERR_TRUNCATE; return (error); } @@ -646,9 +674,13 @@ if (error) return (-1); error = fstat(stream->fd, &sb); - if (error) + if (error) { + stream->error = STREAM_ERR_TRUNCATE; return (-1); + } error = stream_truncate(stream, sb.st_size + off); + if (error) + stream->error = STREAM_ERR_TRUNCATE; return (error); } @@ -670,6 +702,8 @@ return (error); } error = lseek(stream->fd, 0, SEEK_SET); + if (error) + stream->error = STREAM_ERR_SEEK; return (error); } @@ -679,6 +713,36 @@ { return (stream->eof); +} + +/* Give a descriptive error message */ +int +stream_error(struct stream *stream) +{ + + switch (stream->error) { + case STREAM_ERR_READ: + lprintf(-1, "Error reading from stream\n"); + break; + case STREAM_ERR_WRITE: + lprintf(-1, "Error writing to stream\n"); + break; + case STREAM_ERR_FLUSH: + lprintf(-1, "Error flushing stream\n"); + break; + case STREAM_ERR_SEEK: + lprintf(-1, "Error seeking in stream\n"); + break; + case STREAM_ERR_SYNC: + lprintf(-1, "Error synchronizing stream\n"); + break; + case STREAM_ERR_TRUNCATE: + lprintf(-1, "Error truncating stream\n"); + break; + default: + assert(stream->error == 0); + } + return (stream->error); } /* Close a stream and free any resources held by it. */ Index: stream.h =================================================================== RCS file: /home/ncvs/projects/csup/stream.h,v retrieving revision 1.21 diff -u -r1.21 stream.h --- stream.h 10 Feb 2006 18:18:47 -0000 1.21 +++ stream.h 17 Mar 2006 23:33:50 -0000 @@ -65,6 +65,7 @@ int stream_truncate_rel(struct stream *, off_t); int stream_rewind(struct stream *); int stream_eof(struct stream *); +int stream_error(struct stream *); int stream_close(struct stream *); int stream_filter_start(struct stream *, stream_filter_t, void *); void stream_filter_stop(struct stream *);