dovecot-2.0: Added i_stream_create_file() for creating istream f...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Jul 15 22:38:32 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/b7d98c5db865
changeset: 11829:b7d98c5db865
user: Timo Sirainen <tss at iki.fi>
date: Thu Jul 15 20:38:29 2010 +0100
description:
Added i_stream_create_file() for creating istream from lazily opened file.
diffstat:
src/lib/istream-file.c | 57 +++++++++++++++++++++++++---
src/lib/istream.h | 3 +
2 files changed, 53 insertions(+), 7 deletions(-)
diffs (120 lines):
diff -r 6e0a2ce2910c -r b7d98c5db865 src/lib/istream-file.c
--- a/src/lib/istream-file.c Thu Jul 15 17:03:42 2010 +0000
+++ b/src/lib/istream-file.c Thu Jul 15 20:38:29 2010 +0100
@@ -9,6 +9,7 @@
#include <time.h>
#include <unistd.h>
+#include <fcntl.h>
#include <sys/stat.h>
struct file_istream {
@@ -35,6 +36,19 @@
_stream->fd = -1;
}
+static int i_stream_file_open(struct istream_private *stream)
+{
+ const char *path = i_stream_get_name(&stream->istream);
+
+ stream->fd = open(path, O_RDONLY);
+ if (stream->fd == -1) {
+ stream->istream.stream_errno = errno;
+ i_error("file_istream.open(%s) failed: %m", path);
+ return -1;
+ }
+ return 0;
+}
+
static ssize_t i_stream_file_read(struct istream_private *stream)
{
struct file_istream *fstream = (struct file_istream *) stream;
@@ -44,6 +58,11 @@
if (!i_stream_get_buffer_space(stream, 1, &size))
return -2;
+ if (stream->fd == -1) {
+ if (i_stream_file_open(stream) < 0)
+ return -1;
+ }
+
do {
if (fstream->file) {
ret = pread(stream->fd, stream->w_buffer + stream->pos,
@@ -129,11 +148,18 @@
i_stream_file_stat(struct istream_private *stream, bool exact ATTR_UNUSED)
{
struct file_istream *fstream = (struct file_istream *) stream;
+ const char *name = i_stream_get_name(&stream->istream);
- if (fstream->file) {
- if (fstat(fstream->istream.fd, &fstream->istream.statbuf) < 0) {
- i_error("file_istream.fstat(%s) failed: %m",
- i_stream_get_name(&stream->istream));
+ if (!fstream->file) {
+ /* return defaults */
+ } else if (stream->fd != -1) {
+ if (fstat(stream->fd, &stream->statbuf) < 0) {
+ i_error("file_istream.fstat(%s) failed: %m", name);
+ return NULL;
+ }
+ } else {
+ if (stat(name, &stream->statbuf) < 0) {
+ i_error("file_istream.fstat(%s) failed: %m", name);
return NULL;
}
}
@@ -141,8 +167,8 @@
return &stream->statbuf;
}
-struct istream *i_stream_create_fd(int fd, size_t max_buffer_size,
- bool autoclose_fd)
+static struct istream *
+i_stream_create_file_common(int fd, size_t max_buffer_size, bool autoclose_fd)
{
struct file_istream *fstream;
struct stat st;
@@ -158,7 +184,7 @@
fstream->istream.stat = i_stream_file_stat;
/* if it's a file, set the flags properly */
- if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {
+ if (fd == -1 || (fstat(fd, &st) == 0 && S_ISREG(st.st_mode))) {
fstream->file = TRUE;
fstream->istream.istream.blocking = TRUE;
fstream->istream.istream.seekable = TRUE;
@@ -167,3 +193,20 @@
return i_stream_create(&fstream->istream, NULL, fd);
}
+
+struct istream *i_stream_create_fd(int fd, size_t max_buffer_size,
+ bool autoclose_fd)
+{
+ i_assert(fd != -1);
+
+ return i_stream_create_file_common(fd, max_buffer_size, autoclose_fd);
+}
+
+struct istream *i_stream_create_file(const char *path, size_t max_buffer_size)
+{
+ struct istream *input;
+
+ input = i_stream_create_file_common(-1, max_buffer_size, TRUE);
+ i_stream_set_name(input, path);
+ return input;
+}
diff -r 6e0a2ce2910c -r b7d98c5db865 src/lib/istream.h
--- a/src/lib/istream.h Thu Jul 15 17:03:42 2010 +0000
+++ b/src/lib/istream.h Thu Jul 15 20:38:29 2010 +0100
@@ -24,6 +24,9 @@
struct istream *i_stream_create_fd(int fd, size_t max_buffer_size,
bool autoclose_fd);
+/* Open the given path only when something is actually tried to be read from
+ the stream. */
+struct istream *i_stream_create_file(const char *path, size_t max_buffer_size);
struct istream *i_stream_create_mmap(int fd, size_t block_size,
uoff_t start_offset, uoff_t v_size,
bool autoclose_fd);
More information about the dovecot-cvs
mailing list