istream-file.c revision 331b4805d76c0b3a5a38a560276f3cf110f55ba0
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* @UNSAFE: whole file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "ioloop.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "istream-internal.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "network.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <time.h>
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include <unistd.h>
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen#include <fcntl.h>
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include <sys/stat.h>
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstruct file_istream {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct istream_private istream;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen uoff_t skip_left;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen unsigned int file:1;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen unsigned int autoclose_fd:1;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen unsigned int seen_eof:1;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void i_stream_file_close(struct iostream_private *stream)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen{
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen struct file_istream *fstream = (struct file_istream *)stream;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen struct istream_private *_stream = (struct istream_private *)stream;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (fstream->autoclose_fd && _stream->fd != -1) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (close(_stream->fd) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_error("file_istream.close(%s) failed: %m",
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen i_stream_get_name(&_stream->istream));
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen _stream->fd = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int i_stream_file_open(struct istream_private *stream)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen const char *path = i_stream_get_name(&stream->istream);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen stream->fd = open(path, O_RDONLY);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (stream->fd == -1) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen stream->istream.stream_errno = errno;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_error("file_istream.open(%s) failed: %m", path);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen return 0;
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen}
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainenstatic ssize_t i_stream_file_read(struct istream_private *stream)
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ssize_t ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!i_stream_get_buffer_space(stream, 1, &size))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -2;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (stream->fd == -1) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (i_stream_file_open(stream) < 0)
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen return -1;
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen }
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen do {
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if (fstream->file) {
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen ret = pread(stream->fd, stream->w_buffer + stream->pos,
5c1a8aee989af87bddefd71e2aa83aa2bd695155Timo Sirainen size, stream->istream.v_offset +
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen (stream->pos - stream->skip));
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen } else if (fstream->seen_eof) {
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen /* don't try to read() again. EOF from keyboard (^D)
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen requires this to work right. */
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen ret = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = read(stream->fd, stream->w_buffer + stream->pos,
ec1e30ecc38f0deddaf655413cf02d5972ddbc70Timo Sirainen size);
ec1e30ecc38f0deddaf655413cf02d5972ddbc70Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } while (unlikely(ret < 0 && errno == EINTR &&
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen stream->istream.blocking));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen if (ret == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* EOF */
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen stream->istream.eof = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fstream->seen_eof = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (unlikely(ret < 0)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (errno == EINTR || errno == EAGAIN) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(!stream->istream.blocking);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(errno != 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen stream->istream.stream_errno = errno;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen if (ret > 0 && fstream->skip_left > 0) {
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen i_assert(!fstream->file);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(stream->skip == stream->pos);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (fstream->skip_left >= (size_t)ret) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fstream->skip_left -= ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret -= fstream->skip_left;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen stream->pos += fstream->skip_left;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen stream->skip += fstream->skip_left;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fstream->skip_left = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen stream->pos += ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(ret != 0 || !fstream->file);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(ret != -1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void i_stream_file_seek(struct istream_private *stream, uoff_t v_offset,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen bool mark ATTR_UNUSED)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (!stream->istream.seekable) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (v_offset < stream->istream.v_offset)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen i_panic("stream doesn't support seeking backwards");
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen fstream->skip_left += v_offset - stream->istream.v_offset;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen stream->istream.v_offset = v_offset;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen stream->skip = stream->pos = 0;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen fstream->seen_eof = FALSE;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainenstatic void i_stream_file_sync(struct istream_private *stream)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (!stream->istream.seekable) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen /* can't do anything or data would be lost */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen stream->skip = stream->pos = 0;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
bef8712387812fc5d9496b9958935c6d0c418777Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenstatic const struct stat *
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Siraineni_stream_file_stat(struct istream_private *stream, bool exact ATTR_UNUSED)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen const char *name = i_stream_get_name(&stream->istream);
bef8712387812fc5d9496b9958935c6d0c418777Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (!fstream->file) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen /* return defaults */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen } else if (stream->fd != -1) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (fstat(stream->fd, &stream->statbuf) < 0) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen i_error("file_istream.fstat(%s) failed: %m", name);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return NULL;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen } else {
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen if (stat(name, &stream->statbuf) < 0) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen i_error("file_istream.fstat(%s) failed: %m", name);
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen return NULL;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen return &stream->statbuf;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic struct istream *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Siraineni_stream_create_file_common(int fd, size_t max_buffer_size, bool autoclose_fd)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct file_istream *fstream;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct stat st;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen bool is_file;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen fstream = i_new(struct file_istream, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fstream->autoclose_fd = autoclose_fd;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen fstream->istream.iostream.close = i_stream_file_close;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fstream->istream.max_buffer_size = max_buffer_size;
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen fstream->istream.read = i_stream_file_read;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fstream->istream.seek = i_stream_file_seek;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fstream->istream.sync = i_stream_file_sync;
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen fstream->istream.stat = i_stream_file_stat;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen /* if it's a file, set the flags properly */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (fd == -1)
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen is_file = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else if (fstat(fd, &st) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen is_file = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else if (S_ISREG(st.st_mode))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen is_file = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else if (!S_ISDIR(st.st_mode))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen is_file = FALSE;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen else {
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen /* we're trying to open a directory.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen we're not designed for it. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fstream->istream.istream.stream_errno = EISDIR;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen is_file = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen if (is_file) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen fstream->file = TRUE;
5529671faac3c5672a948be93091056736c7afffTimo Sirainen fstream->istream.istream.blocking = TRUE;
5529671faac3c5672a948be93091056736c7afffTimo Sirainen fstream->istream.istream.seekable = TRUE;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen }
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen fstream->istream.istream.readable_fd = TRUE;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return i_stream_create(&fstream->istream, NULL, fd);
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen}
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainenstruct istream *i_stream_create_fd(int fd, size_t max_buffer_size,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen bool autoclose_fd)
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(fd != -1);
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return i_stream_create_file_common(fd, max_buffer_size, autoclose_fd);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainenstruct istream *i_stream_create_file(const char *path, size_t max_buffer_size)
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen struct istream *input;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen input = i_stream_create_file_common(-1, max_buffer_size, TRUE);
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen i_stream_set_name(input, path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return input;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen