{
struct istream_private *stream = &sstream->istream;
void *data;
+ size_t old_pos = stream->pos;
i_assert(sstream->fd != -1);
+ i_assert(stream->skip == 0);
stream->max_buffer_size = SIZE_MAX;
+ stream->pos = 0;
data = i_stream_alloc(stream, sstream->write_peak);
+ stream->pos = old_pos;
if (pread_full(sstream->fd, data, sstream->write_peak, 0) < 0) {
- i_error("istream-seekable: read(%s) failed: %m", sstream->temp_path);
- memarea_unref(&stream->memarea);
+ sstream->istream.istream.stream_errno = errno;
+ sstream->istream.istream.eof = TRUE;
+ io_stream_set_error(&sstream->istream.iostream,
+ "istream-seekable: read(%s) failed: %m",
+ sstream->temp_path);
return -1;
}
i_stream_destroy(&sstream->fd_input);
#include <fcntl.h>
#include <unistd.h>
+static int fd_callback_fd = -1;
+
static int fd_callback(const char **path_r, void *context ATTR_UNUSED)
{
int fd;
i_error("creat(%s) failed: %m", *path_r);
else
i_unlink(*path_r);
+ fd_callback_fd = fd;
return fd;
}
test_end();
}
+static void test_istream_seekable_failed_writes(void)
+{
+ struct istream *input, *streams[2];
+
+ test_begin("istream seekable failed write");
+ streams[0] = test_istream_create("stream");
+ test_istream_set_size(streams[0], 3);
+ test_istream_set_allow_eof(streams[0], FALSE);
+ streams[0]->seekable = FALSE;
+ streams[1] = NULL;
+
+ input = i_stream_create_seekable(streams, 2, fd_callback, NULL);
+ i_stream_set_name(input, "test seekable");
+ test_assert(i_stream_read(input) == 2);
+ i_stream_skip(input, 2);
+ test_assert(i_stream_read(input) == 1);
+ i_close_fd(&fd_callback_fd);
+ test_istream_set_size(streams[0], 5);
+
+ test_expect_error_string("istream-seekable: write_full(test-lib.tmp) failed: Bad file descriptor");
+ test_assert(i_stream_read(input) == -1);
+ test_expect_no_more_errors();
+
+ test_expect_error_string("file_istream.close((seekable temp-istream for: test seekable)) failed: Bad file descriptor");
+ i_stream_unref(&input);
+ test_expect_no_more_errors();
+
+ i_stream_unref(&streams[0]);
+ test_end();
+}
+
void test_istream_seekable(void)
{
unsigned int i;
test_istream_seekable_early_end();
test_istream_seekable_invalid_read();
test_istream_seekable_get_size();
+ test_istream_seekable_failed_writes();
}