From 33f01df1c95b43b66e2f0bab2b972dd9e03faeb5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 23 Dec 2003 00:05:15 +0000 Subject: it compiles and works basically git-svn-id: file:///home/lennart/svn/public/ivam2/trunk@9 dbf6933d-3bce-0310-9bcc-ed052ba35b35 --- src/buffio.c | 231 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 162 insertions(+), 69 deletions(-) (limited to 'src/buffio.c') diff --git a/src/buffio.c b/src/buffio.c index 2c3a7fb..25ba5a4 100644 --- a/src/buffio.c +++ b/src/buffio.c @@ -1,12 +1,25 @@ +#include +#include +#include +#include +#include + +#include + +#include + #include "buffio.h" +#include "main.h" #define BUFSIZE 10240 -static void buffio_set_callbacks(struct buffio *b); static void* buffio_read_cb(oop_source *source, int fd, oop_event event, void *user); static void* buffio_write_cb(oop_source *source, int fd, oop_event event, void *user); -struct buffio buffio_new(int fd) { +static void buffio_set_input_callbacks(struct buffio *b); +static void buffio_set_output_callbacks(struct buffio *b); + +struct buffio* buffio_new(int ifd, int ofd) { struct buffio *b; assert(b >= 0); @@ -14,19 +27,21 @@ struct buffio buffio_new(int fd) { assert(b); memset(b, 0, sizeof(struct buffio)); - b->fd = fd; + b->ifd = ifd; + b->ofd = ofd; b->input_buf = malloc(b->input_max_length = BUFSIZE); assert(b->input_buf); - b->input_buf_len = b->input_index = 0; - b->input_watermark = 2; /* Read some more data if 2 or less bytes are in the input buffer */ + b->input_length = b->input_index = 0; + b->input_watermark = b->input_max_length; /* Read some more data if possible */ b->output_buf = malloc(b->output_max_length = BUFSIZE); assert(b->output_buf); b->output_length = b->output_index = 0; b->output_watermark = 1; /* Write some data if 1 or more bytes are in the output buffer */ - buffio_set_callbacks(b); + buffio_set_input_callbacks(b); + buffio_set_output_callbacks(b); return b; } @@ -35,16 +50,18 @@ static void buffio_close_fd(struct buffio *b) { assert(b); if (b->b_read_cb) - event_source->cancel_fd(event_source, b->fd, OOP_READ, buffio_read_cb, b); + event_source->cancel_fd(event_source, b->ifd, OOP_READ); if (b->b_write_cb) - event_source->cancel_fd(event_source, b->fd, OOP_WRITE, buffio_write_cb, b); + event_source->cancel_fd(event_source, b->ofd, OOP_WRITE); - if (b->fd >= 0) - close(b->fd); + if (b->ifd >= 0) + close(b->ifd); + if (b->ofd >= 0 && b->ofd != b->ifd) + close(b->ofd); b->b_read_cb = b->b_write_cb = 0; - b->fd = -1; + b->ifd = b->ofd = -1; } @@ -55,13 +72,69 @@ void buffio_free(struct buffio *b) { free(b); } +#ifdef IODEBUG +static void esc_print(const char*c, const uint8_t *b, size_t l) { + size_t i; + fprintf(stderr, "%s", c); + for (i = 0; i < l; i++, b++) + fputc(*b < 32 ? '.' : *b, stderr); + + fprintf(stderr, "\n"); +}; +#endif + +static void buffio_normalize(struct buffio *b) { + assert(b); + + assert(b->input_index < b->input_max_length); + assert(b->input_length <= b->input_max_length); + + if (!b->input_length) /* This will optimize throughput a bit */ + b->input_index = 0; + + if (!b->output_length) /* This will optimize throughput a bit */ + b->output_index = 0; +} + +static void buffio_set_input_callbacks(struct buffio *b) { + assert(b && b->ifd >= 0 && event_source); + + if (b->input_length <= b->input_watermark) { + if (!b->b_read_cb) { /* Enable the callback */ + event_source->on_fd(event_source, b->ifd, OOP_READ, buffio_read_cb, b); + b->b_read_cb = 1; + } + } else { + if (b->b_read_cb) { /* Disable the callback */ + event_source->cancel_fd(event_source, b->ifd, OOP_READ); + b->b_read_cb = 0; + } + } +} + +static void buffio_set_output_callbacks(struct buffio *b) { + assert(b && b->ofd >= 0 && event_source); + + if (b->output_length >= b->output_watermark) { + if (!b->b_write_cb) { /* Enable the callback */ + event_source->on_fd(event_source, b->ofd, OOP_WRITE, buffio_write_cb, b); + b->b_write_cb = 1; + } + } else { + if (b->b_write_cb) { /* Disable the callback */ + event_source->cancel_fd(event_source, b->ofd, OOP_WRITE); + b->b_write_cb = 0; + } + } +} + static void* buffio_read_cb(oop_source *source, int fd, oop_event event, void *user) { struct buffio *b = user; - assert(source && b && b->fd == fd && event == OOP_READ); + assert(source && b && b->ifd == fd && event == OOP_READ); if (b->input_length < b->input_max_length) { ssize_t s; - size_t m, l; + size_t m, i; i = (b->input_index + b->input_length) % b->input_max_length; @@ -74,6 +147,10 @@ static void* buffio_read_cb(oop_source *source, int fd, oop_event event, void *u return OOP_HALT; } +#ifdef IODEBUG + esc_print("INPUT: ", b->input_buf+i, s); +#endif + if (!s) { buffio_close_fd(b); if (b->eof_cb) @@ -96,9 +173,9 @@ static void* buffio_read_cb(oop_source *source, int fd, oop_event event, void *u static void* buffio_write_cb(oop_source *source, int fd, oop_event event, void *user) { struct buffio *b = user; - assert(source && b && b->fd == fd && event == OOP_WRITE); + assert(source && b && b->ofd == fd && event == OOP_WRITE); - if (b->output_buf > 0) { + if (b->output_length > 0) { ssize_t s; size_t m; @@ -111,6 +188,10 @@ static void* buffio_write_cb(oop_source *source, int fd, oop_event event, void * return OOP_HALT; } +#ifdef IODEBUG + esc_print("OUTPUT: ", b->output_buf+b->output_index, s); +#endif + if (!s) { buffio_close_fd(b); if (b->eof_cb) @@ -120,7 +201,7 @@ static void* buffio_write_cb(oop_source *source, int fd, oop_event event, void * assert(s <= m); b->output_index = (b->output_index + s) % b->output_max_length; - b->ouput_length -= s; + b->output_length -= s; } buffio_normalize(b); @@ -133,51 +214,24 @@ static void* buffio_write_cb(oop_source *source, int fd, oop_event event, void * } -static void buffio_set_input_callbacks(struct buffio *b) { - assert(b && b->fd >= 0 && event_source); - - if (b->input_length <= b->input_watermark) { - if (!b->b_read_cb) { /* Enable the callback */ - event_source->on_fd(event_source, b->fd, OOP_READ, buffio_read_cb, b); - b->b_read_cb = 1; - } - } else { - if (b->read_cb) { /* Disable the callback */ - event_source->cancel_fd(event_source, b->fd, OOP_READ, buffio_read_cb, b); - b->read_cb = 0; - } - } -} - -static void buffio_set_output_callbacks(struct buffio *b) { - assert(b && b->fd >= 0 && event_source); - - if (b->output_length >= b->output_watermark) { - if (!b->b_write_cb) { /* Enable the callback */ - event_source->on_fd(event_source, b->fd, OOP_WRITE, buffio_write_cb, b); - b->b_write_cb = 1; - } - } else { - if (b->b_write_cb) { /* Disable the callback */ - event_source->cancel_fd(event_source, b->fd, OOP_WRITE, buffio_write_cb, b); - b->b_write_cb = 0; - } - } -} int buffio_write(struct buffio *b, const uint8_t *d, size_t l) { - assert(b && s && l); + assert(b && d && l); - if (l < b->output_max_length - b->output_length) { + if (l > b->output_max_length - b->output_length) { daemon_log(LOG_ERR, "buffio_write() with too much data called"); return -1; } + while (l > 0) { + size_t m, i; + + i = (b->output_index + b->output_length) % b->output_max_length; - while (l >= 0) { - i = (b->ouput_index + b->ouput_length) % b->ouput_max_length; + m = l; + if (m > b->output_max_length-b->output_length) + m = b->output_max_length-b->output_length; - m = b->ouput_max_length-b->output_length; if (m > b->output_max_length-i) m = b->output_max_length-i; @@ -188,7 +242,7 @@ int buffio_write(struct buffio *b, const uint8_t *d, size_t l) { } buffio_set_output_callbacks(b); - buffio_normalize(); + buffio_normalize(b); return 0; } @@ -200,7 +254,7 @@ int buffio_print(struct buffio *b, const char *s) { int buffio_command(struct buffio *b, const char *c) { assert(b && c); - + buffio_flush_input(b); return buffio_print(b, c); } @@ -209,29 +263,19 @@ void buffio_flush_input(struct buffio *b) { assert(b); b->input_length = b->input_index = 0; - buffio_set_callbacks(b); + buffio_set_input_callbacks(b); } -static void buffio_normalize(struct buffio *b) { - assert(b); - - assert(b->input_index < b->input_max_length); - assert(b->input_length <= b->input_max_length); - - if (!b->input_length) /* This will optimize throughput a bit */ - b->input_index = 0; -} - int buffio_find_input(struct buffio *b, const char *c) { - size_t l, cl, j; + size_t l, cl, i; assert(b && c && *c); - + cl = strlen(c); for (i = b->input_index, l = b->input_length; l >= cl; i = (i+1) % b->input_max_length, l--) { - char *p; - size_t i; + const char *p; + size_t j; for (j = i, p = c; *p && *p == b->input_buf[j]; p++, j = (j+1) % b->input_max_length); @@ -240,6 +284,7 @@ int buffio_find_input(struct buffio *b, const char *c) { b->input_length = l-cl; buffio_normalize(b); + buffio_set_input_callbacks(b); return 1; } } @@ -248,3 +293,51 @@ int buffio_find_input(struct buffio *b, const char *c) { } +char *buffio_read_line(struct buffio *b, char *c, size_t l) { + size_t i; + assert(b && c && l); + + /* Look for a \n */ + for (i = 0; i < b->input_length && i < l-1; i++) { + if (b->input_buf[(b->input_index+i) % b->input_max_length] == '\n') { + size_t j; + + /* Once again, now copy */ + for (j = 0;; j++) { + c[j] = b->input_buf[(b->input_index+j) % b->input_max_length]; + + /* Finished? */ + if (c[j] == '\n') { + c[j+1] = 0; + + b->input_index = (b->input_index+j+1) % b->input_max_length; + b->input_length -= j+1; + buffio_set_input_callbacks(b); + buffio_normalize(b); + return c; + } + } + } + } + + return NULL; +} + +void buffio_dump(struct buffio *b) { + assert(b); + size_t i; + + fprintf(stderr, "%p INPUT_BUFFER: [", b); + for (i = 0; i < b->input_length; i++) { + char c = b->input_buf[(i + b->input_index) % b->input_max_length]; + fputc(c < 32 ? '.' : c, stderr); + } + fprintf(stderr, "]\n"); + + fprintf(stderr, "%p OUTPUT_BUFFER: [", b); + for (i = 0; i < b->output_length; i++) { + char c = b->output_buf[(i + b->output_index) % b->output_max_length]; + fputc(c < 32 ? '.' : c, stderr); + } + fprintf(stderr, "]\n"); +} -- cgit