summaryrefslogtreecommitdiff
path: root/src/commands/tee.c
blob: 224463cf86690b8c76b1a19c035750e656cc3a56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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;
}