- current = 0;
- total = 0;
- c = '\0';
- b = buf + f->pos;
- memset(b, ' ', f->width);
- while ((current = read(f->fd, &c, 1)) && c != '\n' && c != '\0' && total++ < f->width)
- *b++ = c;
- if (current == -1)
- error("Failed to read: \"%s\". Error: %s\n", f->name, strerror(errno));
- /* TODO Record timestamp read */
- close(f->fd);
- f->fd = -1;
+enum read_status
+slot_read_one(Slot *s, struct timespec t, char *buf)
+{
+ char c; /* Character read. */
+ int r; /* Remaining unused slots in buffer range. */
+
+ for (;;) {
+ switch (read(s->in_fd, &c, 1)) {
+ case -1:
+ khlib_error(
+ "Failed to read: \"%s\". errno: %d, msg: %s\n",
+ s->in_fifo,
+ errno,
+ strerror(errno)
+ );
+ switch (errno) {
+ case EINTR:
+ case EAGAIN:
+ return RETRY;
+ default:
+ return FAILURE;
+ }
+ case 0:
+ khlib_debug("%s: End of FILE\n", s->in_fifo);
+ s->out_pos_cur = s->out_pos_lo;
+ return END_OF_FILE;
+ case 1:
+ /* TODO: Consider making msg term char a CLI option */
+ if (c == '\n' || c == '\0') {
+ r = s->out_pos_hi - s->out_pos_cur;
+ if (r > 0)
+ memset(buf + s->out_pos_cur, ' ', r);
+ s->out_pos_cur = s->out_pos_lo;
+ s->in_last_read = t;
+ return END_OF_MESSAGE;
+ } else {
+ if (s->out_pos_cur <= s->out_pos_hi)
+ buf[s->out_pos_cur++] = c;
+ /* Drop beyond available range. */
+ /*
+ * TODO Define max after which we stop reading.
+ * To ensure that a rogue large message
+ * doesn't trap us here.
+ */
+ }
+ break;
+ default:
+ assert(0);
+ }
+ }