istream.c revision fb502495e9306fe51e9d2c0019e622a98e9803ab
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2002-2015 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_set_name(struct istream *stream, const char *name)
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen stream->real_stream->iostream.name = i_strdup(name);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenconst char *i_stream_get_name(struct istream *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen while (stream->real_stream->iostream.name == NULL) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic void i_stream_close_full(struct istream *stream, bool close_parents)
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen io_stream_close(&stream->real_stream->iostream, close_parents);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen io_stream_ref(&stream->real_stream->iostream);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct istream_private *_stream = (*stream)->real_stream;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen io_stream_unref(&(*stream)->real_stream->iostream);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_add_destroy_callback(struct istream *stream,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen io_stream_add_destroy_callback(&stream->real_stream->iostream,
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainenvoid i_stream_remove_destroy_callback(struct istream *stream,
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen io_stream_remove_destroy_callback(&stream->real_stream->iostream,
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen struct istream_private *_stream = stream->real_stream;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainenconst char *i_stream_get_error(struct istream *stream)
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen /* we'll only return errors for streams that have stream_errno set.
e438c85a6b0f77889e25913bbbba808d6078282dStephan Bosch we might be returning unintended error otherwise. */
c977ee6ce06cbc0b4668fde1ec34f2f5e1773684Timo Sirainen return "<no error>";
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen for (s = stream; s != NULL; s = s->real_stream->parent) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenvoid i_stream_set_init_buffer_size(struct istream *stream, size_t size)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen io_stream_set_max_buffer_size(&stream->real_stream->iostream, max_size);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainensize_t i_stream_get_max_buffer_size(struct istream *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_set_return_partial_line(struct istream *stream, bool set)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic void i_stream_update(struct istream_private *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->parent_expected_offset = stream->parent->v_offset;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *_stream = stream->real_stream;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0)) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_stream_seek(_stream->parent, _stream->parent_expected_offset);
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen i_assert(old_size <= _stream->pos - _stream->skip);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* error handling should be easier if we now just
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen assume the stream is now at EOF */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_assert(old_size == _stream->pos - _stream->skip);
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen i_assert((size_t)ret+old_size == _stream->pos - _stream->skip);
79fff45046397ba48c8693d5f37a1fd93096987fTimo Sirainen /* error handling should be easier if we now just
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen assume the stream is now at EOF. Note that we could get here
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen even if read() didn't return -1, although that's a little
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen bit sloppy istream implementation. */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenssize_t i_stream_read_copy_from_parent(struct istream *istream)
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen struct istream_private *stream = istream->real_stream;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen stream->buffer = i_stream_get_data(stream->parent, &pos);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if ((ret = i_stream_read(stream->parent)) == -2) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->istream.stream_errno = stream->parent->stream_errno;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->buffer = i_stream_get_data(stream->parent, &pos);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* check again, in case the parent stream had been seeked
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen backwards and the previous read() didn't get us far
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) :
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_skip(struct istream *stream, uoff_t count)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct istream_private *_stream = stream->real_stream;
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen /* within buffer */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* have to seek forward */
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen _stream->seek(_stream, stream->v_offset + count, FALSE);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool i_stream_can_optimize_seek(struct istream_private *stream)
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen /* use the fast route only if the parent stream hasn't been changed */
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen return i_stream_can_optimize_seek(stream->parent->real_stream);
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainenvoid i_stream_seek(struct istream *stream, uoff_t v_offset)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_stream_skip(stream, v_offset - stream->v_offset);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid i_stream_seek_mark(struct istream *stream, uoff_t v_offset)
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen struct istream_private *_stream = stream->real_stream;
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen struct istream_private *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint i_stream_stat(struct istream *stream, bool exact, const struct stat **st_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r)
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen struct istream_private *_stream = stream->real_stream;
b9dc21a94401638c00e40b695998875e1563ce77Timo Sirainen return _stream->get_size(_stream, exact, size_r);
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainenbool i_stream_have_bytes_left(struct istream *stream)
27ca6cb0548c6478005c77d04be641356ec7d83cTimo Sirainen return i_stream_get_data_size(stream) > 0 || !stream->eof;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenuoff_t i_stream_get_absolute_offset(struct istream *stream)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return stream->real_stream->abs_start_offset + stream->v_offset;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainenstatic char *i_stream_next_line_finish(struct istream_private *stream, size_t i)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* modify the buffer directly */
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen ret = (char *)stream->w_buffer + stream->skip;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* use a temporary string to return it */
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen stream->line_str = str_new(default_pool, 256);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen str_append_n(stream->line_str, stream->buffer + stream->skip,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic char *i_stream_last_line(struct istream_private *_stream)
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen if (_stream->istream.eof && _stream->skip != _stream->pos &&
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* the last line is missing LF and we want to return it. */
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen return i_stream_next_line_finish(_stream, _stream->pos);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainenchar *i_stream_next_line(struct istream *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const unsigned char *pos;
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen pos = memchr(_stream->buffer + _stream->skip, '\n',
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainenchar *i_stream_read_next_line(struct istream *stream)
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen io_stream_set_error(&stream->real_stream->iostream,
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen i_stream_get_data_size(stream), stream->v_offset);
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen return i_stream_last_line(stream->real_stream);
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainenbool i_stream_last_line_crlf(struct istream *stream)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenstatic bool i_stream_is_buffer_invalid(const struct istream_private *stream)
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen /* the buffer can't point to parent, because it doesn't exist */
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen /* we can pretty safely assume that the stream is using its
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen own private buffer, so it can never become invalid. */
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen stream->parent->real_stream->access_counter) {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen /* parent has been modified behind this stream, we can't trust
265cb53cf8d5cb35edd4c4ff086ca6165605b708Timo Sirainen that our buffer is valid */
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen return i_stream_is_buffer_invalid(stream->parent->real_stream);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainenconst unsigned char *
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Siraineni_stream_get_data(struct istream *stream, size_t *size_r)
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen struct istream_private *_stream = stream->real_stream;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen /* This stream may be using parent's buffer directly as
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen _stream->buffer, but the parent stream has already been
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen modified indirectly. This means that the buffer might no
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen longer point to where we assume it points to. So we'll
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen just return the stream as empty until it's read again.
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen It's a bit ugly to suddenly drop data from the stream that
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen was already read, but since this happens only with shared
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen parent istreams the caller is hopefully aware enough that
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen something like this might happen. The other solutions would
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen be to a) try to automatically read the data back (but we
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen can't handle errors..) or b) always copy data to stream's
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen own buffer instead of pointing to parent's buffer (but this
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen causes data copying that is nearly always unnecessary). */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* if we had already read until EOF, mark the stream again as
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen not being at the end of file. */
216cd45a5f47c9bd46fe67c1b3bd6b1a42f6e39cTimo Sirainensize_t i_stream_get_data_size(struct istream *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenunsigned char *i_stream_get_modifiable_data(struct istream *stream,
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen struct istream_private *_stream = stream->real_stream;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen if (_stream->skip >= _stream->pos || _stream->w_buffer == NULL) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint i_stream_read_data(struct istream *stream, const unsigned char **data_r,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen /* we need more data */
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen } while (ret > 0);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen /* need to read more */
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen /* we read at least some new data */
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenvoid i_stream_compress(struct istream_private *stream)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen memmove(stream->w_buffer, stream->w_buffer + stream->skip,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenvoid i_stream_grow_buffer(struct istream_private *stream, size_t bytes)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (stream->buffer_size <= stream->init_buffer_size)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen stream->buffer_size = stream->init_buffer_size;
7f472e15b5f19a3536634863950c80a88079da23Timo Sirainen stream->buffer_size = nearest_power(stream->buffer_size);
0139fcb57a88f6ed27a1bb4a1bd537b04fd2b5d6Timo Sirainen if (stream->buffer_size > stream->max_buffer_size)
0139fcb57a88f6ed27a1bb4a1bd537b04fd2b5d6Timo Sirainen stream->buffer_size = stream->max_buffer_size;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen stream->w_buffer = i_realloc(stream->w_buffer, old_size,
1503ac7619d97193d6690292b5f9523552c5d6ceTimo Sirainenbool i_stream_try_alloc(struct istream_private *stream,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (wanted_size > stream->buffer_size - stream->pos) {
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen /* remove the unused bytes from beginning of buffer */
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen stream->buffer_size < stream->max_buffer_size) {
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen /* buffer is full - grow it */
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen i_stream_grow_buffer(stream, I_STREAM_MIN_SIZE);
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainenvoid *i_stream_alloc(struct istream_private *stream, size_t size)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_stream_try_alloc(stream, size, &avail_size);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen stream->buffer_size = nearest_power(stream->pos + size);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen stream->w_buffer = i_realloc(stream->w_buffer, old_size,
8c81109dca287f1830aac57bae61e57260248941Timo Sirainen i_stream_try_alloc(stream, size, &avail_size);
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainenbool i_stream_add_data(struct istream *_stream, const unsigned char *data,
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen struct istream_private *stream = _stream->real_stream;
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen memcpy(stream->w_buffer + stream->pos, data, size);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_set_input_pending(struct istream *stream, bool pending)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_switch_ioloop(struct istream *stream)
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen if (stream->real_stream->switch_ioloop != NULL)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen stream->real_stream->switch_ioloop(stream->real_stream);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainenvoid i_stream_set_io(struct istream *stream, struct io *io)
a020eb653b2620a989e4795adceb6136037327b2Timo Sirainenvoid i_stream_unset_io(struct istream *stream, struct io *io)
8cca3b43b28365cfee4dc733c00caaeab8ecd2adTimo Siraineni_stream_default_set_max_buffer_size(struct iostream_private *stream,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen struct istream_private *_stream = (struct istream_private *)stream;
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen i_stream_set_max_buffer_size(_stream->parent, max_size);
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainenstatic void i_stream_default_close(struct iostream_private *stream,
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen struct istream_private *_stream = (struct istream_private *)stream;
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainenstatic void i_stream_default_destroy(struct iostream_private *stream)
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen struct istream_private *_stream = (struct istream_private *)stream;
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Siraineni_stream_default_seek_seekable(struct istream_private *stream,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_default_seek_nonseekable(struct istream_private *stream,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_panic("stream %s doesn't support seeking backwards",
303e375b7e76278f4ec541f49af0476d3e4ee710Timo Sirainen /* read failed */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ", because we have data only up to offset %"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->istream.v_offset, stream->istream.eof);
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen if (available <= v_offset - stream->istream.v_offset)
85779ec11f23eb8efeb8993b1e0b9aad62c4122aTimo Siraineni_stream_default_stat(struct istream_private *stream, bool exact)
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen return stream->istream.stream_errno == 0 ? 0 : -1;
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen if (i_stream_stat(stream->parent, exact, &st) < 0)
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen if (exact && !stream->stream_size_passthrough) {
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen /* exact size is not known, even if parent returned something */
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Siraineni_stream_default_get_size(struct istream_private *stream,
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainenvoid i_stream_init_parent(struct istream_private *_stream,
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen _stream->access_counter = parent->real_stream->access_counter;
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen _stream->parent_start_offset = parent->v_offset;
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen _stream->parent_expected_offset = parent->v_offset;
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen _stream->abs_start_offset = parent->v_offset +
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen /* if parent stream is an istream-error, copy the error */
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen _stream->istream.stream_errno = parent->stream_errno;
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Siraineni_stream_create(struct istream_private *_stream, struct istream *parent, int fd)
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen _stream->iostream.close = i_stream_default_close;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen _stream->iostream.destroy = i_stream_default_destroy;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen _stream->get_size = i_stream_default_get_size;
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen if (_stream->iostream.set_max_buffer_size == NULL) {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen _stream->init_buffer_size = I_STREAM_MIN_SIZE;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen memset(&_stream->statbuf, 0, sizeof(_stream->statbuf));
85779ec11f23eb8efeb8993b1e0b9aad62c4122aTimo Sirainenstruct istream *i_stream_create_error(int stream_errno)
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen i_stream_set_name(&stream->istream, "(error)");
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Siraineni_stream_create_error_str(int stream_errno, const char *fmt, ...)