|
|
1.1 root 1: /*
2: * Copyright (c) 1988 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1988 Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)tee.c 5.10 (Berkeley) 6/1/90";
28: #endif /* not lint */
29:
30: #include <sys/types.h>
31: #include <sys/file.h>
32: #include <signal.h>
33: #include <stdio.h>
34: #include <unistd.h>
35:
36: typedef struct _list {
37: struct _list *next;
38: int fd;
39: char *name;
40: } LIST;
41: LIST *head;
42:
43: main(argc, argv)
44: int argc;
45: char **argv;
46: {
47: extern int errno, optind;
48: register LIST *p;
49: register int n, fd, rval, wval;
50: register char *bp;
51: int append, ch, exitval;
52: char *buf, *malloc(), *strerror();
53: off_t lseek();
54:
55: append = 0;
56: while ((ch = getopt(argc, argv, "ai")) != EOF)
57: switch((char)ch) {
58: case 'a':
59: append = 1;
60: break;
61: case 'i':
62: (void)signal(SIGINT, SIG_IGN);
63: break;
64: case '?':
65: default:
66: (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n");
67: exit(1);
68: }
69: argv += optind;
70: argc -= optind;
71:
72: if (!(buf = malloc((u_int)8 * 1024))) {
73: (void)fprintf(stderr, "tee: out of space.\n");
74: exit(1);
75: }
76: add(STDOUT_FILENO, "stdout");
77: for (; *argv; ++argv)
78: if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND :
79: O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0)
80: (void)fprintf(stderr, "tee: %s: %s.\n",
81: *argv, strerror(errno));
82: else
83: add(fd, *argv);
84: exitval = 0;
85: while ((rval = read(STDIN_FILENO, buf, sizeof(buf))) > 0)
86: for (p = head; p; p = p->next) {
87: n = rval;
88: bp = buf;
89: do {
90: if ((wval = write(p->fd, bp, n)) == -1) {
91: (void)fprintf(stderr, "tee: %s: %s.\n",
92: p->name, strerror(errno));
93: exitval = 1;
94: break;
95: }
96: bp += wval;
97: } while (n -= wval);
98: }
99: if (rval < 0) {
100: (void)fprintf(stderr, "tee: read: %s\n", strerror(errno));
101: exit(1);
102: }
103: exit(exitval);
104: }
105:
106: add(fd, name)
107: int fd;
108: char *name;
109: {
110: LIST *p;
111: char *malloc(), *strerror();
112:
113: /* NOSTRICT */
114: if (!(p = (LIST *)malloc((u_int)sizeof(LIST)))) {
115: (void)fprintf(stderr, "tee: out of space.\n");
116: exit(1);
117: }
118: p->fd = fd;
119: p->name = name;
120: p->next = head;
121: head = p;
122: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.