]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: iostream-rawlog now writes to ostreams instead of directly to fds.
authorTimo Sirainen <tss@iki.fi>
Sat, 17 Jan 2015 02:14:58 +0000 (04:14 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 17 Jan 2015 02:14:58 +0000 (04:14 +0200)
src/lib/iostream-rawlog-private.h
src/lib/iostream-rawlog.c
src/lib/iostream-rawlog.h
src/lib/istream-rawlog.c
src/lib/istream-rawlog.h
src/lib/ostream-rawlog.c
src/lib/ostream-rawlog.h

index 12ec9581e71a24c60d2d31a5a8a4c34f3240fbbc..9da3736907874796f434d79d2aeb693474bea129 100644 (file)
@@ -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;
index 7b8d8e59165fe14feee7c4e64518bd66560fc7ff..435da5dd92034383ed33419361f2eb19ec0f65c6 100644 (file)
 
 #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);
+}
index dde2c865458687463b781ed15e6c090eddfadb3c..26ff592665afede7ac2ea61a625dffd2656ebb04 100644 (file)
@@ -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
index aedf8a33b12ee5f71c4c44ea0c47301c4ca9a7a9..1ec2566e055ed77b7fa66ba441355094bfa34794 100644 (file)
@@ -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;
index 08d9a3597ee06aae03a8fcf0227eb13f4a21c91d..7fc9ac194a637ae4a6fa1dac4e02236625813c60 100644 (file)
@@ -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
index ea273c3a2520712f1f63aed2746acc19feb22912..7df2ba9f5685da8e3e4b24b790c69bab8f5b5762 100644 (file)
@@ -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);
 }
index a81e43317b32aeeb82c419a4e88800a49fe69fc4..59899532aecef2686840b1ce91724ef7d3537a6d 100644 (file)
@@ -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