bore

Unnamed repository
Log | Files | Refs

commit 0f1826ad5aea5a7e10c94d37f3ae960d615c6adc
parent 660e87bbb6963521534f817f1f2c88c549772489
Author: aabacchus <ben@bvnf.space>
Date:   Sun, 19 Sep 2021 21:22:53 +0100

tee: add

Diffstat:
MMakefile | 2+-
Atee.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile @@ -1,6 +1,6 @@ .POSIX: -BINS = cat echo +BINS = cat echo tee XCFLAGS = $(CFLAGS) -Wall -Wextra -Wpedantic -g .PHONY: clean diff --git a/tee.c b/tee.c @@ -0,0 +1,73 @@ +#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) { + 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)); + return 1; + } + } + if (write(1, buf, n) == -1) { + fprintf(stderr, "tee: write: %s\n", strerror(errno)); + return 1; + } + } + if (n == -1){ + fprintf(stderr, "tee: read: %s\n", strerror(errno)); + return 1; + } + return 0; +} + +int +main(int argc, char **argv) { + int err = 0; + int flags = O_WRONLY | O_CREAT; + + int c; + while ((c = getopt(argc, argv, "ai")) != EOF) { + 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; + continue; + } + } + if (tee(fds, i) != 0) { + err = 1; + } + while (--i) { + if (close(fds[i]) == -1){ + fprintf(stderr, "tee: close: %s\n", strerror(errno)); + err = 1; + } + } + return err; +}