]> git.itanic.dy.fi Git - log-plotter/blob - data.c
ef11dfa0550f6dbe926a5cf3dd960e62604517b2
[log-plotter] / data.c
1 #include <unistd.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <time.h>
5 #include <sys/epoll.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8
9 #include "debug.h"
10
11 /**
12  * Read data from a slow device
13  *
14  * return 1 when a complete NULL terminated line has been read
15  *
16  * return 0 when a partial line has been read and appended to the
17  *               buffer at @offset
18  *
19  * return negative on error
20  */
21 static int read_log_line(int infd, char *buf, size_t bufsize, int *offset)
22 {
23         int ret;
24         int i;
25
26         ret = read(infd, buf + *offset, bufsize - *offset - 1);
27         if (ret < 0) {
28                 pr_err("read: %m\n");
29                 return -1;
30         }
31
32         if (ret == 0) {
33                 pr_err("Read EOF, stopping\n");
34                 return -1;
35         }
36         buf[*offset + ret] = 0;
37
38         for (i = 0; i < ret; i++) {
39                 if (buf[i + *offset] == '\n' ||
40                     buf[i + *offset] == '\r') {
41                         /*
42                          * Got a complete line when there is a newline
43                          * at the end. Remove the newline and possible
44                          * other junk, such as '\r'
45                          */
46                         buf[i + *offset] = 0;
47                         *offset = 0;
48
49                         return 1;
50                 }
51
52                 /*
53                  * Fixme! Nothing guarantees that there isn't actually
54                  * more data (a part of a new log entry perhaps) after
55                  * the newline. So in rare cases (we are prevented
56                  * from reading the serial line in very long time) we
57                  * might lose data from the stream..
58                  */
59         }
60
61         *offset += ret;
62         return 0;
63 }
64
65 int read_data(int infd, int outfd)
66 {
67         struct epoll_event ev;
68         time_t start_time = 0, cur_time;
69         int epoll_fd;
70         int ret;
71         char buf[256];
72         int offset = 0;
73
74         epoll_fd = epoll_create(1);
75         if (epoll_fd < 0) {
76                 pr_err("Failed to create epoll socket: %m\n");
77                 return -1;
78         }
79
80         ev.events = EPOLLIN;
81         ev.data.fd = infd;
82         if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, infd, &ev) == -1) {
83                 pr_err("epoll_ctl: %m\n");
84                 return 1;
85         }
86
87         while (1) {
88                 char str[320];
89                 int len;
90
91                 ret = epoll_wait(epoll_fd, &ev, 1, -1);
92                 if (ret == 0)
93                         continue;
94
95                 if (ret < 0) {
96                         pr_err("epoll: %m\n");
97                         return -1;
98                 }
99
100                 ret = read_log_line(infd, buf, sizeof(buf), &offset);
101                 if (ret < 0)
102                         return ret;
103
104                 if (ret == 0)
105                         continue;
106
107                 if (strlen(buf) < 5) {
108                         pr_debug("discarding truncated log entry\n");
109                         offset = 0;
110                         continue;
111                 }
112
113                 if (!start_time)
114                         start_time = time(NULL);
115
116                 cur_time = time(NULL);
117
118                 pr_info("%s\n", buf);
119
120                 if (!outfd)
121                         continue;
122
123                 len = snprintf(str, sizeof(str),
124                         "%ld;%s\n", cur_time - start_time, buf);
125
126                 ret = write(outfd, str, len);
127                 if (ret < 0) {
128                         pr_err("write: %m\n");
129                         break;
130                 }
131         }
132
133         return 0;
134 }
135