changeset 20859:d2d89eae7828

lib: ostream-file: Allow creating derived file output streams.
author Stephan Bosch <stephan@rename-it.nl>
date Sat, 30 Apr 2016 14:10:59 +0200
parents decbc9f93ddf
children 668274a98b48
files src/lib/Makefile.am src/lib/ostream-file-private.h src/lib/ostream-file.c
diffstat 3 files changed, 67 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/Makefile.am	Sat Apr 30 13:55:52 2016 +0200
+++ b/src/lib/Makefile.am	Sat Apr 30 14:10:59 2016 +0200
@@ -246,6 +246,7 @@
 	ostream.h \
 	ostream-escaped.h \
 	ostream-failure-at.h \
+	ostream-file-private.h \
 	ostream-hash.h \
 	ostream-private.h \
 	ostream-null.h \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/ostream-file-private.h	Sat Apr 30 14:10:59 2016 +0200
@@ -0,0 +1,43 @@
+#ifndef OSTREAM_FILE_PRIVATE_H
+#define OSTREAM_FILE_PRIVATE_H
+
+#include "ostream-private.h"
+
+struct file_ostream {
+	struct ostream_private ostream;
+
+	ssize_t (*writev)(struct file_ostream *fstream,
+		 const struct const_iovec *iov,
+		 unsigned int iov_count);
+
+	int fd;
+	struct io *io;
+	uoff_t buffer_offset;
+	uoff_t real_offset;
+
+	unsigned char *buffer; /* ring-buffer */
+	size_t buffer_size, optimal_block_size;
+	size_t head, tail; /* first unsent/unused byte */
+
+	unsigned int full:1; /* if head == tail, is buffer empty or full? */
+	unsigned int file:1;
+	unsigned int flush_pending:1;
+	unsigned int socket_cork_set:1;
+	unsigned int no_socket_cork:1;
+	unsigned int no_sendfile:1;
+	unsigned int autoclose_fd:1;
+};
+
+struct ostream *
+o_stream_create_file_common(struct file_ostream *fstream,
+	int fd, size_t max_buffer_size, bool autoclose_fd);
+ssize_t o_stream_file_writev(struct file_ostream *fstream,
+				   const struct const_iovec *iov,
+				   unsigned int iov_size);
+ssize_t o_stream_file_sendv(struct ostream_private *stream,
+				   const struct const_iovec *iov,
+				   unsigned int iov_count);
+void o_stream_file_close(struct iostream_private *stream,
+				bool close_parent);
+
+#endif
--- a/src/lib/ostream-file.c	Sat Apr 30 13:55:52 2016 +0200
+++ b/src/lib/ostream-file.c	Sat Apr 30 14:10:59 2016 +0200
@@ -9,7 +9,7 @@
 #include "sendfile-util.h"
 #include "istream.h"
 #include "istream-private.h"
-#include "ostream-private.h"
+#include "ostream-file-private.h"
 
 #include <unistd.h>
 #include <sys/stat.h>
@@ -28,27 +28,6 @@
 #define MAX_SSIZE_T(size) \
 	((size) < SSIZE_T_MAX ? (size_t)(size) : SSIZE_T_MAX)
 
-struct file_ostream {
-	struct ostream_private ostream;
-
-	int fd;
-	struct io *io;
-	uoff_t buffer_offset;
-	uoff_t real_offset;
-
-	unsigned char *buffer; /* ring-buffer */
-	size_t buffer_size, optimal_block_size;
-	size_t head, tail; /* first unsent/unused byte */
-
-	unsigned int full:1; /* if head == tail, is buffer empty or full? */
-	unsigned int file:1;
-	unsigned int flush_pending:1;
-	unsigned int socket_cork_set:1;
-	unsigned int no_socket_cork:1;
-	unsigned int no_sendfile:1;
-	unsigned int autoclose_fd:1;
-};
-
 static void stream_send_io(struct file_ostream *fstream);
 
 static void stream_closed(struct file_ostream *fstream)
@@ -67,7 +46,7 @@
 	fstream->ostream.ostream.closed = TRUE;
 }
 
-static void o_stream_file_close(struct iostream_private *stream,
+void o_stream_file_close(struct iostream_private *stream,
 				bool close_parent ATTR_UNUSED)
 {
 	struct file_ostream *fstream = (struct file_ostream *)stream;
@@ -169,8 +148,7 @@
 	return 0;
 }
 
-static ssize_t
-o_stream_file_writev(struct file_ostream *fstream,
+ssize_t o_stream_file_writev(struct file_ostream *fstream,
 				   const struct const_iovec *iov,
 				   unsigned int iov_count)
 {
@@ -246,7 +224,7 @@
 		total_size += iov[i].iov_len;
 
 	o_stream_socket_cork(fstream);
-	ret = o_stream_file_writev(fstream, iov, iov_count);
+	ret = fstream->writev(fstream, iov, iov_count);
 	partial = ret != (ssize_t)total_size;
 
 	if (ret < 0) {
@@ -557,7 +535,7 @@
 	return sent;
 }
 
-static ssize_t o_stream_file_sendv(struct ostream_private *stream,
+ssize_t o_stream_file_sendv(struct ostream_private *stream,
 				   const struct const_iovec *iov,
 				   unsigned int iov_count)
 {
@@ -940,12 +918,12 @@
 		fstream->io = io_loop_move_io(&fstream->io);
 }
 
-static struct file_ostream *
-o_stream_create_fd_common(int fd, bool autoclose_fd)
+struct ostream *
+o_stream_create_file_common(struct file_ostream *fstream,
+	int fd, size_t max_buffer_size, bool autoclose_fd)
 {
-	struct file_ostream *fstream;
+	struct ostream *ostream;
 
-	fstream = i_new(struct file_ostream, 1);
 	fstream->fd = fd;
 	fstream->autoclose_fd = autoclose_fd;
 	fstream->optimal_block_size = DEFAULT_OPTIMAL_BLOCK_SIZE;
@@ -963,7 +941,15 @@
 	fstream->ostream.send_istream = o_stream_file_send_istream;
 	fstream->ostream.switch_ioloop = o_stream_file_switch_ioloop;
 
-	return fstream;
+	fstream->writev = o_stream_file_writev;
+
+	fstream->ostream.max_buffer_size = max_buffer_size;
+	ostream = o_stream_create(&fstream->ostream, NULL, fd);
+
+	if (max_buffer_size == 0)
+		fstream->ostream.max_buffer_size = fstream->optimal_block_size;
+
+	return ostream;
 }
 
 static void fstream_init_file(struct file_ostream *fstream)
@@ -993,9 +979,9 @@
 	struct ostream *ostream;
 	off_t offset;
 
-	fstream = o_stream_create_fd_common(fd, autoclose_fd);
-	fstream->ostream.max_buffer_size = max_buffer_size;
-	ostream = o_stream_create(&fstream->ostream, NULL, fd);
+	fstream = i_new(struct file_ostream, 1);
+	ostream = o_stream_create_file_common
+		(fstream, fd, max_buffer_size, autoclose_fd);
 
 	offset = lseek(fd, 0, SEEK_CUR);
 	if (offset >= 0) {
@@ -1010,9 +996,6 @@
 		}
 	}
 
-	if (max_buffer_size == 0)
-		fstream->ostream.max_buffer_size = fstream->optimal_block_size;
-
 	return ostream;
 }
 
@@ -1035,13 +1018,11 @@
 	if (offset == (uoff_t)-1)
 		offset = lseek(fd, 0, SEEK_CUR);
 
-	fstream = o_stream_create_fd_common(fd, autoclose_fd);
+	fstream = i_new(struct file_ostream, 1);
+	ostream = o_stream_create_file_common(fstream, fd, 0, autoclose_fd);
 	fstream_init_file(fstream);
-	fstream->ostream.max_buffer_size = fstream->optimal_block_size;
 	fstream->real_offset = offset;
 	fstream->buffer_offset = offset;
-
-	ostream = o_stream_create(&fstream->ostream, NULL, fd);
 	ostream->offset = offset;
 	return ostream;
 }