diff options
| author | Charles Cabergs <me@cacharle.xyz> | 2020-08-22 19:43:03 +0200 |
|---|---|---|
| committer | Charles Cabergs <me@cacharle.xyz> | 2020-08-22 19:43:03 +0200 |
| commit | c40f79737a4ce6ae0cd8bd6ea7f302217333e486 (patch) | |
| tree | 5afe1af26880bd7f8b16ee33fb8e14f99f665938 /src/tee.c | |
| parent | f204fe59bd5fa537bf84cb522339c92b16f5a909 (diff) | |
| download | coreutils-c40f79737a4ce6ae0cd8bd6ea7f302217333e486.tar.gz coreutils-c40f79737a4ce6ae0cd8bd6ea7f302217333e486.tar.bz2 coreutils-c40f79737a4ce6ae0cd8bd6ea7f302217333e486.zip | |
Added Makefile
Diffstat (limited to 'src/tee.c')
| -rw-r--r-- | src/tee.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/tee.c b/src/tee.c new file mode 100644 index 0000000..4df5074 --- /dev/null +++ b/src/tee.c @@ -0,0 +1,68 @@ +#define _POSIX_C_SOURCE 2 // getopt +#define _XOPEN_SOURCE 500 // sigaction +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <errno.h> +#include <string.h> +#include <signal.h> + +#define BUFFER_SIZE 2048 + +char *g_name = "tee"; + +int main(int argc, char **argv) +{ + int option; + bool append = false; + + g_name = argv[0]; + + struct sigaction action; + action.sa_handler = SIG_IGN; + action.sa_flags = SA_NODEFER; + + while ((option = getopt(argc, argv, "ai")) != -1) + { + switch (option) + { + case 'a': + append = true; + break; + case 'i': + sigaction(SIGINT, &action, NULL); + break; + } + } + + size_t files_num = argc - optind; + FILE **files = calloc(files_num, sizeof(FILE*)); + if (files == NULL) + return EXIT_FAILURE; + + for (size_t i = 0; i < files_num; i++) + { + files[i] = fopen(argv[optind + i], append ? "a" : "w"); + if (files[i] == NULL) + { + fprintf(stderr, "%s: %s: %s\n", g_name, argv[optind + i], strerror(errno)); + i--; + files_num--; + } + } + + char buf[BUFFER_SIZE + 1] = {0}; + size_t read_size = 0; + while ((read_size = fread(buf, 1, BUFFER_SIZE, stdin)) > 0) + { + fwrite(buf, 1, read_size, stdout); + for (size_t i = 0; i < files_num; i++) + fwrite(buf, 1, read_size, files[i]); + } + + for (size_t i = 0; i < files_num; i++) + fclose(files[i]); + free(files); + return EXIT_SUCCESS; +} |
