21
22
return stream->real_stream->iostream.name;
25
static void i_stream_close_full(struct istream *stream, bool close_parents)
27
io_stream_close(&stream->real_stream->iostream, close_parents);
28
stream->closed = TRUE;
30
if (stream->stream_errno == 0)
31
stream->stream_errno = EPIPE;
24
34
void i_stream_destroy(struct istream **stream)
26
i_stream_close(*stream);
36
i_stream_close_full(*stream, FALSE);
27
37
i_stream_unref(stream);
47
#undef i_stream_set_destroy_callback
48
void i_stream_set_destroy_callback(struct istream *stream,
57
#undef i_stream_add_destroy_callback
58
void i_stream_add_destroy_callback(struct istream *stream,
49
59
istream_callback_t *callback, void *context)
51
61
struct iostream_private *iostream = &stream->real_stream->iostream;
62
struct iostream_destroy_callback *dc;
53
iostream->destroy_callback = callback;
54
iostream->destroy_context = context;
64
if (!array_is_created(&iostream->destroy_callbacks))
65
i_array_init(&iostream->destroy_callbacks, 2);
66
dc = array_append_space(&iostream->destroy_callbacks);
67
dc->callback = callback;
68
dc->context = context;
57
void i_stream_unset_destroy_callback(struct istream *stream)
71
void i_stream_remove_destroy_callback(struct istream *stream,
59
74
struct iostream_private *iostream = &stream->real_stream->iostream;
75
const struct iostream_destroy_callback *dcs;
76
unsigned int i, count;
61
iostream->destroy_callback = NULL;
62
iostream->destroy_context = NULL;
78
dcs = array_get(&iostream->destroy_callbacks, &count);
79
for (i = 0; i < count; i++) {
80
if (dcs[i].callback == callback) {
81
array_delete(&iostream->destroy_callbacks, i, 1);
65
88
int i_stream_get_fd(struct istream *stream)
69
92
return _stream->fd;
95
const char *i_stream_get_error(struct istream *stream)
99
/* we'll only return errors for streams that have stream_errno set.
100
we might be returning unintended error otherwise. */
101
if (stream->stream_errno == 0)
104
for (s = stream; s != NULL; s = s->real_stream->parent) {
105
if (s->stream_errno == 0)
107
if (s->real_stream->iostream.error != NULL)
108
return s->real_stream->iostream.error;
110
return strerror(stream->stream_errno);
72
113
void i_stream_close(struct istream *stream)
74
io_stream_close(&stream->real_stream->iostream);
75
stream->closed = TRUE;
77
if (stream->stream_errno == 0)
78
stream->stream_errno = ENOENT;
115
i_stream_close_full(stream, TRUE);
81
118
void i_stream_set_init_buffer_size(struct istream *stream, size_t size)
271
const struct stat *i_stream_stat(struct istream *stream, bool exact)
310
int i_stream_stat(struct istream *stream, bool exact, const struct stat **st_r)
273
312
struct istream_private *_stream = stream->real_stream;
275
314
if (unlikely(stream->closed))
278
return _stream->stat(_stream, exact);
317
if (_stream->stat(_stream, exact) < 0)
319
*st_r = &_stream->statbuf;
281
323
int i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r)
379
425
if (line != NULL)
382
if (i_stream_read(stream) <= 0)
428
switch (i_stream_read(stream)) {
430
stream->stream_errno = ENOBUFS;
383
434
return i_stream_last_line(stream->real_stream);
442
bool i_stream_last_line_crlf(struct istream *stream)
444
return stream->real_stream->line_crlf;
388
447
const unsigned char *
389
448
i_stream_get_data(const struct istream *stream, size_t *size_r)
505
*size_r = stream->buffer_size - stream->pos;
506
return stream->pos != stream->buffer_size;
573
*size_r = stream->buffer_size - stream->pos;
574
if (stream->try_alloc_limit > 0 &&
575
*size_r > stream->try_alloc_limit)
576
*size_r = stream->try_alloc_limit;
580
void *i_stream_alloc(struct istream_private *stream, size_t size)
582
size_t old_size, avail_size;
584
i_stream_try_alloc(stream, size, &avail_size);
585
if (avail_size < size) {
586
old_size = stream->buffer_size;
587
stream->buffer_size = nearest_power(stream->pos + size);
588
stream->w_buffer = i_realloc(stream->w_buffer, old_size,
589
stream->buffer_size);
590
stream->buffer = stream->w_buffer;
591
i_stream_try_alloc(stream, size, &avail_size);
592
i_assert(avail_size >= size);
594
return stream->w_buffer + stream->pos;
509
597
bool i_stream_add_data(struct istream *_stream, const unsigned char *data,
532
620
i_stream_set_max_buffer_size(_stream->parent, max_size);
623
static void i_stream_default_close(struct iostream_private *stream,
626
struct istream_private *_stream = (struct istream_private *)stream;
628
if (close_parent && _stream->parent != NULL)
629
i_stream_close(_stream->parent);
535
632
static void i_stream_default_destroy(struct iostream_private *stream)
537
634
struct istream_private *_stream = (struct istream_private *)stream;
541
638
i_stream_unref(&_stream->parent);
544
void i_stream_default_seek(struct istream_private *stream,
545
uoff_t v_offset, bool mark ATTR_UNUSED)
642
i_stream_default_seek_seekable(struct istream_private *stream,
643
uoff_t v_offset, bool mark ATTR_UNUSED)
645
stream->istream.v_offset = v_offset;
646
stream->skip = stream->pos = 0;
649
void i_stream_default_seek_nonseekable(struct istream_private *stream,
650
uoff_t v_offset, bool mark ATTR_UNUSED)
547
652
size_t available;
549
654
if (stream->istream.v_offset > v_offset)
550
i_panic("stream doesn't support seeking backwards");
655
i_panic("stream %s doesn't support seeking backwards",
656
i_stream_get_name(&stream->istream));
552
658
while (stream->istream.v_offset < v_offset) {
553
659
(void)i_stream_read(&stream->istream);
569
static const struct stat *
570
i_stream_default_stat(struct istream_private *stream, bool exact ATTR_UNUSED)
676
i_stream_default_stat(struct istream_private *stream, bool exact)
572
return &stream->statbuf;
678
const struct stat *st;
680
if (stream->parent == NULL)
681
return stream->istream.stream_errno == 0 ? 0 : -1;
683
if (i_stream_stat(stream->parent, exact, &st) < 0)
685
stream->statbuf = *st;
686
if (exact && !stream->stream_size_passthrough) {
687
/* exact size is not known, even if parent returned something */
688
stream->statbuf.st_size = -1;
576
694
i_stream_default_get_size(struct istream_private *stream,
577
695
bool exact, uoff_t *size_r)
579
const struct stat *st;
581
st = stream->stat(stream, exact);
697
if (stream->stat(stream, exact) < 0)
584
if (st->st_size == -1)
699
if (stream->statbuf.st_size == -1)
587
*size_r = st->st_size;
702
*size_r = stream->statbuf.st_size;
706
void i_stream_init_parent(struct istream_private *_stream,
707
struct istream *parent)
709
_stream->access_counter = parent->real_stream->access_counter;
710
_stream->parent = parent;
711
_stream->parent_start_offset = parent->v_offset;
712
_stream->parent_expected_offset = parent->v_offset;
713
_stream->abs_start_offset = parent->v_offset +
714
parent->real_stream->abs_start_offset;
715
/* if parent stream is an istream-error, copy the error */
716
_stream->istream.stream_errno = parent->stream_errno;
717
_stream->istream.eof = parent->eof;
718
i_stream_ref(parent);
592
722
i_stream_create(struct istream_private *_stream, struct istream *parent, int fd)
594
724
_stream->fd = fd;
595
if (parent != NULL) {
596
_stream->access_counter = parent->real_stream->access_counter;
597
_stream->parent = parent;
598
_stream->parent_start_offset = parent->v_offset;
599
_stream->parent_expected_offset = parent->v_offset;
600
_stream->abs_start_offset = parent->v_offset +
601
parent->real_stream->abs_start_offset;
602
i_stream_ref(parent);
726
i_stream_init_parent(_stream, parent);
604
727
_stream->istream.real_stream = _stream;
729
if (_stream->iostream.close == NULL)
730
_stream->iostream.close = i_stream_default_close;
606
731
if (_stream->iostream.destroy == NULL)
607
732
_stream->iostream.destroy = i_stream_default_destroy;
608
733
if (_stream->seek == NULL) {
609
i_assert(!_stream->istream.seekable);
610
_stream->seek = i_stream_default_seek;
734
_stream->seek = _stream->istream.seekable ?
735
i_stream_default_seek_seekable :
736
i_stream_default_seek_nonseekable;
612
738
if (_stream->stat == NULL)
613
739
_stream->stat = i_stream_default_stat;
629
755
io_stream_init(&_stream->iostream);
630
756
return &_stream->istream;
759
struct istream *i_stream_create_error(int stream_errno)
761
struct istream_private *stream;
763
stream = i_new(struct istream_private, 1);
764
stream->istream.closed = TRUE;
765
stream->istream.readable_fd = FALSE;
766
stream->istream.blocking = TRUE;
767
stream->istream.seekable = TRUE;
768
stream->istream.eof = TRUE;
769
stream->istream.stream_errno = stream_errno;
770
i_stream_create(stream, NULL, -1);
771
i_stream_set_name(&stream->istream, "(error)");
772
return &stream->istream;
776
i_stream_create_error_str(int stream_errno, const char *fmt, ...)
778
struct istream *input;
782
input = i_stream_create_error(stream_errno);
783
io_stream_set_verror(&input->real_stream->iostream, fmt, args);