diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:36:47 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:36:47 +0000 |
commit | 0441d265f2bb9da249c7abf333f0f771fadb4ab5 (patch) | |
tree | 3f3789daa2f6db22da6e55e92bee0062a7d613fe /src/lib-fs/ostream-metawrap.c | |
parent | Initial commit. (diff) | |
download | dovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.tar.xz dovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.zip |
Adding upstream version 1:2.3.21+dfsg1.upstream/1%2.3.21+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib-fs/ostream-metawrap.c')
-rw-r--r-- | src/lib-fs/ostream-metawrap.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/lib-fs/ostream-metawrap.c b/src/lib-fs/ostream-metawrap.c new file mode 100644 index 0000000..3359bd3 --- /dev/null +++ b/src/lib-fs/ostream-metawrap.c @@ -0,0 +1,71 @@ +/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "istream.h" +#include "ostream-private.h" +#include "ostream-metawrap.h" + +struct metawrap_ostream { + struct ostream_private ostream; + void (*write_callback)(void *); + void *context; +}; + +static void o_stream_metawrap_call_callback(struct metawrap_ostream *mstream) +{ + void (*write_callback)(void *) = mstream->write_callback; + + if (write_callback != NULL) { + mstream->write_callback = NULL; + write_callback(mstream->context); + /* metadata headers aren't counted as part of the offset */ + mstream->ostream.ostream.offset = 0; + } +} + +static ssize_t +o_stream_metawrap_sendv(struct ostream_private *stream, + const struct const_iovec *iov, unsigned int iov_count) +{ + struct metawrap_ostream *mstream = (struct metawrap_ostream *)stream; + ssize_t ret; + + o_stream_metawrap_call_callback(mstream); + if ((ret = o_stream_sendv(stream->parent, iov, iov_count)) < 0) + o_stream_copy_error_from_parent(stream); + else + stream->ostream.offset += ret; + return ret; +} + +static enum ostream_send_istream_result +o_stream_metawrap_send_istream(struct ostream_private *_outstream, + struct istream *instream) +{ + struct metawrap_ostream *outstream = + (struct metawrap_ostream *)_outstream; + uoff_t orig_instream_offset = instream->v_offset; + enum ostream_send_istream_result res; + + o_stream_metawrap_call_callback(outstream); + if ((res = o_stream_send_istream(_outstream->parent, instream)) == OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT) + o_stream_copy_error_from_parent(_outstream); + _outstream->ostream.offset += instream->v_offset - orig_instream_offset; + return res; +} + +struct ostream * +o_stream_create_metawrap(struct ostream *output, + void (*write_callback)(void *), void *context) +{ + struct metawrap_ostream *mstream; + + mstream = i_new(struct metawrap_ostream, 1); + mstream->ostream.sendv = o_stream_metawrap_sendv; + mstream->ostream.send_istream = o_stream_metawrap_send_istream; + mstream->write_callback = write_callback; + mstream->context = context; + + return o_stream_create(&mstream->ostream, output, + o_stream_get_fd(output)); +} |