1 /*
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char copyright[] =
10 "@(#) Copyright (c) 1988, 1993\n\
11 The Regents of the University of California. All rights reserved.\n";
12 #endif /* not lint */
13
14 #ifndef lint
15 static char sccsid[] = "@(#)tee.c 8.1 (Berkeley) 06/06/93";
16 #endif /* not lint */
17
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <signal.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 typedef struct _list {
29 struct _list *next;
30 int fd;
31 char *name;
32 } LIST;
33 LIST *head;
34
35 void add __P((int, char *));
36 void err __P((int, const char *, ...));
37
38 int
main(argc,argv)39 main(argc, argv)
40 int argc;
41 char *argv[];
42 {
43 register LIST *p;
44 register int n, fd, rval, wval;
45 register char *bp;
46 int append, ch, exitval;
47 char *buf;
48 #define BSIZE (8 * 1024)
49
50 append = 0;
51 while ((ch = getopt(argc, argv, "ai")) != EOF)
52 switch((char)ch) {
53 case 'a':
54 append = 1;
55 break;
56 case 'i':
57 (void)signal(SIGINT, SIG_IGN);
58 break;
59 case '?':
60 default:
61 (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n");
62 exit(1);
63 }
64 argv += optind;
65 argc -= optind;
66
67 if ((buf = malloc((u_int)BSIZE)) == NULL)
68 err(1, "%s", strerror(errno));
69
70 add(STDOUT_FILENO, "stdout");
71
72 for (exitval = 0; *argv; ++argv)
73 if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND :
74 O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0) {
75 err(0, "%s: %s", *argv, strerror(errno));
76 exitval = 1;
77 } else
78 add(fd, *argv);
79
80 while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0)
81 for (p = head; p; p = p->next) {
82 n = rval;
83 bp = buf;
84 do {
85 if ((wval = write(p->fd, bp, n)) == -1) {
86 err(0, "%s: %s",
87 p->name, strerror(errno));
88 exitval = 1;
89 break;
90 }
91 bp += wval;
92 } while (n -= wval);
93 }
94 if (rval < 0)
95 err(1, "read: %s", strerror(errno));
96 exit(exitval);
97 }
98
99 void
add(fd,name)100 add(fd, name)
101 int fd;
102 char *name;
103 {
104 LIST *p;
105
106 if ((p = malloc((u_int)sizeof(LIST))) == NULL)
107 err(1, "%s", strerror(errno));
108 p->fd = fd;
109 p->name = name;
110 p->next = head;
111 head = p;
112 }
113
114 #if __STDC__
115 #include <stdarg.h>
116 #else
117 #include <varargs.h>
118 #endif
119
120 void
121 #if __STDC__
err(int doexit,const char * fmt,...)122 err(int doexit, const char *fmt, ...)
123 #else
124 err(doexit, fmt, va_alist)
125 int doexit;
126 char *fmt;
127 va_dcl
128 #endif
129 {
130 va_list ap;
131 #if __STDC__
132 va_start(ap, fmt);
133 #else
134 va_start(ap);
135 #endif
136 (void)fprintf(stderr, "tee: ");
137 (void)vfprintf(stderr, fmt, ap);
138 va_end(ap);
139 (void)fprintf(stderr, "\n");
140 if (doexit)
141 exit(1);
142 }
143