Coverage Report

Created: 2026-06-09 06:49

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