Commit | Line | Data |
---|---|---|
381222b6 | 1 | /* |
d8309abf KB |
2 | * Copyright (c) 1988 Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
cb956e54 | 5 | * %sccs.include.redist.c% |
381222b6 BJ |
6 | */ |
7 | ||
d8309abf KB |
8 | #ifndef lint |
9 | char copyright[] = | |
10 | "@(#) Copyright (c) 1988 Regents of the University of California.\n\ | |
11 | All rights reserved.\n"; | |
12 | #endif /* not lint */ | |
f76b99eb | 13 | |
d8309abf | 14 | #ifndef lint |
43bdb59a | 15 | static char sccsid[] = "@(#)tee.c 5.13 (Berkeley) %G%"; |
d8309abf | 16 | #endif /* not lint */ |
f76b99eb | 17 | |
d8309abf | 18 | #include <sys/types.h> |
162f6647 | 19 | #include <sys/stat.h> |
d8309abf | 20 | #include <signal.h> |
43bdb59a KB |
21 | #include <errno.h> |
22 | #include <fcntl.h> | |
d364a185 | 23 | #include <unistd.h> |
162f6647 KB |
24 | #include <stdio.h> |
25 | #include <stdlib.h> | |
26 | #include <string.h> | |
381222b6 | 27 | |
0e9710be KB |
28 | typedef struct _list { |
29 | struct _list *next; | |
30 | int fd; | |
31 | char *name; | |
32 | } LIST; | |
33 | LIST *head; | |
34 | ||
43bdb59a KB |
35 | void add __P((int, char *)); |
36 | void err __P((int, const char *, ...)); | |
37 | ||
38 | int | |
d8309abf KB |
39 | main(argc, argv) |
40 | int argc; | |
43bdb59a | 41 | char *argv[]; |
381222b6 | 42 | { |
0e9710be | 43 | register LIST *p; |
57e36e24 KB |
44 | register int n, fd, rval, wval; |
45 | register char *bp; | |
46 | int append, ch, exitval; | |
162f6647 | 47 | char *buf; |
6e52f822 | 48 | #define BSIZE (8 * 1024) |
d8309abf KB |
49 | |
50 | append = 0; | |
51 | while ((ch = getopt(argc, argv, "ai")) != EOF) | |
52 | switch((char)ch) { | |
381222b6 | 53 | case 'a': |
d8309abf | 54 | append = 1; |
381222b6 BJ |
55 | break; |
56 | case 'i': | |
d8309abf KB |
57 | (void)signal(SIGINT, SIG_IGN); |
58 | break; | |
59 | case '?': | |
60 | default: | |
0e9710be KB |
61 | (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n"); |
62 | exit(1); | |
381222b6 | 63 | } |
d8309abf KB |
64 | argv += optind; |
65 | argc -= optind; | |
66 | ||
43bdb59a KB |
67 | if ((buf = malloc((u_int)BSIZE)) == NULL) |
68 | err(1, "%s", strerror(errno)); | |
69 | ||
d364a185 | 70 | add(STDOUT_FILENO, "stdout"); |
43bdb59a KB |
71 | |
72 | for (exitval = 0; *argv; ++argv) | |
e25d9a9b | 73 | if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND : |
43bdb59a KB |
74 | O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0) { |
75 | err(0, "%s: %s", *argv, strerror(errno)); | |
76 | exitval = 1; | |
77 | } else | |
0e9710be | 78 | add(fd, *argv); |
43bdb59a | 79 | |
6e52f822 | 80 | while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0) |
57e36e24 KB |
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) { | |
43bdb59a | 86 | err(0, "%s: %s", |
57e36e24 KB |
87 | p->name, strerror(errno)); |
88 | exitval = 1; | |
89 | break; | |
90 | } | |
91 | bp += wval; | |
92 | } while (n -= wval); | |
93 | } | |
43bdb59a KB |
94 | if (rval < 0) |
95 | err(1, "read: %s", strerror(errno)); | |
0e9710be KB |
96 | exit(exitval); |
97 | } | |
98 | ||
43bdb59a | 99 | void |
0e9710be KB |
100 | add(fd, name) |
101 | int fd; | |
102 | char *name; | |
103 | { | |
104 | LIST *p; | |
0e9710be | 105 | |
43bdb59a KB |
106 | if ((p = malloc((u_int)sizeof(LIST))) == NULL) |
107 | err(1, "%s", strerror(errno)); | |
0e9710be KB |
108 | p->fd = fd; |
109 | p->name = name; | |
110 | p->next = head; | |
111 | head = p; | |
381222b6 | 112 | } |
43bdb59a KB |
113 | |
114 | #if __STDC__ | |
115 | #include <stdarg.h> | |
116 | #else | |
117 | #include <varargs.h> | |
118 | #endif | |
119 | ||
120 | void | |
121 | #if __STDC__ | |
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 | } |