istream-tee.c revision bcb4e51a409d94ae670de96afb8483a4f7855294
/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "istream-private.h"
#include "istream-tee.h"
struct tee_istream {
struct tee_child_istream *children;
};
struct tee_child_istream {
struct istream_private istream;
struct tee_istream *tee;
struct tee_child_istream *next;
bool last_read_waiting:1;
};
{
const unsigned char *data;
continue;
}
}
}
{
}
}
}
bool close_parent ATTR_UNUSED)
{
}
{
struct tee_child_istream **p;
if (*p == tstream) {
break;
}
}
/* last child. the tee is now destroyed */
} else {
}
/* i_stream_unref() shouldn't unref the parent */
}
static void
{
}
{
const unsigned char *data;
/* initial read */
}
/* last_high_offset contains how far we have read this child tee stream
so far. input->v_offset + size contains how much is available in
the parent stream without having to read more. */
/* we've read everything, need to read more */
if (ret <= 0) {
/* someone else is holding the data,
wait for it */
return 0;
}
return ret;
}
} else {
/* there's still some data available from parent */
}
return ret;
}
static int
{
return -1;
return 0;
}
{
i_panic("tee-istream: i_stream_sync() called "
"with data still buffered");
}
}
{
struct tee_istream *tee;
} else {
}
return tee;
}
{
struct tee_child_istream *tstream;
/* we keep the reference in tee stream, no need for extra references */
return ret;
}
{
struct tee_child_istream *tstream =
return tstream->last_read_waiting;
}