X-Git-Url: http://git.itanic.dy.fi/?p=log-plotter;a=blobdiff_plain;f=main.c;h=e116477dd5d77ba2d731dde0e404ea1f888ff435;hp=6189b7be34b7048123c441f8ea1c33e96c258741;hb=3d8040b9815e450cec28cc26aa1d158fb02500ae;hpb=564f4d9d9c2cc16e53265c40ad63712cf14f534d diff --git a/main.c b/main.c index 6189b7b..e116477 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -9,12 +10,67 @@ #include "baud.h" #include "debug.h" -int read_data(int infd, int outfd) +/** + * Read data from a slow device + * + * return 1 when a complete NULL terminated line has been read + * + * return 0 when a partial line has been read and appended to the + * buffer at @offset + * + * return negative on error + */ +static int read_log_line(int infd, char *buf, size_t bufsize, int *offset) +{ + int ret; + int i; + + ret = read(infd, buf + *offset, bufsize - *offset - 1); + if (read < 0) { + pr_err("read: %m\n"); + return -1; + } + + if (ret == 0) { + pr_err("Read EOF, stopping\n"); + return -1; + } + buf[*offset + ret] = 0; + + for (i = 0; i < ret; i++) { + if (buf[i + *offset] == '\n' || + buf[i + *offset] == '\r') { + /* + * Got a complete line when there is a newline + * at the end. Remove the newline and possible + * other junk, such as '\r' + */ + buf[i + *offset] = 0; + *offset = 0; + + return 1; + } + + /* + * Fixme! Nothing guarantees that there isn't actually + * more data (a part of a new log entry perhaps) after + * the newline. So in rare cases (we are prevented + * from reading the serial line in very long time) we + * might lose data from the stream.. + */ + } + + *offset += ret; + return 0; +} + +static int read_data(int infd, int outfd) { struct epoll_event ev; int epoll_fd; int ret; char buf[256]; + int offset; epoll_fd = epoll_create(1); if (epoll_fd < 0) { @@ -39,22 +95,28 @@ int read_data(int infd, int outfd) return -1; } - ret = read(infd, buf, sizeof(buf)); - if (read < 0) { - pr_err("read: %m\n"); - break; - } + ret = read_log_line(infd, buf, sizeof(buf), &offset); + if (ret < 0) + return ret; - if (ret == 0) { - pr_err("Read EOF, stopping\n"); - break; - } + if (ret == 0) + continue; - ret = write(outfd, buf, ret); - if (read < 0) { - pr_err("write: %m\n"); - break; + if (outfd) { + char newline = '\n'; + ret = write(outfd, buf, strlen(buf)); + if (read < 0) { + pr_err("write: %m\n"); + break; + } + ret = write(outfd, &newline, 1); + if (read < 0) { + pr_err("write: %m\n"); + break; + } } + + pr_info("%s\n", buf); } return 0; @@ -63,7 +125,7 @@ int read_data(int infd, int outfd) int main(int argc, char *argv[]) { struct plotter_options options; - int fd, baud, ret = 0, out_fd = STDOUT_FILENO; + int fd, baud, ret = 0, out_fd = 0; if (read_args(argc, argv, &options)) return 1;