-
- Fifo *last = cfg->fifos;
- cfg->fifos = NULL;
- for (Fifo *f = last; f; ) {
- Fifo *next = f->next;
- f->next = cfg->fifos;
- cfg->fifos = f;
- f = next;
- }
-}
-
-void
-fifo_read_error(Fifo *f, char *buf)
-{
- char *b;
- int i;
-
- b = buf + f->pos;
- /* Copy as much of the error message as possible.
- * EXCLUDING the reminating \0. */
- for (i = 0; i < errlen && i < f->width; i++)
- b[i] = errmsg[i];
- /* Any remaining slots: */
- for (; i < f->width; i++)
- b[i] = '_';
-}
-
-void
-fifo_read_one(Fifo *f, char *buf, Config *cfg)
-{
- ssize_t current;
- ssize_t total;
- char *b;
- char c;
-
- current = 0;
- total = 0;
- c = '\0';
- b = buf + f->pos;
- 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));
- fifo_read_error(f, buf);
- } else {
- while (total++ < f->width)
- *b++ = ' ';
- }
- /* TODO Record timestamp read */
- close(f->fd);
- f->fd = -1;
-}
-
-void
-fifo_read_all(Config *cfg, char *buf)
-{
- fd_set fds;
- int maxfd = -1;
- int ready;
- struct stat st;
-
- FD_ZERO(&fds);
- for (Fifo *f = cfg->fifos; f; f = f->next) {
- /* TODO: Create the FIFO if it doesn't already exist. */
- if (lstat(f->name, &st) < 0) {
- error("Cannot stat \"%s\". Error: %s\n", f->name, strerror(errno));
- fifo_read_error(f, buf);
- continue;
- }
- if (!(st.st_mode & S_IFIFO)) {
- error("\"%s\" is not a FIFO\n", f->name);
- fifo_read_error(f, buf);
- continue;
- }
- debug("opening: %s\n", f->name);
- if (f->fd < 0)
- f->fd = open(f->name, O_RDONLY | O_NONBLOCK);
- if (f->fd == -1) {
- /* TODO: Consider backing off retries for failed fifos. */
- error("Failed to open \"%s\"\n", f->name);
- fifo_read_error(f, buf);
- continue;
- }
- if (f->fd > maxfd)
- maxfd = f->fd;
- FD_SET(f->fd, &fds);
- }
- debug("selecting...\n");
- ready = select(maxfd + 1, &fds, NULL, NULL, NULL);
- debug("ready: %d\n", ready);
- assert(ready != 0);
- if (ready < 0)
- fatal("%s", strerror(errno));
- for (Fifo *f = cfg->fifos; f; f = f->next) {
- if (FD_ISSET(f->fd, &fds)) {
- debug("reading: %s\n", f->name);
- fifo_read_one(f, buf, cfg);
- }
- }
-}
-
-void
-snooze(struct timespec *t, Config *cfg)
-{
- struct timespec remainder;
- int result;
-
- result = nanosleep(t, &remainder);
-
- if (result < 0) {
- if (errno == EINTR) {
- info(
- "nanosleep interrupted. Remainder: "
- "{ tv_sec = %ld, tv_nsec = %ld }",
- remainder.tv_sec, remainder.tv_nsec);
- /* No big deal if we occasionally sleep less,
- * so not attempting to correct after an interruption.
- */
- } else {
- fatal("nanosleep: %s\n", strerror(errno));
- }
- }