bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainenvoid o_stream_set_name(struct ostream *stream, const char *name)
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen stream->real_stream->iostream.name = i_strdup(name);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainenconst char *o_stream_get_name(struct ostream *stream)
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen while (stream->real_stream->iostream.name == NULL) {
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainenconst char *o_stream_get_error(struct ostream *stream)
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen /* we'll only return errors for streams that have stream_errno set.
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen we might be returning unintended error otherwise. */
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen return "<no error>";
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen for (s = stream; s != NULL; s = s->real_stream->parent) {
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenstatic void o_stream_close_full(struct ostream *stream, bool close_parents)
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen /* Ideally o_stream_finish() would be called for all non-failed
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen ostreams, but strictly requiring it would cause unnecessary
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen complexity for many callers. Just require that at this point
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen after flushing there isn't anything in the output buffer or that
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen we're ignoring all errors. */
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen i_assert(stream->real_stream->error_handling_disabled);
9a48c2243fe98ca8393be7908f84d20c634bcdf9Timo Sirainen if (!stream->closed && !stream->real_stream->closing) {
9a48c2243fe98ca8393be7908f84d20c634bcdf9Timo Sirainen /* first mark the stream as being closed so the
9a48c2243fe98ca8393be7908f84d20c634bcdf9Timo Sirainen o_stream_copy_error_from_parent() won't recurse us back
9a48c2243fe98ca8393be7908f84d20c634bcdf9Timo Sirainen here. but don't immediately mark the stream closed, because
9a48c2243fe98ca8393be7908f84d20c634bcdf9Timo Sirainen we may still want to write something to it. */
59e26ff34b05cd971a111f8a42fc60c13d9f688bTimo Sirainen io_stream_close(&stream->real_stream->iostream, close_parents);
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen io_stream_ref(&stream->real_stream->iostream);
571fd6ff94570ee11a72a20b649acfdac2495919Timo Sirainen if (stream->real_stream->last_errors_not_checked &&
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen !stream->real_stream->error_handling_disabled &&
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen stream->real_stream->iostream.refcount == 1) {
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen i_panic("output stream %s is missing error handling",
5a1b498b646b5c5dbd1b3f3861df766f560578c5Timo Sirainen if (!io_stream_unref(&stream->real_stream->iostream))
5a1b498b646b5c5dbd1b3f3861df766f560578c5Timo Sirainen io_stream_free(&stream->real_stream->iostream);
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainenvoid o_stream_add_destroy_callback(struct ostream *stream,
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen io_stream_add_destroy_callback(&stream->real_stream->iostream,
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainenvoid o_stream_remove_destroy_callback(struct ostream *stream,
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen io_stream_remove_destroy_callback(&stream->real_stream->iostream,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainenvoid o_stream_set_flush_callback(struct ostream *stream,
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct ostream_private *_stream = stream->real_stream;
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen _stream->set_flush_callback(_stream, callback, context);
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainenvoid o_stream_unset_flush_callback(struct ostream *stream)
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen struct ostream_private *_stream = stream->real_stream;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen _stream->set_flush_callback(_stream, NULL, NULL);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenvoid o_stream_set_max_buffer_size(struct ostream *stream, size_t max_size)
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen io_stream_set_max_buffer_size(&stream->real_stream->iostream, max_size);
556f95092c3bc850517d5ab2bb502024a55645f1Timo Sirainensize_t o_stream_get_max_buffer_size(struct ostream *stream)
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct ostream_private *_stream = stream->real_stream;
3d77cc0d502dc69ffe2afe318605964dd40b7b20Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0))
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct ostream_private *_stream = stream->real_stream;
3d77cc0d502dc69ffe2afe318605964dd40b7b20Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0))
10ff47d5d6146995e16da00d36eca7d162064a7bTimo Sirainenbool o_stream_is_corked(struct ostream *stream)
10ff47d5d6146995e16da00d36eca7d162064a7bTimo Sirainen struct ostream_private *_stream = stream->real_stream;
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct ostream_private *_stream = stream->real_stream;
3d77cc0d502dc69ffe2afe318605964dd40b7b20Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0)) {
34d5077c37dc6224a2d430a72ae51a3f38e9e4f6Timo Sirainen "Output stream buffer was full (%"PRIuSIZE_T" bytes)",
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen if (unlikely((ret = _stream->flush(_stream)) < 0)) {
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenvoid o_stream_set_flush_pending(struct ostream *stream, bool set)
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct ostream_private *_stream = stream->real_stream;
3d77cc0d502dc69ffe2afe318605964dd40b7b20Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0))
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainensize_t o_stream_get_buffer_used_size(const struct ostream *stream)
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen const struct ostream_private *_stream = stream->real_stream;
de954ff15b495be13007a8aca2c09fd1d356a283Timo Sirainensize_t o_stream_get_buffer_avail_size(const struct ostream *stream)
de954ff15b495be13007a8aca2c09fd1d356a283Timo Sirainen size_t used = o_stream_get_buffer_used_size(stream);
de954ff15b495be13007a8aca2c09fd1d356a283Timo Sirainen return stream->real_stream->max_buffer_size <= used ? 0 :
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenint o_stream_seek(struct ostream *stream, uoff_t offset)
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct ostream_private *_stream = stream->real_stream;
3d77cc0d502dc69ffe2afe318605964dd40b7b20Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0)) {
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen if (unlikely(_stream->seek(_stream, offset) < 0)) {
b92e979748a22925b0770d3004eaab043ed69574Timo Sirainenssize_t o_stream_send(struct ostream *stream, const void *data, size_t size)
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Siraineno_stream_sendv_int(struct ostream *stream, const struct const_iovec *iov,
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct ostream_private *_stream = stream->real_stream;
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen unsigned int i;
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen for (i = 0, total_size = 0; i < iov_count; i++)
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen ret = _stream->sendv(_stream, iov, iov_count);
f8b6c3d6bc9d63665af5e0a3c8b604438e4c3a4eTimo Sirainen stream->real_stream->last_write_timeval = ioloop_timeval;
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainenssize_t o_stream_sendv(struct ostream *stream, const struct const_iovec *iov,
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0)) {
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen return o_stream_sendv_int(stream, iov, iov_count, &overflow);
b92e979748a22925b0770d3004eaab043ed69574Timo Sirainenssize_t o_stream_send_str(struct ostream *stream, const char *str)
555ebb032f9b8f0cdb66f27ce7374734833e7cacTimo Sirainen return o_stream_send(stream, str, strlen(str));
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenvoid o_stream_nsend(struct ostream *stream, const void *data, size_t size)
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenvoid o_stream_nsendv(struct ostream *stream, const struct const_iovec *iov,
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0 ||
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen (void)o_stream_sendv_int(stream, iov, iov_count, &overflow);
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen stream->real_stream->last_errors_not_checked = TRUE;
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenvoid o_stream_nsend_str(struct ostream *stream, const char *str)
d6193a892452ae87548f5745dada01f82816765dTimo Sirainenvoid o_stream_set_finish_also_parent(struct ostream *stream, bool set)
d6193a892452ae87548f5745dada01f82816765dTimo Sirainen stream->real_stream->finish_also_parent = set;
d6193a892452ae87548f5745dada01f82816765dTimo Sirainenvoid o_stream_set_finish_via_child(struct ostream *stream, bool set)
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenvoid o_stream_ignore_last_errors(struct ostream *stream)
98a73e104c7b9c3747053e63113451e24daf7f36Timo Sirainen stream->real_stream->last_errors_not_checked = FALSE;
7660a5183e89459d255dc5873894ff08806711d5Timo Sirainen io_stream_set_error(&stream->real_stream->iostream, "aborted writing");
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenvoid o_stream_set_no_error_handling(struct ostream *stream, bool set)
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen stream->real_stream->error_handling_disabled = set;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Siraineno_stream_send_istream(struct ostream *outstream, struct istream *instream)
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct ostream_private *_outstream = outstream->real_stream;
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen uoff_t old_outstream_offset = outstream->offset;
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen uoff_t old_instream_offset = instream->v_offset;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen if (unlikely(instream->closed || instream->stream_errno != 0)) {
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen return OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen if (unlikely(outstream->closed || outstream->stream_errno != 0)) {
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen return OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen res = _outstream->send_istream(_outstream, instream);
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen i_assert(!i_stream_have_bytes_left(instream));
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen /* non-failure - make sure stream offsets match */
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen i_assert((outstream->offset - old_outstream_offset) ==
f8b6c3d6bc9d63665af5e0a3c8b604438e4c3a4eTimo Sirainen if (outstream->offset != old_outstream_offset)
f8b6c3d6bc9d63665af5e0a3c8b604438e4c3a4eTimo Sirainen outstream->real_stream->last_write_timeval = ioloop_timeval;
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainenvoid o_stream_nsend_istream(struct ostream *outstream, struct istream *instream)
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainen switch (o_stream_send_istream(outstream, instream)) {
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainen outstream->stream_errno = instream->stream_errno;
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainen io_stream_set_error(&outstream->real_stream->iostream,
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainen "nsend-istream: read(%s) failed: %s",
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainen outstream->real_stream->last_errors_not_checked = TRUE;
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainenint o_stream_pwrite(struct ostream *stream, const void *data, size_t size,
3d77cc0d502dc69ffe2afe318605964dd40b7b20Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0)) {
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen ret = stream->real_stream->write_at(stream->real_stream,
f8b6c3d6bc9d63665af5e0a3c8b604438e4c3a4eTimo Sirainen stream->real_stream->last_write_timeval = ioloop_timeval;
f8b6c3d6bc9d63665af5e0a3c8b604438e4c3a4eTimo Sirainenvoid o_stream_get_last_write_time(struct ostream *stream, struct timeval *tv_r)
f8b6c3d6bc9d63665af5e0a3c8b604438e4c3a4eTimo Sirainen *tv_r = stream->real_stream->last_write_timeval;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainenio_stream_copy(struct ostream *outstream, struct istream *instream)
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen while (i_stream_read_more(instream, &data, &iov.iov_len) > 0) {
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen if ((ret = o_stream_sendv(outstream, &iov, 1)) < 0)
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen return OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen else if (ret == 0)
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen return OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen return OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen return OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT;
8aa8399893c66b40e2790a4568256807a6ec6742Stephan Boschvoid o_stream_switch_ioloop_to(struct ostream *stream, struct ioloop *ioloop)
71da447014454c84828d9dface77219875554d7dTimo Sirainen struct ostream_private *_stream = stream->real_stream;
8aa8399893c66b40e2790a4568256807a6ec6742Stephan Bosch io_stream_switch_ioloop_to(&_stream->iostream, ioloop);
8aa8399893c66b40e2790a4568256807a6ec6742Stephan Boschvoid o_stream_switch_ioloop(struct ostream *stream)
8aa8399893c66b40e2790a4568256807a6ec6742Stephan Bosch o_stream_switch_ioloop_to(stream, current_ioloop);
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenstatic void o_stream_default_close(struct iostream_private *stream,
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen struct ostream_private *_stream = (struct ostream_private *)stream;
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainenstatic void o_stream_default_destroy(struct iostream_private *stream)
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen struct ostream_private *_stream = (struct ostream_private *)stream;
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Siraineno_stream_default_set_max_buffer_size(struct iostream_private *stream,
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen struct ostream_private *_stream = (struct ostream_private *)stream;
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen o_stream_set_max_buffer_size(_stream->parent, max_size);
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainenstatic void o_stream_default_cork(struct ostream_private *_stream, bool set)
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainenvoid o_stream_copy_error_from_parent(struct ostream_private *_stream)
d691782ae9eb4f6ab06bc42f1617e889e7c18a3bTimo Sirainenint o_stream_flush_parent_if_needed(struct ostream_private *_stream)
d691782ae9eb4f6ab06bc42f1617e889e7c18a3bTimo Sirainen if (o_stream_get_buffer_used_size(_stream->parent) >= IO_BLOCK_SIZE) {
d691782ae9eb4f6ab06bc42f1617e889e7c18a3bTimo Sirainen /* we already have quite a lot of data in parent stream.
d691782ae9eb4f6ab06bc42f1617e889e7c18a3bTimo Sirainen unless we can flush it, don't add any more to it or we
d691782ae9eb4f6ab06bc42f1617e889e7c18a3bTimo Sirainen could keep wasting memory by just increasing the buffer
d691782ae9eb4f6ab06bc42f1617e889e7c18a3bTimo Sirainen size all the time. */
d691782ae9eb4f6ab06bc42f1617e889e7c18a3bTimo Sirainen if (o_stream_get_buffer_used_size(_stream->parent) >= IO_BLOCK_SIZE)
5df4dbc38d7b7d54cba35a2c258366e1d4bac3c8Timo Sirainenint o_stream_flush_parent(struct ostream_private *_stream)
d6193a892452ae87548f5745dada01f82816765dTimo Sirainen if (!_stream->finished || !_stream->finish_also_parent ||
d6193a892452ae87548f5745dada01f82816765dTimo Sirainen !_stream->parent->real_stream->finish_via_child)
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainenstatic int o_stream_default_flush(struct ostream_private *_stream)
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Siraineno_stream_default_set_flush_callback(struct ostream_private *_stream,
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen o_stream_set_flush_callback(_stream->parent, callback, context);
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Siraineno_stream_default_set_flush_pending(struct ostream_private *_stream, bool set)
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen o_stream_set_flush_pending(_stream->parent, set);
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Siraineno_stream_default_get_used_size(const struct ostream_private *_stream)
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen return o_stream_get_buffer_used_size(_stream->parent);
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Siraineno_stream_default_seek(struct ostream_private *_stream,
981139bb2e446bb2050c1158614725f8413fd709Timo Siraineno_stream_default_sendv(struct ostream_private *stream,
981139bb2e446bb2050c1158614725f8413fd709Timo Sirainen const struct const_iovec *iov, unsigned int iov_count)
981139bb2e446bb2050c1158614725f8413fd709Timo Sirainen if ((ret = o_stream_sendv(stream->parent, iov, iov_count)) < 0) {
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Siraineno_stream_default_write_at(struct ostream_private *_stream,
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen size_t size ATTR_UNUSED, uoff_t offset ATTR_UNUSED)
378e6cb162b355d6f103526505bc00b9a78962e7Timo Siraineno_stream_default_send_istream(struct ostream_private *outstream,
46631c1d903c409444b1b1c4a1d41a033c09ee37Timo Sirainen return io_stream_copy(&outstream->ostream, instream);
8aa8399893c66b40e2790a4568256807a6ec6742Stephan Boscho_stream_default_switch_ioloop_to(struct ostream_private *_stream,
8aa8399893c66b40e2790a4568256807a6ec6742Stephan Bosch o_stream_switch_ioloop_to(_stream->parent, ioloop);
8b247780e911909a9fdc47f69ce6d1478902ad98Timo Siraineno_stream_create(struct ostream_private *_stream, struct ostream *parent, int fd)
f28583935a4509d3f7932738bba6c548ef455c82Timo Sirainen _stream->callback = parent->real_stream->callback;
f28583935a4509d3f7932738bba6c548ef455c82Timo Sirainen _stream->context = parent->real_stream->context;
f28583935a4509d3f7932738bba6c548ef455c82Timo Sirainen _stream->max_buffer_size = parent->real_stream->max_buffer_size;
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen _stream->iostream.close = o_stream_default_close;
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen _stream->iostream.destroy = o_stream_default_destroy;
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen if (_stream->iostream.set_max_buffer_size == NULL) {
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen _stream->flush_pending = o_stream_default_set_flush_pending;
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen _stream->get_used_size = o_stream_default_get_used_size;
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen _stream->write_at = o_stream_default_write_at;
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen _stream->send_istream = o_stream_default_send_istream;
8aa8399893c66b40e2790a4568256807a6ec6742Stephan Bosch _stream->switch_ioloop_to = o_stream_default_switch_ioloop_to;
0c1835a90dd1dcedaeaedd1cd91672299cbeb5beTimo Sirainenstruct ostream *o_stream_create_error(int stream_errno)
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Siraineno_stream_create_error_str(int stream_errno, const char *fmt, ...)
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Sirainen io_stream_set_verror(&output->real_stream->iostream, fmt, args);
981139bb2e446bb2050c1158614725f8413fd709Timo Sirainenstruct ostream *o_stream_create_passthrough(struct ostream *output)