15 * Read data from a slow device
17 * return 1 when a complete NULL terminated line has been read
19 * return 0 when a partial line has been read and appended to the
22 * return negative on error
24 static int read_log_line(int infd, char *buf, size_t bufsize, int *offset)
29 ret = read(infd, buf + *offset, bufsize - *offset - 1);
36 pr_err("Read EOF, stopping\n");
39 buf[*offset + ret] = 0;
41 for (i = 0; i < ret; i++) {
42 if (buf[i + *offset] == '\n' ||
43 buf[i + *offset] == '\r') {
45 * Got a complete line when there is a newline
46 * at the end. Remove the newline and possible
47 * other junk, such as '\r'
56 * Fixme! Nothing guarantees that there isn't actually
57 * more data (a part of a new log entry perhaps) after
58 * the newline. So in rare cases (we are prevented
59 * from reading the serial line in very long time) we
60 * might lose data from the stream..
68 static int read_data(int infd, int outfd)
70 struct epoll_event ev;
71 time_t start_time = 0, cur_time;
77 epoll_fd = epoll_create(1);
79 pr_err("Failed to create epoll socket: %m\n");
85 if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, infd, &ev) == -1) {
86 pr_err("epoll_ctl: %m\n");
94 ret = epoll_wait(epoll_fd, &ev, 1, -1);
99 pr_err("epoll: %m\n");
104 start_time = time(NULL);
106 ret = read_log_line(infd, buf, sizeof(buf), &offset);
113 if (strlen(buf) < 5) {
114 pr_debug("discarding truncated log entry\n");
119 cur_time = time(NULL);
121 pr_info("%s\n", buf);
126 len = snprintf(str, sizeof(str),
127 "%ld;%s\n", cur_time - start_time, buf);
129 ret = write(outfd, str, len);
131 pr_err("write: %m\n");
139 int main(int argc, char *argv[])
141 struct plotter_options options;
142 int fd, baud, ret = 0, out_fd = 0;
144 if (read_args(argc, argv, &options))
147 baud = options.baud_rate;
148 fd = open_at_baud(options.device_path, &baud);
152 if (baud != options.baud_rate) {
153 pr_err("Failed to set baudrate to %d, only got %d\n",
154 options.baud_rate, baud);
159 if (options.output_path) {
160 pr_debug("Opening %s for writing the log file\n",
161 options.output_path);
163 out_fd = open(options.output_path,
164 O_CREAT | O_APPEND | O_WRONLY, 0664);
166 pr_err("Failed to open file %s for writing: %m\n",
167 options.output_path);
173 read_data(fd, out_fd);