diff options
author | Tristan Riehs <tristan.riehs@bordeaux-inp.fr> | 2023-10-19 22:09:32 +0200 |
---|---|---|
committer | Tristan Riehs <tristan.riehs@bordeaux-inp.fr> | 2023-10-19 22:09:32 +0200 |
commit | ccecf92b8c46d3db1da634fe5cf8a92b226d51f6 (patch) | |
tree | 1408eb1f06b6fb10709ab5c8582c29a38b4d583a | |
parent | 9ac1b23f334b4d0284e903b8ee83b296c8caffb9 (diff) |
stdin clone OK
-rw-r--r-- | rpt.c | 44 |
1 files changed, 43 insertions, 1 deletions
@@ -1,14 +1,21 @@ #define _GNU_SOURCE /* getopt_long */ #include <errno.h> +#include <fcntl.h> #include <getopt.h> #include <stdio.h> #include <stdlib.h> +#include <sys/stat.h> #include <sys/wait.h> #include <unistd.h> #define VERSION "1.0.0" -#define TMPFILE "/tmp/repeat-tmp" + +/* Size of the buffer used to clone stdin. */ +#define BUFSIZE 8000 + +/* File descriptor associated to the clone of stdin. */ +int clone_fd; void print_usage(FILE *output) @@ -103,6 +110,39 @@ repeat_cmd(char **argv, long count, void (*handle_error_f)(int status)) invoke_cmd(argv, handle_error_f); } +void +copy_stdin() +{ + ssize_t nbytes; + char buf[BUFSIZE]; + FILE *tmp_stream; + + tmp_stream = tmpfile(); + + if (!tmp_stream) + { + perror("rpt"); + exit(1); + } + + clone_fd = fileno(tmp_stream); + errno = 0; + + while ((nbytes = read(STDIN_FILENO, buf, BUFSIZE)) > 0) + { + if (write(clone_fd, buf, nbytes) < 0) + break; + } + + fclose(tmp_stream); + + if (errno) + { + perror("rpt"); + exit(1); + } +} + int main(int argc, char* argv[]) { @@ -167,7 +207,9 @@ main(int argc, char* argv[]) return 3; } + copy_stdin(); repeat_cmd(argv + optind, count, handle_error_f); + close(clone_fd); return 0; } |