X-Git-Url: https://pd.if.org/git/?p=pdutils;a=blobdiff_plain;f=utils%2Ftee%2Ftee.c;fp=utils%2Ftee%2Ftee.c;h=9b6d4cb8915881df9a0fd8d0d0ac0f5fd1fe56cb;hp=0000000000000000000000000000000000000000;hb=4daa873acbfc240e9ecc350e74c14bbfd58fabc9;hpb=b6d847ae20c32744d508eced2be3132c3fa8c5b9 diff --git a/utils/tee/tee.c b/utils/tee/tee.c new file mode 100644 index 0000000..9b6d4cb --- /dev/null +++ b/utils/tee/tee.c @@ -0,0 +1,102 @@ +/* + * tee.c - duplicate standard input + * + * Version: 2008-1.01 + * Build: c89 -o tee tee.c + * Source: + * Spec: + * + * This is free and unencumbered software released into the public domain, + * provided "as is", without warranty of any kind, express or implied. See the + * file UNLICENSE and the website for further details. + */ + + +#define _POSIX_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +#define USAGE "usage: tee [-ai] [file ...]\n" +#define AMBIGOPT "tee: Ambiguous [-]; operand or bad option?\n" +#define FLIMIT "tee: Maximum of %d output files exceeded\n" +#define BUFSIZE 4096 +#define MAXFILES 13 + +static void error(char *s); + +static int exitstatus; + + +int main(int argc, char **argv) +{ + extern int opterr, optind; + int c, i; + unsigned char buf[BUFSIZE]; + ssize_t n; + int slot, fdfn[MAXFILES + 1][2], mode = O_WRONLY | O_CREAT | O_TRUNC; + + setlocale(LC_ALL, ""); + opterr = 0; + + while ((c = getopt(argc, argv, "ai")) != -1) + switch (c) + { + case 'a': /* append to rather than overwrite file(s) */ + mode = O_WRONLY | O_CREAT | O_APPEND; + break; + + case 'i': /* ignore the SIGINT signal */ + signal(SIGINT, SIG_IGN); + break; + + default: + fprintf(stderr, USAGE); + return(1); + } + + i = optind; + fdfn[0][0] = STDOUT_FILENO; + + for (slot = 1; i < argc ; i++) + { + if (slot > MAXFILES) + fprintf(stderr, FLIMIT, MAXFILES); + else + { + if ((fdfn[slot][0] = open(argv[i], mode, 0666)) == -1) + error(argv[i]); + else + fdfn[slot++][1] = i; + } + } + + while ((n = read(STDIN_FILENO, buf, BUFSIZE)) > 0) + { + for (i = 0; i < slot; i++) + if (write(fdfn[i][0], buf, (size_t)n) != n) + error(argv[fdfn[i][1]]); + } + + if (n < 0) + error("stdin"); + + for (i = 1; i < slot; i++) + if (close(fdfn[i][0]) == -1) + error(argv[fdfn[i][1]]); + + return(exitstatus); +} + + +void error(char *s) +{ + fprintf(stderr, "tee: %s: %s\n", s, strerror(errno)); + exitstatus = 1; +}