blob: 3359bd3b258a44b8fe03bbd06e3bd60642b81d98 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "istream.h"
#include "ostream-private.h"
#include "ostream-metawrap.h"
struct metawrap_ostream {
struct ostream_private ostream;
void (*write_callback)(void *);
void *context;
};
static void o_stream_metawrap_call_callback(struct metawrap_ostream *mstream)
{
void (*write_callback)(void *) = mstream->write_callback;
if (write_callback != NULL) {
mstream->write_callback = NULL;
write_callback(mstream->context);
/* metadata headers aren't counted as part of the offset */
mstream->ostream.ostream.offset = 0;
}
}
static ssize_t
o_stream_metawrap_sendv(struct ostream_private *stream,
const struct const_iovec *iov, unsigned int iov_count)
{
struct metawrap_ostream *mstream = (struct metawrap_ostream *)stream;
ssize_t ret;
o_stream_metawrap_call_callback(mstream);
if ((ret = o_stream_sendv(stream->parent, iov, iov_count)) < 0)
o_stream_copy_error_from_parent(stream);
else
stream->ostream.offset += ret;
return ret;
}
static enum ostream_send_istream_result
o_stream_metawrap_send_istream(struct ostream_private *_outstream,
struct istream *instream)
{
struct metawrap_ostream *outstream =
(struct metawrap_ostream *)_outstream;
uoff_t orig_instream_offset = instream->v_offset;
enum ostream_send_istream_result res;
o_stream_metawrap_call_callback(outstream);
if ((res = o_stream_send_istream(_outstream->parent, instream)) == OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT)
o_stream_copy_error_from_parent(_outstream);
_outstream->ostream.offset += instream->v_offset - orig_instream_offset;
return res;
}
struct ostream *
o_stream_create_metawrap(struct ostream *output,
void (*write_callback)(void *), void *context)
{
struct metawrap_ostream *mstream;
mstream = i_new(struct metawrap_ostream, 1);
mstream->ostream.sendv = o_stream_metawrap_sendv;
mstream->ostream.send_istream = o_stream_metawrap_send_istream;
mstream->write_callback = write_callback;
mstream->context = context;
return o_stream_create(&mstream->ostream, output,
o_stream_get_fd(output));
}
|