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;
}
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 */
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);
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;
}
rstream->hdr_offset + rstream->mail_size);
rstream->eof = TRUE;
rstream->corrupted = TRUE;
+ rstream->istream.istream.stream_errno = EBADMSG;
return -1;
}
}
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);
}
{
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;
i_stream_skip(stream->parent, i);
ret = dest - stream->pos;
- i_assert(ret != 0);
+ i_assert(ret > 0);
stream->pos = dest;
return ret;
}
i_assert(cstream->pending_cr && size == 1);
return i_stream_crlf_read_lf(stream);
}
+ i_assert(ret > 0);
stream->pos = dest;
return ret;
}
size_t size;
ssize_t ret;
- stream->istream.stream_errno = 0;
if (!i_stream_get_buffer_space(stream, 1, &size))
return -2;
i_assert(!stream->istream.blocking);
ret = 0;
} else {
- stream->istream.eof = TRUE;
+ i_assert(errno != 0);
stream->istream.stream_errno = errno;
return -1;
}
stream->pos += ret;
i_assert(ret != 0 || !fstream->file);
+ i_assert(ret != -1);
return ret;
}
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;
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;
}
i_assert(v_offset <= lstream->v_size);
- stream->istream.stream_errno = 0;
stream->istream.v_offset = v_offset;
stream->skip = stream->pos = 0;
}
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() */
stream->pos = stream->buffer_size;
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;
}
stream->pos = stream->buffer_size;
- i_assert(stream->pos - stream->skip != 0);
+ i_assert(stream->pos - stream->skip > 0);
return stream->pos - stream->skip;
}
#include "lib.h"
#include "buffer.h"
+#include "close-keep-errno.h"
#include "hex-binary.h"
#include "randgen.h"
#include "write-full.h"
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;
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 */
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;
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. */
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;
}
/* 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;
}
/* 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);
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;
}
i_assert(stream->buffer == data);
ret = size - stream->pos;
+ i_assert(ret > 0);
stream->pos = size;
return ret;
}
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)
ssize_t i_stream_read(struct istream *stream)
{
struct istream_private *_stream = stream->real_stream;
+ ssize_t ret;
if (unlikely(stream->closed))
return -1;
stream->eof = FALSE;
- return _stream->read(_stream);
+ stream->stream_errno = 0;
+
+ ret = _stream->read(_stream);
+ if (ret < 0) {
+ if (stream->stream_errno != 0) {
+ /* error handling should be easier if we now just
+ assume the stream is now at EOF */
+ stream->eof = TRUE;
+ } else {
+ i_assert(stream->eof);
+ }
+ } else {
+ i_assert(ret != 0 || !stream->blocking);
+ }
+ return ret;
}
void i_stream_skip(struct istream *stream, uoff_t count)
if (unlikely(stream->closed))
return;
+ stream->stream_errno = 0;
_stream->seek(_stream, stream->v_offset + count, FALSE);
}
i_assert(!stream->blocking);
return 0;
}
- if (read_more && stream->eof) {
- /* we read at least some new data */
- return 0;
+ if (stream->eof) {
+ if (read_more) {
+ /* we read at least some new data */
+ return 0;
+ }
+ } else {
+ i_assert(stream->stream_errno != 0);
}
- i_assert(stream->stream_errno != 0);
return -1;
}
size_t size;
int ret;
- if (stream->istream.closed)
- return -1;
-
- stream->istream.stream_errno = 0;
-
if (stream->pos == stream->buffer_size) {
if (!zstream->marked && stream->skip > 0) {
/* don't try to keep anything cached if we don't
i_assert(!stream->istream.blocking);
ret = 0;
} else {
- stream->istream.eof = TRUE;
+ i_assert(errno != 0);
stream->istream.stream_errno = errno;
return -1;
}
zstream->seek_offset += ret;
stream->pos += ret;
- i_assert(ret != 0);
+ i_assert(ret > 0);
return ret;
}
struct zlib_istream *zstream = (struct zlib_istream *) stream;
uoff_t start_offset = stream->istream.v_offset - stream->skip;
- stream->istream.stream_errno = 0;
-
#ifndef HAVE_GZSEEK
if (v_offset < start_offset) {
/* need to reopen, but since closing the file closes the