From: Timo Sirainen Date: Fri, 27 Oct 2017 22:15:14 +0000 (+0300) Subject: lib: Add o_stream_finish() X-Git-Tag: 2.3.0.rc1~708 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=84717f00ddbf5cd0ebe3f285090d5e97e458e19c;p=thirdparty%2Fdovecot%2Fcore.git lib: Add o_stream_finish() This marks the ostream as fully finished, with no further writes coming to it. Otherwise it behaves like o_stream_flush(). The ostream.flush() methods are supposed to write their trailer (if the ostream has one) when they see that ostream.finished is set. These will be implemented by the following commits. --- diff --git a/src/lib/ostream-private.h b/src/lib/ostream-private.h index f35d472362..d9d4fa5f7c 100644 --- a/src/lib/ostream-private.h +++ b/src/lib/ostream-private.h @@ -38,6 +38,7 @@ struct ostream_private { void *context; bool corked:1; + bool finished:1; bool closing:1; bool last_errors_not_checked:1; bool error_handling_disabled:1; diff --git a/src/lib/ostream.c b/src/lib/ostream.c index 9b27293ff9..15e23d44f7 100644 --- a/src/lib/ostream.c +++ b/src/lib/ostream.c @@ -264,6 +264,7 @@ o_stream_sendv_int(struct ostream *stream, const struct const_iovec *iov, if (total_size == 0) return 0; + i_assert(!_stream->finished); ret = _stream->sendv(_stream, iov, iov_count); if (unlikely(ret != (ssize_t)total_size)) { if (ret < 0) { @@ -325,6 +326,12 @@ void o_stream_nsend_str(struct ostream *stream, const char *str) o_stream_nsend(stream, str, strlen(str)); } +int o_stream_finish(struct ostream *stream) +{ + stream->real_stream->finished = TRUE; + return o_stream_flush(stream); +} + void o_stream_ignore_last_errors(struct ostream *stream) { while (stream != NULL) { @@ -355,6 +362,7 @@ o_stream_send_istream(struct ostream *outstream, struct istream *instream) return OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT; } + i_assert(!_outstream->finished); res = _outstream->send_istream(_outstream, instream); switch (res) { case OSTREAM_SEND_ISTREAM_RESULT_FINISHED: @@ -417,6 +425,7 @@ int o_stream_pwrite(struct ostream *stream, const void *data, size_t size, return -1; } + i_assert(!stream->real_stream->finished); ret = stream->real_stream->write_at(stream->real_stream, data, size, offset); if (unlikely(ret < 0)) { diff --git a/src/lib/ostream.h b/src/lib/ostream.h index 586747f373..b93fd2d4e4 100644 --- a/src/lib/ostream.h +++ b/src/lib/ostream.h @@ -159,6 +159,11 @@ static inline int o_stream_nfinish(struct ostream *stream) { return o_stream_flush(stream) < 0 ? -1 : 0; } +/* Mark the ostream as finished and flush it. If the ostream has a footer, + it's written here. Any further write attempts to the ostream will + assert-crash. Returns the same as o_stream_flush(). Afterwards any calls to + this function are identical to o_stream_flush(). */ +int o_stream_finish(struct ostream *stream); /* Marks the stream's error handling as completed to avoid i_panic() on destroy. */ void o_stream_ignore_last_errors(struct ostream *stream);