dovecot-1.2: Input streams: Improved error handling and added mo...

dovecot at dovecot.org dovecot at dovecot.org
Sat Sep 13 13:06:10 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/40a07553606c
changeset: 8196:40a07553606c
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Sep 13 13:06:06 2008 +0300
description:
Input streams: Improved error handling and added more asserts.

diffstat:

11 files changed, 63 insertions(+), 36 deletions(-)
src/lib-mail/istream-header-filter.c          |    5 +++
src/lib-storage/index/mbox/istream-raw-mbox.c |    8 +++++-
src/lib/istream-concat.c                      |    2 -
src/lib/istream-crlf.c                        |    3 +-
src/lib/istream-file.c                        |    5 +--
src/lib/istream-limit.c                       |    3 +-
src/lib/istream-mmap.c                        |    5 +--
src/lib/istream-seekable.c                    |   23 ++++++++++-------
src/lib/istream-tee.c                         |    1 
src/lib/istream.c                             |   33 +++++++++++++++++++------
src/plugins/zlib/istream-zlib.c               |   11 +-------

diffs (truncated from 398 to 300 lines):

diff -r 413c70b0ae1d -r 40a07553606c src/lib-mail/istream-header-filter.c
--- a/src/lib-mail/istream-header-filter.c	Sat Sep 13 13:02:13 2008 +0300
+++ b/src/lib-mail/istream-header-filter.c	Sat Sep 13 13:06:06 2008 +0300
@@ -92,6 +92,7 @@ read_mixed(struct header_filter_istream 
 
 	mstream->istream.buffer = buffer_get_data(mstream->hdr_buf, &pos);
 	ret = (ssize_t)(pos - mstream->istream.pos - mstream->istream.skip);
+	i_assert(ret > 0);
 	mstream->istream.pos = pos;
 	return ret;
 }
@@ -244,8 +245,10 @@ static ssize_t read_header(struct header
 	ret = (ssize_t)(pos - mstream->istream.pos - mstream->istream.skip);
 	mstream->istream.pos = pos;
 
-	if (hdr_ret == 0)
+	if (hdr_ret == 0) {
+		i_assert(ret > 0);
 		return ret;
+	}
 
 	if (hdr == NULL) {
 		/* finished */
diff -r 413c70b0ae1d -r 40a07553606c src/lib-storage/index/mbox/istream-raw-mbox.c
--- a/src/lib-storage/index/mbox/istream-raw-mbox.c	Sat Sep 13 13:02:13 2008 +0300
+++ b/src/lib-storage/index/mbox/istream-raw-mbox.c	Sat Sep 13 13:06:06 2008 +0300
@@ -61,7 +61,11 @@ static int mbox_read_from_line(struct ra
 
 	while ((p = memchr(buf+skip, '\n', pos-skip)) == NULL) {
 		if (i_stream_read(rstream->istream.parent) < 0) {
-			/* EOF - shouldn't happen */
+			/* EOF shouldn't happen */
+			rstream->istream.istream.eof =
+				rstream->istream.parent->eof;
+			rstream->istream.istream.stream_errno =
+				rstream->istream.parent->stream_errno;
 			return -1;
 		}
 		buf = i_stream_get_data(rstream->istream.parent, &pos);
@@ -79,6 +83,7 @@ static int mbox_read_from_line(struct ra
 	    mbox_from_parse(buf+5, pos-5, &received_time, &tz, &sender) < 0) {
 		/* broken From - should happen only at beginning of
 		   file if this isn't a mbox.. */
+		rstream->istream.istream.stream_errno = EBADMSG;
 		return -1;
 	}
 
@@ -302,6 +307,7 @@ static ssize_t i_stream_raw_mbox_read(st
 			rstream->hdr_offset + rstream->mail_size);
 		rstream->eof = TRUE;
 		rstream->corrupted = TRUE;
+		rstream->istream.istream.stream_errno = EBADMSG;
 		return -1;
 	}
 
diff -r 413c70b0ae1d -r 40a07553606c src/lib/istream-concat.c
--- a/src/lib/istream-concat.c	Sat Sep 13 13:02:13 2008 +0300
+++ b/src/lib/istream-concat.c	Sat Sep 13 13:06:06 2008 +0300
@@ -138,6 +138,7 @@ static ssize_t i_stream_concat_read(stru
 		}
 
 		stream->istream.eof = cstream->cur_input->eof && last_stream;
+		i_assert(ret != -1 || stream->istream.eof);
 		data = i_stream_get_data(cstream->cur_input, &pos);
 	}
 
@@ -198,7 +199,6 @@ static void i_stream_concat_seek(struct 
 {
 	struct concat_istream *cstream = (struct concat_istream *)stream;
 
-	stream->istream.stream_errno = 0;
 	stream->istream.v_offset = v_offset;
 	stream->skip = stream->pos = 0;
 	cstream->prev_size = 0;
diff -r 413c70b0ae1d -r 40a07553606c src/lib/istream-crlf.c
--- a/src/lib/istream-crlf.c	Sat Sep 13 13:02:13 2008 +0300
+++ b/src/lib/istream-crlf.c	Sat Sep 13 13:06:06 2008 +0300
@@ -87,7 +87,7 @@ static ssize_t i_stream_crlf_read_crlf(s
 	i_stream_skip(stream->parent, i);
 
 	ret = dest - stream->pos;
-	i_assert(ret != 0);
+	i_assert(ret > 0);
 	stream->pos = dest;
 	return ret;
 }
@@ -147,6 +147,7 @@ static ssize_t i_stream_crlf_read_lf(str
 		i_assert(cstream->pending_cr && size == 1);
 		return i_stream_crlf_read_lf(stream);
 	}
+	i_assert(ret > 0);
 	stream->pos = dest;
 	return ret;
 }
diff -r 413c70b0ae1d -r 40a07553606c src/lib/istream-file.c
--- a/src/lib/istream-file.c	Sat Sep 13 13:02:13 2008 +0300
+++ b/src/lib/istream-file.c	Sat Sep 13 13:06:06 2008 +0300
@@ -46,7 +46,6 @@ static ssize_t i_stream_file_read(struct
 	size_t size;
 	ssize_t ret;
 
-	stream->istream.stream_errno = 0;
 	if (!i_stream_get_buffer_space(stream, 1, &size))
 		return -2;
 
@@ -78,7 +77,7 @@ static ssize_t i_stream_file_read(struct
 			i_assert(!stream->istream.blocking);
 			ret = 0;
 		} else {
-			stream->istream.eof = TRUE;
+			i_assert(errno != 0);
 			stream->istream.stream_errno = errno;
 			return -1;
 		}
@@ -101,6 +100,7 @@ static ssize_t i_stream_file_read(struct
 
 	stream->pos += ret;
 	i_assert(ret != 0 || !fstream->file);
+	i_assert(ret != -1);
 	return ret;
 }
 
@@ -117,7 +117,6 @@ static void i_stream_file_seek(struct is
 		fstream->skip_left += v_offset - stream->istream.v_offset;
 	}
 
-	stream->istream.stream_errno = 0;
 	stream->istream.v_offset = v_offset;
 	stream->skip = stream->pos = 0;
 	fstream->seen_eof = FALSE;
diff -r 413c70b0ae1d -r 40a07553606c src/lib/istream-limit.c
--- a/src/lib/istream-limit.c	Sat Sep 13 13:02:13 2008 +0300
+++ b/src/lib/istream-limit.c	Sat Sep 13 13:06:06 2008 +0300
@@ -80,6 +80,8 @@ static ssize_t i_stream_limit_read(struc
 	ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) :
 		(ret == 0 ? 0 : -1);
 	stream->pos = pos;
+	i_assert(ret != -1 || stream->istream.eof ||
+		 stream->istream.stream_errno != 0);
 	return ret;
 }
 
@@ -90,7 +92,6 @@ static void i_stream_limit_seek(struct i
 
 	i_assert(v_offset <= lstream->v_size);
 
-	stream->istream.stream_errno = 0;
 	stream->istream.v_offset = v_offset;
 	stream->skip = stream->pos = 0;
 }
diff -r 413c70b0ae1d -r 40a07553606c src/lib/istream-mmap.c
--- a/src/lib/istream-mmap.c	Sat Sep 13 13:02:13 2008 +0300
+++ b/src/lib/istream-mmap.c	Sat Sep 13 13:06:06 2008 +0300
@@ -65,8 +65,6 @@ static ssize_t i_stream_mmap_read(struct
 	struct mmap_istream *mstream = (struct mmap_istream *) stream;
 	size_t aligned_skip;
 	uoff_t top;
-
-	stream->istream.stream_errno = 0;
 
 	if (stream->pos < stream->buffer_size) {
 		/* more bytes available without needing to mmap() */
@@ -108,6 +106,7 @@ static ssize_t i_stream_mmap_read(struct
 			mmap(NULL, stream->buffer_size, PROT_READ, MAP_PRIVATE,
 			     stream->fd, mstream->mmap_offset);
 		if (mstream->mmap_base == MAP_FAILED) {
+			i_assert(errno != 0);
 			stream->istream.stream_errno = errno;
 			mstream->mmap_base = NULL;
 			stream->buffer = NULL;
@@ -126,7 +125,7 @@ static ssize_t i_stream_mmap_read(struct
 	}
 
 	stream->pos = stream->buffer_size;
-	i_assert(stream->pos - stream->skip != 0);
+	i_assert(stream->pos - stream->skip > 0);
 	return stream->pos - stream->skip;
 }
 
diff -r 413c70b0ae1d -r 40a07553606c src/lib/istream-seekable.c
--- a/src/lib/istream-seekable.c	Sat Sep 13 13:02:13 2008 +0300
+++ b/src/lib/istream-seekable.c	Sat Sep 13 13:06:06 2008 +0300
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "buffer.h"
+#include "close-keep-errno.h"
 #include "hex-binary.h"
 #include "randgen.h"
 #include "write-full.h"
@@ -107,14 +108,14 @@ static int copy_to_temp_file(struct seek
 	if (unlink(path) < 0) {
 		/* shouldn't happen.. */
 		i_error("unlink(%s) failed: %m", path);
-		(void)close(fd);
+		close_keep_errno(fd);
 		return -1;
 	}
 
 	/* copy our currently read buffer to it */
 	if (write_full(fd, sstream->buffer->data, sstream->buffer->used) < 0) {
 		i_error("write_full(%s) failed: %m", path);
-		(void)close(fd);
+		close_keep_errno(fd);
 		return -1;
 	}
 	sstream->write_peak = sstream->buffer->used;
@@ -139,10 +140,10 @@ static ssize_t read_more(struct seekable
 
 	while ((ret = i_stream_read(sstream->cur_input)) < 0) {
 		if (!sstream->cur_input->eof) {
-			/* error */
+			/* full / error */
 			sstream->istream.istream.stream_errno =
 				sstream->cur_input->stream_errno;
-			return -1;
+			return ret;
 		}
 
 		/* go to next stream */
@@ -161,7 +162,7 @@ static ssize_t read_more(struct seekable
 	return ret;
 }
 
-static bool read_from_buffer(struct seekable_istream *sstream, ssize_t *ret)
+static bool read_from_buffer(struct seekable_istream *sstream, ssize_t *ret_r)
 {
 	struct istream_private *stream = &sstream->istream;
 	const unsigned char *data;
@@ -174,8 +175,8 @@ static bool read_from_buffer(struct seek
 			return FALSE;
 
 		/* read more to buffer */
-		*ret = read_more(sstream);
-		if (*ret <= 0)
+		*ret_r = read_more(sstream);
+		if (*ret_r <= 0)
 			return TRUE;
 
 		/* we should have more now. */
@@ -188,7 +189,8 @@ static bool read_from_buffer(struct seek
 	stream->buffer = CONST_PTR_OFFSET(sstream->buffer->data, offset);
 	pos = sstream->buffer->used - offset;
 
-	*ret = pos - stream->pos;
+	*ret_r = pos - stream->pos;
+	i_assert(*ret_r > 0);
 	stream->pos = pos;
 	return TRUE;
 }
@@ -210,6 +212,8 @@ static ssize_t i_stream_seekable_read(st
 
 		/* copy everything to temp file and use it as the stream */
 		if (copy_to_temp_file(sstream) < 0) {
+			i_assert(errno != 0);
+			stream->istream.stream_errno = errno;
 			i_stream_close(&stream->istream);
 			return -1;
 		}
@@ -225,6 +229,8 @@ static ssize_t i_stream_seekable_read(st
 		/* save to our file */
 		data = i_stream_get_data(sstream->cur_input, &size);
 		if (write_full(sstream->fd, data, size) < 0) {
+			i_assert(errno != 0);
+			stream->istream.stream_errno = errno;
 			i_error("write_full(%s...) failed: %m",
 				sstream->temp_prefix);
 			i_stream_close(&stream->istream);
@@ -255,7 +261,6 @@ static void i_stream_seekable_seek(struc
 static void i_stream_seekable_seek(struct istream_private *stream,
 				   uoff_t v_offset, bool mark ATTR_UNUSED)
 {
-	stream->istream.stream_errno = 0;
 	stream->istream.v_offset = v_offset;
 	stream->skip = stream->pos = 0;
 }
diff -r 413c70b0ae1d -r 40a07553606c src/lib/istream-tee.c
--- a/src/lib/istream-tee.c	Sat Sep 13 13:02:13 2008 +0300
+++ b/src/lib/istream-tee.c	Sat Sep 13 13:06:06 2008 +0300
@@ -141,6 +141,7 @@ static ssize_t i_stream_tee_read(struct 
 
 	i_assert(stream->buffer == data);
 	ret = size - stream->pos;
+	i_assert(ret > 0);
 	stream->pos = size;
 	return ret;
 }
diff -r 413c70b0ae1d -r 40a07553606c src/lib/istream.c
--- a/src/lib/istream.c	Sat Sep 13 13:02:13 2008 +0300
+++ b/src/lib/istream.c	Sat Sep 13 13:06:06 2008 +0300
@@ -51,7 +51,7 @@ void i_stream_close(struct istream *stre
 	stream->closed = TRUE;
 
 	if (stream->stream_errno == 0)
-		stream->stream_errno = ECONNRESET;
+		stream->stream_errno = EBADFD;
 }
 
 void i_stream_set_max_buffer_size(struct istream *stream, size_t max_size)
@@ -62,12 +62,27 @@ ssize_t i_stream_read(struct istream *st


More information about the dovecot-cvs mailing list