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