From: Timo Sirainen Date: Sat, 17 Jan 2015 02:14:58 +0000 (+0200) Subject: lib: iostream-rawlog now writes to ostreams instead of directly to fds. X-Git-Tag: 2.2.16.rc1~140 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2;p=thirdparty%2Fdovecot%2Fcore.git lib: iostream-rawlog now writes to ostreams instead of directly to fds. --- diff --git a/src/lib/iostream-rawlog-private.h b/src/lib/iostream-rawlog-private.h index 12ec9581e7..9da3736907 100644 --- a/src/lib/iostream-rawlog-private.h +++ b/src/lib/iostream-rawlog-private.h @@ -13,8 +13,7 @@ struct rawlog_iostream { struct iostream_private *iostream; enum iostream_rawlog_flags flags; - char *rawlog_path; - int rawlog_fd; + struct ostream *rawlog_output; buffer_t *buffer; bool input; diff --git a/src/lib/iostream-rawlog.c b/src/lib/iostream-rawlog.c index 7b8d8e5916..435da5dd92 100644 --- a/src/lib/iostream-rawlog.c +++ b/src/lib/iostream-rawlog.c @@ -21,29 +21,14 @@ #define RAWLOG_MAX_LINE_LEN 8192 -static int -rawlog_write(struct rawlog_iostream *rstream, const void *data, size_t size) -{ - if (rstream->rawlog_fd == -1) - return -1; - - if (write_full(rstream->rawlog_fd, data, size) < 0) { - i_error("rawlog_istream.write(%s) failed: %m", - rstream->rawlog_path); - iostream_rawlog_close(rstream); - return -1; - } - return 0; -} - -static int +static void rawlog_write_timestamp(struct rawlog_iostream *rstream, bool line_ends) { unsigned char data[MAX_INT_STRLEN + 6 + 1 + 3]; buffer_t buf; if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_TIMESTAMP) == 0) - return 0; + return; buffer_create_from_data(&buf, data, sizeof(data)); str_printfa(&buf, "%lu.%06u ", @@ -54,7 +39,7 @@ rawlog_write_timestamp(struct rawlog_iostream *rstream, bool line_ends) str_append_c(&buf, line_ends ? ':' : '>'); str_append_c(&buf, ' '); } - return rawlog_write(rstream, buf.data, buf.used); + o_stream_nsend(rstream->rawlog_output, buf.data, buf.used); } void iostream_rawlog_init(struct rawlog_iostream *rstream, @@ -66,28 +51,61 @@ void iostream_rawlog_init(struct rawlog_iostream *rstream, rstream->buffer = buffer_create_dynamic(default_pool, 1024); } +static void +iostream_rawlog_write_buffered(struct rawlog_iostream *rstream, + const unsigned char *data, size_t size) +{ + const unsigned char *p; + size_t pos; + bool line_ends; + + while (size > 0) { + p = memchr(data, '\n', size); + if (p != NULL) { + line_ends = TRUE; + pos = p-data + 1; + } else if (rstream->buffer->used + size < RAWLOG_MAX_LINE_LEN) { + buffer_append(rstream->buffer, data, size); + break; + } else { + line_ends = FALSE; + pos = size; + } + + rawlog_write_timestamp(rstream, line_ends); + if (rstream->buffer->used > 0) { + o_stream_nsend(rstream->rawlog_output, + rstream->buffer->data, + rstream->buffer->used); + buffer_set_used_size(rstream->buffer, 0); + } + o_stream_nsend(rstream->rawlog_output, data, pos); + + data += pos; + size -= pos; + } +} + static void iostream_rawlog_write_unbuffered(struct rawlog_iostream *rstream, const unsigned char *data, size_t size) { size_t i, start; - if (!rstream->line_continued) { - if (rawlog_write_timestamp(rstream, TRUE) < 0) - return; - } + if (!rstream->line_continued) + rawlog_write_timestamp(rstream, TRUE); for (start = 0, i = 1; i < size; i++) { if (data[i-1] == '\n') { - if (rawlog_write(rstream, data + start, i - start) < 0 || - rawlog_write_timestamp(rstream, TRUE) < 0) - return; + o_stream_nsend(rstream->rawlog_output, + data + start, i - start); + rawlog_write_timestamp(rstream, TRUE); start = i; } } if (start != size) { - if (rawlog_write(rstream, data + start, size - start) < 0) - return; + o_stream_nsend(rstream->rawlog_output, + data + start, size - start); } rstream->line_continued = data[size-1] != '\n'; } @@ -95,59 +113,30 @@ iostream_rawlog_write_unbuffered(struct rawlog_iostream *rstream, void iostream_rawlog_write(struct rawlog_iostream *rstream, const unsigned char *data, size_t size) { - const unsigned char *p; - size_t pos; - bool line_ends; - - if (size == 0) + if (size == 0 || rstream->rawlog_output == NULL) return; io_loop_time_refresh(); - if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_BUFFERED) == 0) { - iostream_rawlog_write_unbuffered(rstream, data, size); - return; - } - while (rstream->rawlog_fd != -1 && size > 0) { - p = memchr(data, '\n', size); - if (p != NULL) { - line_ends = TRUE; - pos = p-data + 1; - } else if (rstream->buffer->used + size < RAWLOG_MAX_LINE_LEN) { - buffer_append(rstream->buffer, data, size); - return; - } else { - line_ends = FALSE; - pos = size; - } - - if (rawlog_write_timestamp(rstream, line_ends) < 0) - break; - if (rstream->buffer->used > 0) { - if (rawlog_write(rstream, rstream->buffer->data, - rstream->buffer->used) < 0) - break; - buffer_set_used_size(rstream->buffer, 0); - } - if (rawlog_write(rstream, data, pos) < 0) - break; + o_stream_cork(rstream->rawlog_output); + if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_BUFFERED) != 0) + iostream_rawlog_write_buffered(rstream, data, size); + else + iostream_rawlog_write_unbuffered(rstream, data, size); + o_stream_uncork(rstream->rawlog_output); - data += pos; - size -= pos; + if (o_stream_nfinish(rstream->rawlog_output) < 0) { + i_error("write(%s) failed: %s", + o_stream_get_name(rstream->rawlog_output), + o_stream_get_error(rstream->rawlog_output)); + iostream_rawlog_close(rstream); } } void iostream_rawlog_close(struct rawlog_iostream *rstream) { - if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_AUTOCLOSE) != 0 && - rstream->rawlog_fd != -1) { - if (close(rstream->rawlog_fd) < 0) { - i_error("rawlog_istream.close(%s) failed: %m", - rstream->rawlog_path); - } - } - rstream->rawlog_fd = -1; - i_free_and_null(rstream->rawlog_path); + if (rstream->rawlog_output != NULL) + o_stream_unref(&rstream->rawlog_output); if (rstream->buffer != NULL) buffer_free(&rstream->buffer); } @@ -285,3 +274,24 @@ int iostream_rawlog_create_path(const char *path, struct istream **input, iostream_rawlog_create_fd(fd, path, input, output); return 0; } + +void iostream_rawlog_create_from_stream(struct ostream *rawlog_output, + struct istream **input, + struct ostream **output) +{ + const enum iostream_rawlog_flags rawlog_flags = + IOSTREAM_RAWLOG_FLAG_BUFFERED | + IOSTREAM_RAWLOG_FLAG_TIMESTAMP; + struct istream *old_input; + struct ostream *old_output; + + old_input = *input; + old_output = *output; + o_stream_ref(rawlog_output); + *input = i_stream_create_rawlog_from_stream(old_input, rawlog_output, + rawlog_flags); + *output = o_stream_create_rawlog_from_stream(old_output, rawlog_output, + rawlog_flags); + i_stream_unref(&old_input); + o_stream_unref(&old_output); +} diff --git a/src/lib/iostream-rawlog.h b/src/lib/iostream-rawlog.h index dde2c86545..26ff592665 100644 --- a/src/lib/iostream-rawlog.h +++ b/src/lib/iostream-rawlog.h @@ -13,5 +13,10 @@ iostream_rawlog_create_prefix(const char *prefix, struct istream **input, int ATTR_NOWARN_UNUSED_RESULT iostream_rawlog_create_path(const char *path, struct istream **input, struct ostream **output); +/* Create rawlog that appends to the given rawlog_output. + Both input and output are written to the same stream. */ +void iostream_rawlog_create_from_stream(struct ostream *rawlog_output, + struct istream **input, + struct ostream **output); #endif diff --git a/src/lib/istream-rawlog.c b/src/lib/istream-rawlog.c index aedf8a33b1..1ec2566e05 100644 --- a/src/lib/istream-rawlog.c +++ b/src/lib/istream-rawlog.c @@ -1,6 +1,7 @@ /* Copyright (c) 2011-2015 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "ostream.h" #include "iostream-rawlog-private.h" #include "istream-private.h" #include "istream-rawlog.h" @@ -76,17 +77,30 @@ struct istream * i_stream_create_rawlog(struct istream *input, const char *rawlog_path, int rawlog_fd, enum iostream_rawlog_flags flags) { - struct rawlog_istream *rstream; + struct ostream *rawlog_output; + bool autoclose_fd = (flags & IOSTREAM_RAWLOG_FLAG_AUTOCLOSE) != 0; i_assert(rawlog_path != NULL); i_assert(rawlog_fd != -1); + rawlog_output = o_stream_create_fd(rawlog_fd, 0, autoclose_fd); + o_stream_set_name(rawlog_output, + t_strdup_printf("rawlog(%s)", rawlog_path)); + return i_stream_create_rawlog_from_stream(input, rawlog_output, flags); +} + +struct istream * +i_stream_create_rawlog_from_stream(struct istream *input, + struct ostream *rawlog_output, + enum iostream_rawlog_flags flags) +{ + struct rawlog_istream *rstream; + rstream = i_new(struct rawlog_istream, 1); rstream->istream.max_buffer_size = input->real_stream->max_buffer_size; rstream->istream.stream_size_passthrough = TRUE; - rstream->riostream.rawlog_path = i_strdup(rawlog_path); - rstream->riostream.rawlog_fd = rawlog_fd; + rstream->riostream.rawlog_output = rawlog_output; iostream_rawlog_init(&rstream->riostream, flags, TRUE); rstream->istream.read = i_stream_rawlog_read; diff --git a/src/lib/istream-rawlog.h b/src/lib/istream-rawlog.h index 08d9a3597e..7fc9ac194a 100644 --- a/src/lib/istream-rawlog.h +++ b/src/lib/istream-rawlog.h @@ -4,5 +4,9 @@ struct istream * i_stream_create_rawlog(struct istream *input, const char *rawlog_path, int rawlog_fd, enum iostream_rawlog_flags flags); +struct istream * +i_stream_create_rawlog_from_stream(struct istream *input, + struct ostream *rawlog_output, + enum iostream_rawlog_flags flags); #endif diff --git a/src/lib/ostream-rawlog.c b/src/lib/ostream-rawlog.c index ea273c3a25..7df2ba9f56 100644 --- a/src/lib/ostream-rawlog.c +++ b/src/lib/ostream-rawlog.c @@ -55,18 +55,30 @@ struct ostream * o_stream_create_rawlog(struct ostream *output, const char *rawlog_path, int rawlog_fd, enum iostream_rawlog_flags flags) { - struct rawlog_ostream *rstream; + struct ostream *rawlog_output; + bool autoclose_fd = (flags & IOSTREAM_RAWLOG_FLAG_AUTOCLOSE) != 0; i_assert(rawlog_path != NULL); i_assert(rawlog_fd != -1); + rawlog_output = o_stream_create_fd(rawlog_fd, 0, autoclose_fd); + o_stream_set_name(rawlog_output, + t_strdup_printf("rawlog(%s)", rawlog_path)); + return o_stream_create_rawlog_from_stream(output, rawlog_output, flags); +} + +struct ostream * +o_stream_create_rawlog_from_stream(struct ostream *output, + struct ostream *rawlog_output, + enum iostream_rawlog_flags flags) +{ + struct rawlog_ostream *rstream; + rstream = i_new(struct rawlog_ostream, 1); rstream->ostream.sendv = o_stream_rawlog_sendv; rstream->ostream.iostream.close = o_stream_rawlog_close; - rstream->riostream.rawlog_path = i_strdup(rawlog_path); - rstream->riostream.rawlog_fd = rawlog_fd; + rstream->riostream.rawlog_output = rawlog_output; iostream_rawlog_init(&rstream->riostream, flags, FALSE); - return o_stream_create(&rstream->ostream, output, -1); } diff --git a/src/lib/ostream-rawlog.h b/src/lib/ostream-rawlog.h index a81e43317b..59899532ae 100644 --- a/src/lib/ostream-rawlog.h +++ b/src/lib/ostream-rawlog.h @@ -4,5 +4,9 @@ struct ostream * o_stream_create_rawlog(struct ostream *output, const char *rawlog_path, int rawlog_fd, enum iostream_rawlog_flags flags); +struct ostream * +o_stream_create_rawlog_from_stream(struct ostream *output, + struct ostream *rawlog_output, + enum iostream_rawlog_flags flags); #endif