ostream.c revision 46631c1d903c409444b1b1c4a1d41a033c09ee37
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2002-2014 Dovecot authors, see the included COPYING file */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenvoid o_stream_set_name(struct ostream *stream, const char *name)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen stream->real_stream->iostream.name = i_strdup(name);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenconst char *o_stream_get_name(struct ostream *stream)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen while (stream->real_stream->iostream.name == NULL) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenconst char *o_stream_get_error(struct ostream *stream)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* we'll only return errors for streams that have stream_errno set.
46e917c9fa05cbe7bddf805d3a9838b61e3960e1Timo Sirainen we might be returning unintended error otherwise. */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return "<no error>";
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen for (s = stream; s != NULL; s = s->real_stream->parent) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic void o_stream_close_full(struct ostream *stream, bool close_parents)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (!stream->closed && !stream->real_stream->closing) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* first mark the stream as being closed so the
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen o_stream_copy_error_from_parent() won't recurse us back
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen here. but don't immediately mark the stream closed, because
16cb5d65265dd0b216542803fd80c4b999ae118eTimo Sirainen we may still want to write something to it. */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen io_stream_close(&stream->real_stream->iostream, close_parents);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen io_stream_ref(&stream->real_stream->iostream);
56d1345c43bbd28c36b7faa85e4163bd9e874290Timo Sirainen if (stream->real_stream->last_errors_not_checked &&
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen !stream->real_stream->error_handling_disabled &&
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen stream->real_stream->iostream.refcount == 1) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen i_panic("output stream %s is missing error handling",
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen io_stream_unref(&stream->real_stream->iostream);
56aa97d74071f3a2987140c2ff1cfd5a59cb35aaTimo Sirainenvoid o_stream_set_flush_callback(struct ostream *stream,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct ostream_private *_stream = stream->real_stream;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen _stream->set_flush_callback(_stream, callback, context);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenvoid o_stream_unset_flush_callback(struct ostream *stream)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct ostream_private *_stream = stream->real_stream;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen _stream->set_flush_callback(_stream, NULL, NULL);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenvoid o_stream_set_max_buffer_size(struct ostream *stream, size_t max_size)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen io_stream_set_max_buffer_size(&stream->real_stream->iostream, max_size);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainensize_t o_stream_get_max_buffer_size(struct ostream *stream)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct ostream_private *_stream = stream->real_stream;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct ostream_private *_stream = stream->real_stream;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenbool o_stream_is_corked(struct ostream *stream)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct ostream_private *_stream = stream->real_stream;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic void o_stream_clear_error(struct ostream *stream)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen i_free_and_null(stream->real_stream->iostream.error);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct ostream_private *_stream = stream->real_stream;
95d62f8d6d281cc488dc4f488d4388701e559012Josef 'Jeff' Sipek if (unlikely((ret = _stream->flush(_stream)) < 0)) {
9a1f68e5ab08eabd352d533315cba1c69006e2c1Timo Sirainen stream->last_failed_errno = stream->stream_errno;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenvoid o_stream_set_flush_pending(struct ostream *stream, bool set)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct ostream_private *_stream = stream->real_stream;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainensize_t o_stream_get_buffer_used_size(const struct ostream *stream)
95d62f8d6d281cc488dc4f488d4388701e559012Josef 'Jeff' Sipek const struct ostream_private *_stream = stream->real_stream;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainensize_t o_stream_get_buffer_avail_size(const struct ostream *stream)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen size_t used = o_stream_get_buffer_used_size(stream);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return stream->real_stream->max_buffer_size <= used ? 0 :
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenint o_stream_seek(struct ostream *stream, uoff_t offset)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct ostream_private *_stream = stream->real_stream;
5d4a0dac041964a04405bc6b94de51315ca917afTimo Sirainen if (unlikely(_stream->seek(_stream, offset) < 0)) {
5d4a0dac041964a04405bc6b94de51315ca917afTimo Sirainen stream->last_failed_errno = stream->stream_errno;
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainenssize_t o_stream_send(struct ostream *stream, const void *data, size_t size)
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainenssize_t o_stream_sendv(struct ostream *stream, const struct const_iovec *iov,
050acc3755ccc5bcf261a6de3250164a54a0b6f3Timo Sirainen struct ostream_private *_stream = stream->real_stream;
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen unsigned int i;
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen for (i = 0, total_size = 0; i < iov_count; i++)
cf35bb040d505e2fc333470850c65029992778a4Timo Sirainen ret = _stream->sendv(_stream, iov, iov_count);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen stream->last_failed_errno = stream->stream_errno;
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainenssize_t o_stream_send_str(struct ostream *stream, const char *str)
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen return o_stream_send(stream, str, strlen(str));
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainenvoid o_stream_nsend(struct ostream *stream, const void *data, size_t size)
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainenvoid o_stream_nsendv(struct ostream *stream, const struct const_iovec *iov,
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen stream->real_stream->last_errors_not_checked = TRUE;
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainenvoid o_stream_nsend_str(struct ostream *stream, const char *str)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen stream->real_stream->last_errors_not_checked = TRUE;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen return stream->last_failed_errno != 0 ? -1 : 0;
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainenvoid o_stream_ignore_last_errors(struct ostream *stream)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen stream->real_stream->last_errors_not_checked = FALSE;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenvoid o_stream_set_no_error_handling(struct ostream *stream, bool set)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen stream->real_stream->error_handling_disabled = set;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenoff_t o_stream_send_istream(struct ostream *outstream,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct ostream_private *_outstream = outstream->real_stream;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (unlikely(outstream->closed || instream->closed)) {
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen ret = _outstream->send_istream(_outstream, instream);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen outstream->last_failed_errno = outstream->stream_errno;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenint o_stream_pwrite(struct ostream *stream, const void *data, size_t size,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen ret = stream->real_stream->write_at(stream->real_stream,
2e708f348f20caa47210cf46cf7654f167fa47bbTimo Sirainen stream->last_failed_errno = stream->stream_errno;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenoff_t io_stream_copy(struct ostream *outstream, struct istream *instream)
const unsigned char *data;
if (ret <= 0) {
if (ret == 0)
bool close_parent)
if (set) {
int ret;
return ret;
void *context)
static size_t
struct ostream *
return output;
struct ostream *
return output;