#include #include #include #include #include #include #include #include static void usage(void) { fprintf(stderr, "usage: api-exabgp [ -t timeout ] fifo\n"); exit(1); } static int fifo_open(const char *name) { int fd; fd = open(name, O_RDONLY | O_NONBLOCK); if (fd == -1) err(1, "open %s", name); return fd; } int main(int argc, char **argv) { struct pollfd pfd[2]; char buf[512]; const char *errstr, *fifo; int fd, ch, timeout = 0; time_t end, now; ssize_t n; while ((ch = getopt(argc, argv, "t:")) != -1) { switch (ch) { case 't': timeout = strtonum(optarg, 0, 120, &errstr); if (errstr != NULL) errx(1, "timeout is %s: %s", errstr, optarg); break; default: usage(); } } argc -= optind; argv += optind; if (argv[0] == NULL) usage(); fifo = argv[0]; pfd[0].fd = 0; pfd[0].events = POLLIN; pfd[1].fd = fd = fifo_open(fifo); pfd[1].events = POLLIN; end = time(NULL) + timeout; while (1) { now = time(NULL); if (timeout != 0 && end < now) { if (write(1, "shutdown\n", 9) != 9) errx(1, "bad write to stdout"); } if (poll(pfd, 2, 1000) == -1) err(1, "poll"); if (pfd[0].revents & POLLIN) { n = read(0, buf, sizeof(buf)); if (n == -1) err(1, "read stdin"); if (n > 2 && strncmp(buf + n - 2, "\n\n", 2) == 0) n--; if (write(2, buf, n) != n) errx(1, "bad write to stderr"); if (n > 8 && strncmp(buf, "shutdown", 8) == 0) errx(0, "exabgp shutdown"); } if (pfd[1].revents & POLLIN) { n = read(fd, buf, sizeof(buf)); if (n == -1) err(1, "read fifo"); if (n > 0) { if (write(1, buf, n) != n) errx(1, "bad write to stdout"); } } if (pfd[1].revents & POLLHUP) { /* re-open fifo */ close(fd); pfd[1].fd = fd = fifo_open(fifo); } } }