#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include int main(int argc, const char *argv[]) { int pipefds[2]; int file_fd; int sock; int listen_fd; struct sockaddr_in in_addr; int res; int to_read; if (argc != 3) { fprintf(stderr, "usage: %s to_read\n", argv[0]); exit(1); } to_read = atoi(argv[2]); if (pipe(pipefds) != 0) { fprintf(stderr, "pipe returned %s\n", strerror(errno)); exit(1); } if ((file_fd = open(argv[1], O_CREAT|O_RDWR, 0644)) == -1) { fprintf(stderr, "open returned %s\n", strerror(errno)); exit(1); } listen_fd = socket(PF_INET, SOCK_STREAM, 0); if (listen_fd == -1) { fprintf(stderr, "socket returned %s\n", strerror(errno)); exit(1); } in_addr.sin_family = AF_INET; inet_aton("0.0.0.0", &in_addr.sin_addr); in_addr.sin_port = htons(4711); res = bind(listen_fd, (struct sockaddr *)&in_addr, sizeof(in_addr)); if (res == -1) { fprintf(stderr, "bind returned %s\n", strerror(errno)); exit(1); } res = listen(listen_fd, 5); if (res == -1) { fprintf(stderr, "listen returned %s\n", strerror(errno)); exit(1); } sock = accept(listen_fd, NULL, NULL); if (sock == -1) { fprintf(stderr, "accept returned %s\n", strerror(errno)); exit(1); } while (1) { ssize_t nread, nwritten; nread = splice(sock, NULL, pipefds[1], NULL, to_read, SPLICE_F_MOVE); if (nread == -1) { fprintf(stderr, "splice failed: %s\n", strerror(errno)); exit(1); } if (nread == 0) { printf("EOF\n"); return 0; } nwritten = splice(pipefds[0], NULL, file_fd, NULL, nread, SPLICE_F_MOVE); if (nwritten != nread) { fprintf(stderr, "splice failed: %d/%d %s\n", (int)nread, (int)nwritten, nwritten == -1 ? strerror(errno) : ""); exit(1); } } return 0; }