int ret = -1;
i_stream_seek(tstream->dupstream, tstream->dupstream_start_offset);
+ tstream->ostream.ostream.offset = 0;
input = i_stream_create_limit(tstream->dupstream, size);
+ i_stream_unref(&tstream->dupstream);
+
if (io_stream_copy(&tstream->ostream.ostream, input) > 0) {
/* everything copied */
ret = 0;
tstream->ostream.ostream.stream_errno = input->stream_errno;
}
i_stream_destroy(&input);
- i_stream_unref(&tstream->dupstream);
return ret;
}
return o_stream_temp_dup_cancel(outstream);
}
i_stream_seek(instream, in_size);
+ /* we should be at EOF now. o_stream_send_istream() asserts if
+ eof isn't set. */
+ instream->eof = TRUE;
outstream->dupstream_offset = instream->v_offset;
+ outstream->ostream.ostream.offset =
+ outstream->dupstream_offset - outstream->dupstream_start_offset;
return 1;
}
/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */
#include "test-lib.h"
+#include "istream.h"
#include "ostream.h"
#include "iostream-temp.h"
+#include <unistd.h>
+#include <fcntl.h>
+
static void test_iostream_temp_create_sized_memory(void)
{
struct ostream *output;
test_end();
}
+static void test_iostream_temp_istream(void)
+{
+ struct istream *input, *input2, *temp_input;
+ struct ostream *output;
+ int fd;
+
+ test_begin("iostream_temp istream");
+
+ fd = open(".temp.istream", O_RDWR | O_CREAT | O_TRUNC, 0600);
+ if (fd == -1)
+ i_fatal("create(.temp.istream) failed: %m");
+ test_assert(write(fd, "foobar", 6) == 6);
+ test_assert(lseek(fd, 0, SEEK_SET) == 0);
+
+ input = i_stream_create_fd(fd, 1024, TRUE);
+ /* a working fd-dup */
+ output = iostream_temp_create_sized(".nonexistent/",
+ IOSTREAM_TEMP_FLAG_TRY_FD_DUP, "test", 1);
+ test_assert(o_stream_send_istream(output, input) > 0);
+ temp_input = iostream_temp_finish(&output, 128);
+ test_assert(i_stream_read(temp_input) == 6);
+ i_stream_destroy(&temp_input);
+
+ /* non-working fd-dup: write data before sending istream */
+ i_stream_seek(input, 0);
+ output = iostream_temp_create_sized(".intentional-nonexistent-error/",
+ IOSTREAM_TEMP_FLAG_TRY_FD_DUP, "test", 4);
+ test_assert(o_stream_send(output, "1234", 4) == 4);
+ test_expect_errors(1);
+ test_assert(o_stream_send_istream(output, input) > 0);
+ test_expect_no_more_errors();
+ o_stream_destroy(&output);
+
+ /* non-working fd-dup: send two istreams */
+ i_stream_seek(input, 0);
+ input2 = i_stream_create_limit(input, (uoff_t)-1);
+ output = iostream_temp_create_sized(".intentional-nonexistent-error/",
+ IOSTREAM_TEMP_FLAG_TRY_FD_DUP, "test", 4);
+ test_assert(o_stream_send_istream(output, input) > 0);
+ test_expect_errors(1);
+ test_assert(o_stream_send_istream(output, input2) > 0);
+ test_expect_no_more_errors();
+ o_stream_destroy(&output);
+ i_stream_unref(&input2);
+
+ i_stream_destroy(&input);
+
+ i_unlink(".temp.istream");
+ test_end();
+}
+
void test_iostream_temp(void)
{
test_iostream_temp_create_sized_memory();
test_iostream_temp_create_sized_disk();
+ test_iostream_temp_istream();
}