# HG changeset patch # User Stephan Bosch # Date 1462018259 -7200 # Node ID d2d89eae78289832464e4c471767972de3b98b22 # Parent decbc9f93ddf872cffa92632d7a7d439b70871be lib: ostream-file: Allow creating derived file output streams. diff -r decbc9f93ddf -r d2d89eae7828 src/lib/Makefile.am --- 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 \ diff -r decbc9f93ddf -r d2d89eae7828 src/lib/ostream-file-private.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 diff -r decbc9f93ddf -r d2d89eae7828 src/lib/ostream-file.c --- 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 #include @@ -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; }