ostream.c revision b3fc5293379feb3640b23622bcc8f5f8d7f1e81d
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomivoid o_stream_set_name(struct ostream *stream, const char *name)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi stream->real_stream->iostream.name = i_strdup(name);
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomiconst char *o_stream_get_name(struct ostream *stream)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi while (stream->real_stream->iostream.name == NULL) {
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomiconst char *o_stream_get_error(struct ostream *stream)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi /* we'll only return errors for streams that have stream_errno set.
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi we might be returning unintended error otherwise. */
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi return "<no error>";
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi for (s = stream; s != NULL; s = s->real_stream->parent) {
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomistatic void o_stream_close_full(struct ostream *stream, bool close_parents)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi if (!stream->closed && !stream->real_stream->closing) {
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi /* first mark the stream as being closed so the
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi o_stream_copy_error_from_parent() won't recurse us back
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi here. but don't immediately mark the stream closed, because
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi we may still want to write something to it. */
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi io_stream_close(&stream->real_stream->iostream, close_parents);
f01fe9df4240c5b15d0b1c4b485a38f7c5736781Timo Sirainen io_stream_ref(&stream->real_stream->iostream);
b78f4649c236bf4746c81c1d0e877675f0842ac8Timo Sirainen if (stream->real_stream->last_errors_not_checked &&
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi i_panic("output stream %s is missing error handling",
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi if (!io_stream_unref(&stream->real_stream->iostream))
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomivoid o_stream_add_destroy_callback(struct ostream *stream,
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi io_stream_add_destroy_callback(&stream->real_stream->iostream,
c50acc5547b9d92784825a09e3de97db0a806f4eTimo Sirainenvoid o_stream_remove_destroy_callback(struct ostream *stream,
c50acc5547b9d92784825a09e3de97db0a806f4eTimo Sirainen io_stream_remove_destroy_callback(&stream->real_stream->iostream,
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomivoid o_stream_set_flush_callback(struct ostream *stream,
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi struct ostream_private *_stream = stream->real_stream;
f01fe9df4240c5b15d0b1c4b485a38f7c5736781Timo Sirainen _stream->set_flush_callback(_stream, callback, context);
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomivoid o_stream_unset_flush_callback(struct ostream *stream)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi struct ostream_private *_stream = stream->real_stream;
f01fe9df4240c5b15d0b1c4b485a38f7c5736781Timo Sirainenvoid o_stream_set_max_buffer_size(struct ostream *stream, size_t max_size)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi io_stream_set_max_buffer_size(&stream->real_stream->iostream, max_size);
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomisize_t o_stream_get_max_buffer_size(struct ostream *stream)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi struct ostream_private *_stream = stream->real_stream;
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi if (unlikely(stream->closed || stream->stream_errno != 0))
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi struct ostream_private *_stream = stream->real_stream;
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi if (unlikely(stream->closed || stream->stream_errno != 0))
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi struct ostream_private *_stream = stream->real_stream;
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi struct ostream_private *_stream = stream->real_stream;
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi if (unlikely(stream->closed || stream->stream_errno != 0)) {
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi if (unlikely((ret = _stream->flush(_stream)) < 0)) {
f01fe9df4240c5b15d0b1c4b485a38f7c5736781Timo Sirainenvoid o_stream_set_flush_pending(struct ostream *stream, bool set)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi struct ostream_private *_stream = stream->real_stream;
038c2831447440bf0bef89b43dd0968afc298abcStephan Bosch if (unlikely(stream->closed || stream->stream_errno != 0))
36aa1b351b8e9d02a93aa17e5de8a06ac5440084Timo Sirainensize_t o_stream_get_buffer_used_size(const struct ostream *stream)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi const struct ostream_private *_stream = stream->real_stream;
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomisize_t o_stream_get_buffer_avail_size(const struct ostream *stream)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi size_t used = o_stream_get_buffer_used_size(stream);
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi return stream->real_stream->max_buffer_size <= used ? 0 :
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomiint o_stream_seek(struct ostream *stream, uoff_t offset)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi struct ostream_private *_stream = stream->real_stream;
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi if (unlikely(stream->closed || stream->stream_errno != 0)) {
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi if (unlikely(_stream->seek(_stream, offset) < 0)) {
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomissize_t o_stream_send(struct ostream *stream, const void *data, size_t size)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomio_stream_sendv_int(struct ostream *stream, const struct const_iovec *iov,
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi struct ostream_private *_stream = stream->real_stream;
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi unsigned int i;
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomissize_t o_stream_sendv(struct ostream *stream, const struct const_iovec *iov,
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi unsigned int iov_count)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi if (unlikely(stream->closed || stream->stream_errno != 0)) {
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomi return o_stream_sendv_int(stream, iov, iov_count, &overflow);
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomissize_t o_stream_send_str(struct ostream *stream, const char *str)
1de7b73a11afda43323410a4481d866930b1e632Aki Tuomivoid o_stream_nsend(struct ostream *stream, const void *data, size_t size)
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;
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;