2 * tee.c - duplicate standard input
5 * Build: c89 -o tee tee.c
6 * Source: <http://pdcore.sourceforge.net/>
7 * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/tee.html>
9 * This is free and unencumbered software released into the public domain,
10 * provided "as is", without warranty of any kind, express or implied. See the
11 * file UNLICENSE and the website <http://unlicense.org> for further details.
23 #include <sys/types.h>
26 #define USAGE "usage: tee [-ai] [file ...]\n"
27 #define AMBIGOPT "tee: Ambiguous [-]; operand or bad option?\n"
28 #define FLIMIT "tee: Maximum of %d output files exceeded\n"
32 static void error(char *s);
34 static int exitstatus;
37 int main(int argc, char **argv)
39 extern int opterr, optind;
41 unsigned char buf[BUFSIZE];
43 int slot, fdfn[MAXFILES + 1][2], mode = O_WRONLY | O_CREAT | O_TRUNC;
45 setlocale(LC_ALL, "");
48 while ((c = getopt(argc, argv, "ai")) != -1)
51 case 'a': /* append to rather than overwrite file(s) */
52 mode = O_WRONLY | O_CREAT | O_APPEND;
55 case 'i': /* ignore the SIGINT signal */
56 signal(SIGINT, SIG_IGN);
60 fprintf(stderr, USAGE);
65 fdfn[0][0] = STDOUT_FILENO;
67 for (slot = 1; i < argc ; i++)
70 fprintf(stderr, FLIMIT, MAXFILES);
73 if ((fdfn[slot][0] = open(argv[i], mode, 0666)) == -1)
80 while ((n = read(STDIN_FILENO, buf, BUFSIZE)) > 0)
82 for (i = 0; i < slot; i++)
83 if (write(fdfn[i][0], buf, (size_t)n) != n)
84 error(argv[fdfn[i][1]]);
90 for (i = 1; i < slot; i++)
91 if (close(fdfn[i][0]) == -1)
92 error(argv[fdfn[i][1]]);
100 fprintf(stderr, "tee: %s: %s\n", s, strerror(errno));