xref: /csrg-svn/usr.bin/tee/tee.c (revision 42770)
1 /*
2  * Copyright (c) 1988 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
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 */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)tee.c	5.10 (Berkeley) 06/01/90";
16 #endif /* not lint */
17 
18 #include <sys/types.h>
19 #include <sys/file.h>
20 #include <signal.h>
21 #include <stdio.h>
22 #include <unistd.h>
23 
24 typedef struct _list {
25 	struct _list *next;
26 	int fd;
27 	char *name;
28 } LIST;
29 LIST *head;
30 
31 main(argc, argv)
32 	int argc;
33 	char **argv;
34 {
35 	extern int errno, optind;
36 	register LIST *p;
37 	register int n, fd, rval, wval;
38 	register char *bp;
39 	int append, ch, exitval;
40 	char *buf, *malloc(), *strerror();
41 	off_t lseek();
42 
43 	append = 0;
44 	while ((ch = getopt(argc, argv, "ai")) != EOF)
45 		switch((char)ch) {
46 		case 'a':
47 			append = 1;
48 			break;
49 		case 'i':
50 			(void)signal(SIGINT, SIG_IGN);
51 			break;
52 		case '?':
53 		default:
54 			(void)fprintf(stderr, "usage: tee [-ai] [file ...]\n");
55 			exit(1);
56 		}
57 	argv += optind;
58 	argc -= optind;
59 
60 	if (!(buf = malloc((u_int)8 * 1024))) {
61 		(void)fprintf(stderr, "tee: out of space.\n");
62 		exit(1);
63 	}
64 	add(STDOUT_FILENO, "stdout");
65 	for (; *argv; ++argv)
66 		if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND :
67 		    O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0)
68 			(void)fprintf(stderr, "tee: %s: %s.\n",
69 			    *argv, strerror(errno));
70 		else
71 			add(fd, *argv);
72 	exitval = 0;
73 	while ((rval = read(STDIN_FILENO, buf, sizeof(buf))) > 0)
74 		for (p = head; p; p = p->next) {
75 			n = rval;
76 			bp = buf;
77 			do {
78 				if ((wval = write(p->fd, bp, n)) == -1) {
79 					(void)fprintf(stderr, "tee: %s: %s.\n",
80 					    p->name, strerror(errno));
81 					exitval = 1;
82 					break;
83 				}
84 				bp += wval;
85 			} while (n -= wval);
86 		}
87 	if (rval < 0) {
88 		(void)fprintf(stderr, "tee: read: %s\n", strerror(errno));
89 		exit(1);
90 	}
91 	exit(exitval);
92 }
93 
94 add(fd, name)
95 	int fd;
96 	char *name;
97 {
98 	LIST *p;
99 	char *malloc(), *strerror();
100 
101 	/* NOSTRICT */
102 	if (!(p = (LIST *)malloc((u_int)sizeof(LIST)))) {
103 		(void)fprintf(stderr, "tee: out of space.\n");
104 		exit(1);
105 	}
106 	p->fd = fd;
107 	p->name = name;
108 	p->next = head;
109 	head = p;
110 }
111