diff options
Diffstat (limited to 'src/commands/tee.c')
-rw-r--r-- | src/commands/tee.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/commands/tee.c b/src/commands/tee.c new file mode 100644 index 0000000..224463c --- /dev/null +++ b/src/commands/tee.c @@ -0,0 +1,75 @@ +#include "../command.h" + +#include <signal.h> +#include <stdio.h> +#include <string.h> + + +static void help() { + printf("Usage: tee [-ai] [FILE]...\n\n"); + printf("Copy stdin to each FILE, and also to stdout\n\n"); + printf("\t-a Append to the given FILEs, don't overwrite\n"); + printf("\t-i Ignore interrupt signals (SIGINT)\n"); + exit(EXIT_SUCCESS); +} + +static void handle(){} + +static void run_tee(int file_count, FILE* files[file_count]) { + char c; + while((c = getchar()) != EOF) { + for (int i = 0; i < file_count; i++) { + fwrite(&c, 1, 1, files[i]); + fflush(files[i]); + } + putchar(c); + } + for (int i = 0; i < file_count; i++) { + fclose(files[i]); + } +} + +COMMAND(tee) { + + bool append = false; + bool handle_sigint = false; + + int start = 0; + for (int i = 0; i < argc; i++) { + if (!prefix("-", argv[i])) break; + if (streql("--help", argv[i])) help(); + + start++; + for (size_t j = 1; j < strlen(argv[i]); j++) { + char o = argv[i][j]; + switch (o) { + case 'a': + append = true; + break; + case 'i': + handle_sigint = true; + break; + default: + error("error: unkown option: %c", o); + } + } + } + + if (handle_sigint) { + signal(SIGINT, handle); + } + + if (argc - start < 1) { + run_tee(0, NULL); + return EXIT_SUCCESS; + } + + FILE* files[argc - start]; + for (int i = start; i < argc; i++) { + FILE* file = get_file(argv[i], append ? "a" : "w"); + files[i - start] = file; + } + + run_tee(argc - start, files); + return EXIT_SUCCESS; +} |