/* * Copyright (C) 2020 - Vito Caputo - * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int n = argc; struct pollfd *pfds; assert(argc >= 1); pfds = calloc(n, sizeof(*pfds)); if (!pfds) { fprintf(stderr, "Unable to allocate struct pollfd array: %s\n", strerror(errno)); return EXIT_FAILURE; } for (int i = 0; i < n; i++) { if (i > 0) { const char *path = argv[i]; pfds[i].fd = open(path, O_RDONLY); if (pfds[i].fd == -1) { fprintf(stderr, "Unable to open \"%s\": %s\n", path, strerror(errno)); return EXIT_FAILURE; } } pfds[i].events = POLLIN; } while (poll(pfds, n, -1) > 0) { for (int i = 0; i < n; i++) { char buf[PIPE_BUF]; ssize_t rr, rw; if (pfds[i].revents & POLLHUP) { fprintf(stderr, "fd %i hangup, quitting\n", pfds[i].fd); return EXIT_SUCCESS; } if (!(pfds[i].revents & POLLIN)) continue; rr = read(pfds[i].fd, buf, sizeof(buf)); if (rr < 0) { fprintf(stderr, "Error reading fd %i: %s\n", pfds[i].fd, strerror(errno)); return EXIT_FAILURE; } rw = write(1, buf, rr); if (rw < 0) { fprintf(stderr, "Error writing: %s\n", strerror(errno)); return EXIT_FAILURE; } if (rw != rr) { fprintf(stderr, "Short write\n"); return EXIT_FAILURE; } } } return EXIT_FAILURE; }