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: #include <sys/cdefs.h>
33: #ifndef lint
34: __COPYRIGHT("@(#) Copyright (c) 1988, 1993\n\
35: The Regents of the University of California. All rights reserved.\n");
36: #endif
37:
38: #ifndef lint
39: #if 0
40: static char sccsid[] = "@(#)tee.c 8.1 (Berkeley) 6/6/93";
41: #endif
42: __RCSID("$NetBSD: tee.c,v 1.7 2003/08/07 11:16:07 agc Exp $");
43: #endif
44:
45: #include <sys/types.h>
46: #include <sys/stat.h>
47: #include <signal.h>
48: #include <errno.h>
49: #include <fcntl.h>
50: #include <unistd.h>
51: #include <stdio.h>
52: #include <stdlib.h>
53: #include <string.h>
54: #include <locale.h>
55: #include <err.h>
56:
57: typedef struct _list {
58: struct _list *next;
59: int fd;
60: char *name;
61: } LIST;
62: LIST *head;
63:
64: void add __P((int, char *));
65: int main __P((int, char **));
66:
67: int
68: main(argc, argv)
69: int argc;
70: char *argv[];
71: {
72: LIST *p;
73: int n, fd, rval, wval;
74: char *bp;
75: int append, ch, exitval;
76: char *buf;
77: #define BSIZE (8 * 1024)
78:
79: setlocale(LC_ALL, "");
80:
81: append = 0;
82: while ((ch = getopt(argc, argv, "ai")) != -1)
83: switch((char)ch) {
84: case 'a':
85: append = 1;
86: break;
87: case 'i':
88: (void)signal(SIGINT, SIG_IGN);
89: break;
90: case '?':
91: default:
92: (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n");
93: exit(1);
94: }
95: argv += optind;
96: argc -= optind;
97:
98: if ((buf = malloc((size_t)BSIZE)) == NULL)
99: err(1, "malloc");
100:
101: add(STDOUT_FILENO, "stdout");
102:
103: for (exitval = 0; *argv; ++argv)
104: if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND :
105: O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0) {
106: warn("%s", *argv);
107: exitval = 1;
108: } else
109: add(fd, *argv);
110:
111: while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0)
112: for (p = head; p; p = p->next) {
113: n = rval;
114: bp = buf;
115: do {
116: if ((wval = write(p->fd, bp, n)) == -1) {
117: warn("%s", p->name);
118: exitval = 1;
119: break;
120: }
121: bp += wval;
122: } while (n -= wval);
123: }
124: if (rval < 0) {
125: warn("read");
126: exitval = 1;
127: }
128:
129: for (p = head; p; p = p->next) {
130: if (close(p->fd) == -1) {
131: warn("%s", p->name);
132: exitval = 1;
133: }
134: }
135:
136: exit(exitval);
137: }
138:
139: void
140: add(fd, name)
141: int fd;
142: char *name;
143: {
144: LIST *p;
145:
146: if ((p = malloc((size_t)sizeof(LIST))) == NULL)
147: err(1, "malloc");
148: p->fd = fd;
149: p->name = name;
150: p->next = head;
151: head = p;
152: }