From d28179fd78550a58be44dcb1e3e830ab7d33172d Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 18 May 2016 22:36:57 +0300 Subject: [PATCH] lib: Changed istream.abs_start_offset to be relative start_offset i_stream_get_absolute_offset() walks through the stream's parents to get the absolute offset. This allows streams to change their start_offset after they have already created (e.g. istream-metawrap). --- src/lib-compression/istream-bzlib.c | 3 +-- src/lib-compression/istream-lz4.c | 3 +-- src/lib-compression/istream-lzma.c | 3 +-- src/lib-compression/istream-zlib.c | 3 +-- src/lib-fs/istream-metawrap.c | 2 +- src/lib/iostream-temp.c | 3 ++- src/lib/istream-mmap.c | 2 +- src/lib/istream-private.h | 2 +- src/lib/istream.c | 10 +++++++--- src/lib/ostream-file.c | 10 +++++----- 10 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/lib-compression/istream-bzlib.c b/src/lib-compression/istream-bzlib.c index 5d1aabfb04..20b2ca7a7f 100644 --- a/src/lib-compression/istream-bzlib.c +++ b/src/lib-compression/istream-bzlib.c @@ -41,8 +41,7 @@ static void bzlib_read_error(struct bzlib_istream *zstream, const char *error) io_stream_set_error(&zstream->istream.iostream, "bzlib.read(%s): %s at %"PRIuUOFF_T, i_stream_get_name(&zstream->istream.istream), error, - zstream->istream.abs_start_offset + - zstream->istream.istream.v_offset); + i_stream_get_absolute_offset(&zstream->istream.istream)); if (zstream->log_errors) i_error("%s", zstream->istream.iostream.error); } diff --git a/src/lib-compression/istream-lz4.c b/src/lib-compression/istream-lz4.c index b5ce92dcb9..b7e072b980 100644 --- a/src/lib-compression/istream-lz4.c +++ b/src/lib-compression/istream-lz4.c @@ -40,8 +40,7 @@ static void lz4_read_error(struct lz4_istream *zstream, const char *error) io_stream_set_error(&zstream->istream.iostream, "lz4.read(%s): %s at %"PRIuUOFF_T, i_stream_get_name(&zstream->istream.istream), error, - zstream->istream.abs_start_offset + - zstream->istream.istream.v_offset); + i_stream_get_absolute_offset(&zstream->istream.istream)); if (zstream->log_errors) i_error("%s", zstream->istream.iostream.error); } diff --git a/src/lib-compression/istream-lzma.c b/src/lib-compression/istream-lzma.c index bf6d5b344e..ed17d6db94 100644 --- a/src/lib-compression/istream-lzma.c +++ b/src/lib-compression/istream-lzma.c @@ -43,8 +43,7 @@ static void lzma_read_error(struct lzma_istream *zstream, const char *error) io_stream_set_error(&zstream->istream.iostream, "lzma.read(%s): %s at %"PRIuUOFF_T, i_stream_get_name(&zstream->istream.istream), error, - zstream->istream.abs_start_offset + - zstream->istream.istream.v_offset); + i_stream_get_absolute_offset(&zstream->istream.istream)); if (zstream->log_errors) i_error("%s", zstream->istream.iostream.error); } diff --git a/src/lib-compression/istream-zlib.c b/src/lib-compression/istream-zlib.c index cb2c76ecaf..c92fe1d36b 100644 --- a/src/lib-compression/istream-zlib.c +++ b/src/lib-compression/istream-zlib.c @@ -58,8 +58,7 @@ static void zlib_read_error(struct zlib_istream *zstream, const char *error) io_stream_set_error(&zstream->istream.iostream, "zlib.read(%s): %s at %"PRIuUOFF_T, i_stream_get_name(&zstream->istream.istream), error, - zstream->istream.abs_start_offset + - zstream->istream.istream.v_offset); + i_stream_get_absolute_offset(&zstream->istream.istream)); if (zstream->log_errors) i_error("%s", zstream->istream.iostream.error); } diff --git a/src/lib-fs/istream-metawrap.c b/src/lib-fs/istream-metawrap.c index d757f51a43..fc96245425 100644 --- a/src/lib-fs/istream-metawrap.c +++ b/src/lib-fs/istream-metawrap.c @@ -64,7 +64,7 @@ static ssize_t i_stream_metawrap_read(struct istream_private *stream) if (ret <= 0) return ret; /* this stream is kind of silently skipping over the metadata */ - stream->abs_start_offset += mstream->start_offset; + stream->start_offset += mstream->start_offset; mstream->in_metadata = FALSE; if (mstream->pending_seek != 0) { i_stream_seek(&stream->istream, mstream->pending_seek); diff --git a/src/lib/iostream-temp.c b/src/lib/iostream-temp.c index 779c4481c4..2b2462ffee 100644 --- a/src/lib/iostream-temp.c +++ b/src/lib/iostream-temp.c @@ -296,7 +296,8 @@ struct istream *iostream_temp_finish(struct ostream **output, for_path = t_strdup_printf(" for %s", tstream->name); if (tstream->dupstream != NULL && !tstream->dupstream->closed) { - abs_offset = tstream->dupstream->real_stream->abs_start_offset + + abs_offset = i_stream_get_absolute_offset(tstream->dupstream) - + tstream->dupstream->v_offset + tstream->dupstream_start_offset; size = tstream->dupstream_offset - tstream->dupstream_start_offset; diff --git a/src/lib/istream-mmap.c b/src/lib/istream-mmap.c index de4ddeb2ad..7e1e1ab130 100644 --- a/src/lib/istream-mmap.c +++ b/src/lib/istream-mmap.c @@ -230,7 +230,7 @@ struct istream *i_stream_create_mmap(int fd, size_t block_size, mstream->istream.stat = i_stream_mmap_stat; mstream->istream.istream.readable_fd = TRUE; - mstream->istream.abs_start_offset = start_offset; + mstream->istream.start_offset = start_offset; istream = i_stream_create(&mstream->istream, NULL, fd); istream->mmaped = TRUE; istream->blocking = TRUE; diff --git a/src/lib/istream-private.h b/src/lib/istream-private.h index c6b69d5754..0fceda0273 100644 --- a/src/lib/istream-private.h +++ b/src/lib/istream-private.h @@ -25,7 +25,7 @@ struct istream_private { struct istream istream; int fd; - uoff_t abs_start_offset; + uoff_t start_offset; struct stat statbuf; /* added by io_add_istream() -> i_stream_set_io() */ struct io *io; diff --git a/src/lib/istream.c b/src/lib/istream.c index bcbb027386..9b66f79af8 100644 --- a/src/lib/istream.c +++ b/src/lib/istream.c @@ -367,7 +367,12 @@ bool i_stream_is_eof(struct istream *stream) uoff_t i_stream_get_absolute_offset(struct istream *stream) { - return stream->real_stream->abs_start_offset + stream->v_offset; + uoff_t abs_offset = stream->v_offset; + while (stream != NULL) { + abs_offset += stream->real_stream->start_offset; + stream = stream->real_stream->parent; + } + return abs_offset; } static char *i_stream_next_line_finish(struct istream_private *stream, size_t i) @@ -827,8 +832,7 @@ void i_stream_init_parent(struct istream_private *_stream, _stream->parent = parent; _stream->parent_start_offset = parent->v_offset; _stream->parent_expected_offset = parent->v_offset; - _stream->abs_start_offset = parent->v_offset + - parent->real_stream->abs_start_offset; + _stream->start_offset = parent->v_offset; /* if parent stream is an istream-error, copy the error */ _stream->istream.stream_errno = parent->stream_errno; _stream->istream.eof = parent->eof; diff --git a/src/lib/ostream-file.c b/src/lib/ostream-file.c index c77742ac5f..51658c97dc 100644 --- a/src/lib/ostream-file.c +++ b/src/lib/ostream-file.c @@ -692,7 +692,7 @@ static int io_stream_sendfile(struct ostream_private *outstream, bool *sendfile_not_supported_r) { struct file_ostream *foutstream = (struct file_ostream *)outstream; - uoff_t in_size, offset, send_size, v_offset; + uoff_t in_size, offset, send_size, v_offset, abs_start_offset; ssize_t ret; *sendfile_not_supported_r = FALSE; @@ -713,9 +713,10 @@ static int io_stream_sendfile(struct ostream_private *outstream, if (o_stream_lseek(foutstream) < 0) return -1; - v_offset = instream->v_offset; + v_offset = instream->v_offset; + abs_start_offset = i_stream_get_absolute_offset(instream) - v_offset; while (v_offset < in_size) { - offset = instream->real_stream->abs_start_offset + v_offset; + offset = abs_start_offset + v_offset; send_size = in_size - v_offset; ret = safe_sendfile(foutstream->fd, in_fd, &offset, @@ -862,8 +863,7 @@ static int io_stream_copy_same_stream(struct ostream_private *outstream, } i_assert(instream->v_offset <= in_size); - in_abs_offset = instream->real_stream->abs_start_offset + - instream->v_offset; + in_abs_offset = i_stream_get_absolute_offset(instream); ret = (off_t)outstream->ostream.offset - in_abs_offset; if (ret == 0) { /* copying data over itself. we don't really