bore

basic core utilities (PD)
git clone git://bvnf.space/bore.git
Log | Files | Refs | README

tee.c (1721B)


      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
     76
     77
     78
#define _XOPEN_SOURCE 700
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define BUF_SIZE 4096

int
tee(int *fds, int len) {
    int ret = 0;
    unsigned char buf[BUF_SIZE];
    ssize_t n;
    while ((n = read(0, buf, BUF_SIZE)) > 0) {
        int i = 0;
        for (; i < len; i++) {
            if (write(fds[i], buf, n) == -1) {
                fprintf(stderr, "tee: write: %s\n", strerror(errno));
                ret = 1;
                continue;
            }
        }
        if (write(1, buf, n) == -1) {
            fprintf(stderr, "tee: write: %s\n", strerror(errno));
            ret = 1;
        }
    }
    if (n == -1) {
        fprintf(stderr, "tee: read: %s\n", strerror(errno));
        ret = 1;
    }
    return ret;
}

int
main(int argc, char **argv) {
    int err = 0;
    int flags = O_WRONLY | O_CREAT;

    int c;
    while ((c = getopt(argc, argv, "ai")) != -1) {
        switch (c) {
            case 'a':
                flags |= O_APPEND;
                break;
            case 'i':
                signal(SIGINT, SIG_IGN);
                break;
        }
    }

    argv += optind - 1;
    int fds[argc - optind];
    int i = 0;

    while (*++argv) {
        fds[i] = open(*argv, flags, 0644);
        if (fds[i] == -1) {
            fprintf(stderr, "tee: open %s: %s\n", *argv, strerror(errno));
            err = 1;
            i--;
            continue;
        }
        i++;
    }
    if (tee(fds, i) != 0) {
        err = 1;
    }
    while (--i > 0) {
        if (close(fds[i]) == -1) {
            fprintf(stderr, "tee: close: %s\n", strerror(errno));
            err = 1;
        }
    }
    return err;
}