2023-05-01 04:31:13 +00:00
|
|
|
#include "../command.h"
|
|
|
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
2023-05-01 22:43:32 +00:00
|
|
|
static struct {
|
|
|
|
bool append;
|
|
|
|
bool handle_sigint;
|
|
|
|
} flags;
|
|
|
|
|
|
|
|
static void help(void) {
|
2023-05-01 04:31:13 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-05-01 22:43:32 +00:00
|
|
|
static void handle(int dummy){UNUSED(dummy);}
|
2023-05-01 04:31:13 +00:00
|
|
|
|
|
|
|
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]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-01 22:43:32 +00:00
|
|
|
static int short_arg(char c, char* next) {
|
|
|
|
UNUSED(next);
|
|
|
|
switch (c) {
|
|
|
|
case 'a':
|
|
|
|
flags.append = true;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
flags.handle_sigint = true;
|
|
|
|
break;
|
|
|
|
default:
|
2023-05-03 16:17:56 +00:00
|
|
|
return ARG_INVALID;
|
2023-05-01 22:43:32 +00:00
|
|
|
}
|
|
|
|
return ARG_UNUSED;
|
|
|
|
}
|
2023-05-01 04:31:13 +00:00
|
|
|
|
2023-05-01 22:43:32 +00:00
|
|
|
COMMAND(tee) {
|
2023-05-01 04:31:13 +00:00
|
|
|
|
2023-05-01 22:43:32 +00:00
|
|
|
flags.append = false;
|
|
|
|
flags.handle_sigint = false;
|
2023-05-01 04:31:13 +00:00
|
|
|
|
2023-05-01 22:43:32 +00:00
|
|
|
int start = parse_args(argc, argv, help, short_arg, NULL);
|
2023-05-01 04:31:13 +00:00
|
|
|
|
2023-05-01 22:43:32 +00:00
|
|
|
if (flags.handle_sigint) {
|
2023-05-01 04:31:13 +00:00
|
|
|
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++) {
|
2023-05-01 22:43:32 +00:00
|
|
|
FILE* file = get_file(argv[i], flags.append ? "a" : "w");
|
2023-05-01 04:31:13 +00:00
|
|
|
files[i - start] = file;
|
|
|
|
}
|
|
|
|
|
|
|
|
run_tee(argc - start, files);
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|