Mercurial > dovecot > core-2.2
changeset 9557:e41c648a2f4c HEAD
ostreams: Moved generic o_stream_send_istream() implementation to ostream.c.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 29 Jun 2009 21:57:27 -0400 |
parents | bf96497404f5 |
children | 320d2164bc17 |
files | src/lib/ostream-file.c src/lib/ostream-internal.h src/lib/ostream.c |
diffstat | 3 files changed, 56 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/ostream-file.c Mon Jun 29 21:56:00 2009 -0400 +++ b/src/lib/ostream-file.c Mon Jun 29 21:57:27 2009 -0400 @@ -737,40 +737,6 @@ return ret < 0 ? -1 : (off_t)(instream->v_offset - start_offset); } -static off_t io_stream_copy(struct ostream_private *outstream, - struct istream *instream) -{ - struct file_ostream *foutstream = (struct file_ostream *)outstream; - uoff_t start_offset; - struct const_iovec iov; - const unsigned char *data; - ssize_t ret; - - start_offset = instream->v_offset; - for (;;) { - (void)i_stream_read_data(instream, &data, &iov.iov_len, - foutstream->optimal_block_size-1); - if (iov.iov_len == 0) { - /* all sent */ - break; - } - - iov.iov_base = data; - ret = o_stream_file_sendv(outstream, &iov, 1); - if (ret <= 0) { - if (ret == 0) - break; - return -1; - } - i_stream_skip(instream, ret); - - if ((size_t)ret != iov.iov_len) - break; - } - - return (off_t) (instream->v_offset - start_offset); -} - static off_t io_stream_copy_backwards(struct ostream_private *outstream, struct istream *instream, uoff_t in_size) { @@ -848,17 +814,14 @@ return (off_t) (in_size - in_start_offset); } -static off_t o_stream_file_send_istream(struct ostream_private *outstream, - struct istream *instream) +static off_t io_stream_copy_stream(struct ostream_private *outstream, + struct istream *instream, bool same_stream) { struct file_ostream *foutstream = (struct file_ostream *)outstream; const struct stat *st; off_t in_abs_offset, ret; - int in_fd; - in_fd = !instream->readable_fd ? -1 : i_stream_get_fd(instream); - - if (in_fd == foutstream->fd) { + if (same_stream) { /* copying data within same fd. we'll have to be careful with seeks and overlapping writes. */ st = i_stream_stat(instream, TRUE); @@ -884,7 +847,21 @@ } } - if (!foutstream->no_sendfile && in_fd != -1 && instream->seekable) { + return io_stream_copy(&outstream->ostream, instream, + foutstream->optimal_block_size); +} + +static off_t o_stream_file_send_istream(struct ostream_private *outstream, + struct istream *instream) +{ + struct file_ostream *foutstream = (struct file_ostream *)outstream; + bool same_stream; + int in_fd; + off_t ret; + + in_fd = !instream->readable_fd ? -1 : i_stream_get_fd(instream); + if (!foutstream->no_sendfile && in_fd != -1 && + in_fd != foutstream->fd && instream->seekable) { ret = io_stream_sendfile(outstream, instream, in_fd); if (ret >= 0 || outstream->ostream.stream_errno != EINVAL) return ret; @@ -895,7 +872,8 @@ foutstream->no_sendfile = TRUE; } - return io_stream_copy(outstream, instream); + same_stream = i_stream_get_fd(instream) == foutstream->fd; + return io_stream_copy_stream(outstream, instream, same_stream); } static struct file_ostream *
--- a/src/lib/ostream-internal.h Mon Jun 29 21:56:00 2009 -0400 +++ b/src/lib/ostream-internal.h Mon Jun 29 21:57:27 2009 -0400 @@ -31,4 +31,7 @@ struct ostream *o_stream_create(struct ostream_private *_stream); +off_t io_stream_copy(struct ostream *outstream, struct istream *instream, + size_t block_size); + #endif
--- a/src/lib/ostream.c Mon Jun 29 21:56:00 2009 -0400 +++ b/src/lib/ostream.c Mon Jun 29 21:57:27 2009 -0400 @@ -203,3 +203,36 @@ io_stream_init(&_stream->iostream); return &_stream->ostream; } + +off_t io_stream_copy(struct ostream *outstream, struct istream *instream, + size_t block_size) +{ + uoff_t start_offset; + struct const_iovec iov; + const unsigned char *data; + ssize_t ret; + + start_offset = instream->v_offset; + for (;;) { + (void)i_stream_read_data(instream, &data, &iov.iov_len, + block_size-1); + if (iov.iov_len == 0) { + /* all sent */ + break; + } + + iov.iov_base = data; + ret = o_stream_sendv(outstream, &iov, 1); + if (ret <= 0) { + if (ret == 0) + break; + return -1; + } + i_stream_skip(instream, ret); + + if ((size_t)ret != iov.iov_len) + break; + } + + return (off_t)(instream->v_offset - start_offset); +}