From: Timo Sirainen Date: Fri, 27 Oct 2017 23:55:22 +0000 (+0300) Subject: lib: Automatically flush ostream when it's closed X-Git-Tag: 2.3.0.rc1~699 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1;p=thirdparty%2Fdovecot%2Fcore.git lib: Automatically flush ostream when it's closed Also verify that it unexpectedly didn't get fully flushed. --- diff --git a/src/lib/ostream.c b/src/lib/ostream.c index 15e23d44f7..04effd05ec 100644 --- a/src/lib/ostream.c +++ b/src/lib/ostream.c @@ -45,6 +45,14 @@ const char *o_stream_get_error(struct ostream *stream) static void o_stream_close_full(struct ostream *stream, bool close_parents) { + /* Ideally o_stream_finish() would be called for all non-failed + ostreams, but strictly requiring it would cause unnecessary + complexity for many callers. Just require that at this point + after flushing there isn't anything in the output buffer or that + we're ignoring all errors. */ + if (o_stream_flush(stream) == 0) + i_assert(stream->real_stream->error_handling_disabled); + if (!stream->closed && !stream->real_stream->closing) { /* first mark the stream as being closed so the o_stream_copy_error_from_parent() won't recurse us back diff --git a/src/lib/ostream.h b/src/lib/ostream.h index 9b15959628..41968e0bf8 100644 --- a/src/lib/ostream.h +++ b/src/lib/ostream.h @@ -100,7 +100,13 @@ void o_stream_remove_destroy_callback(struct ostream *stream, void (*callback)()); /* Mark the stream and all of its parent streams closed. Nothing will be - sent after this call. */ + sent after this call. When using ostreams that require writing a trailer, + o_stream_finish() must be used before the stream is closed. When ostream + is destroyed, it's also closed but its parents aren't. + + Closing the ostream (also via destroy) will first flush the ostream, and + afterwards requires one of: a) stream has failed, b) there is no more + buffered data, c) o_stream_set_no_error_handling() has been called. */ void o_stream_close(struct ostream *stream); /* Set IO_WRITE callback. Default will just try to flush the output and