ostream.c revision d6193a892452ae87548f5745dada01f82816765d
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainenvoid o_stream_set_name(struct ostream *stream, const char *name)
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen stream->real_stream->iostream.name = i_strdup(name);
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainenconst char *o_stream_get_name(struct ostream *stream)
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainen while (stream->real_stream->iostream.name == NULL) {
0a00890f8ec34ee08d0d391441fca36ed42d7a0cTimo Sirainenconst char *o_stream_get_error(struct ostream *stream)
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen /* we'll only return errors for streams that have stream_errno set.
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen we might be returning unintended error otherwise. */
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen return "<no error>";
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen for (s = stream; s != NULL; s = s->real_stream->parent) {
12aad74464367f7e8be11eafe1af985bf7b1adecTimo Sirainenstatic void o_stream_close_full(struct ostream *stream, bool close_parents)
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen /* Ideally o_stream_finish() would be called for all non-failed
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen ostreams, but strictly requiring it would cause unnecessary
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen complexity for many callers. Just require that at this point
12aad74464367f7e8be11eafe1af985bf7b1adecTimo Sirainen after flushing there isn't anything in the output buffer or that
12aad74464367f7e8be11eafe1af985bf7b1adecTimo Sirainen we're ignoring all errors. */
12aad74464367f7e8be11eafe1af985bf7b1adecTimo Sirainen i_assert(stream->real_stream->error_handling_disabled);
12aad74464367f7e8be11eafe1af985bf7b1adecTimo Sirainen if (!stream->closed && !stream->real_stream->closing) {
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen /* first mark the stream as being closed so the
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen o_stream_copy_error_from_parent() won't recurse us back
12aad74464367f7e8be11eafe1af985bf7b1adecTimo Sirainen here. but don't immediately mark the stream closed, because
12aad74464367f7e8be11eafe1af985bf7b1adecTimo Sirainen we may still want to write something to it. */
12aad74464367f7e8be11eafe1af985bf7b1adecTimo Sirainen io_stream_close(&stream->real_stream->iostream, close_parents);
12aad74464367f7e8be11eafe1af985bf7b1adecTimo Sirainen io_stream_ref(&stream->real_stream->iostream);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (stream->real_stream->last_errors_not_checked &&
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen !stream->real_stream->error_handling_disabled &&
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen stream->real_stream->iostream.refcount == 1) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen i_panic("output stream %s is missing error handling",
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen if (!io_stream_unref(&stream->real_stream->iostream))
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen io_stream_free(&stream->real_stream->iostream);
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainenvoid o_stream_add_destroy_callback(struct ostream *stream,
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen io_stream_add_destroy_callback(&stream->real_stream->iostream,
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainenvoid o_stream_remove_destroy_callback(struct ostream *stream,
70cb37c37e4dce8f57cd3f882f7444e76b918befTimo Sirainen io_stream_remove_destroy_callback(&stream->real_stream->iostream,
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainenvoid o_stream_set_flush_callback(struct ostream *stream,
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen struct ostream_private *_stream = stream->real_stream;
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen _stream->set_flush_callback(_stream, callback, context);
98a711be68ba64e1cabf8cacc150af44421e2ac9Timo Sirainenvoid o_stream_unset_flush_callback(struct ostream *stream)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen struct ostream_private *_stream = stream->real_stream;
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen _stream->set_flush_callback(_stream, NULL, NULL);
return ret;
static ssize_t
if (total_size == 0)
if (ret < 0) {
return ret;
unsigned int iov_count)
bool overflow;
unsigned int iov_count)
bool overflow;
if (overflow)
switch (res) {
return res;
return res;
return res;
i_unreached();
int ret;
return ret;
const unsigned char *data;
else if (ret == 0)
bool close_parent)
if (set) {
int ret;
if (ret < 0)
return ret;
void *context)
static size_t
static ssize_t
return ret;
static enum ostream_send_istream_result
struct ostream *
return output;
struct ostream *
return output;