xref: /csrg-svn/usr.bin/tee/tee.c (revision 49236)
11123Sbill /*
235063Sbostic  * Copyright (c) 1988 Regents of the University of California.
335063Sbostic  * All rights reserved.
435063Sbostic  *
542770Sbostic  * %sccs.include.redist.c%
61123Sbill  */
71123Sbill 
835063Sbostic #ifndef lint
935063Sbostic char copyright[] =
1035063Sbostic "@(#) Copyright (c) 1988 Regents of the University of California.\n\
1135063Sbostic  All rights reserved.\n";
1235063Sbostic #endif /* not lint */
131123Sbill 
1435063Sbostic #ifndef lint
15*49236Sbostic static char sccsid[] = "@(#)tee.c	5.11 (Berkeley) 05/06/91";
1635063Sbostic #endif /* not lint */
1725600Ssam 
1835063Sbostic #include <sys/types.h>
19*49236Sbostic #include <sys/stat.h>
20*49236Sbostic #include <fcntl.h>
2135063Sbostic #include <signal.h>
22*49236Sbostic #include <unistd.h>
2335063Sbostic #include <stdio.h>
24*49236Sbostic #include <stdlib.h>
25*49236Sbostic #include <string.h>
2625600Ssam 
2738028Sbostic typedef struct _list {
2838028Sbostic 	struct _list *next;
2938028Sbostic 	int fd;
3038028Sbostic 	char *name;
3138028Sbostic } LIST;
3238028Sbostic LIST *head;
3338028Sbostic 
3435063Sbostic main(argc, argv)
3535063Sbostic 	int argc;
3635063Sbostic 	char **argv;
3735063Sbostic {
3838028Sbostic 	extern int errno, optind;
3938028Sbostic 	register LIST *p;
4038585Sbostic 	register int n, fd, rval, wval;
4138585Sbostic 	register char *bp;
4238585Sbostic 	int append, ch, exitval;
43*49236Sbostic 	char *buf;
4435063Sbostic 	off_t lseek();
4525600Ssam 
4635063Sbostic 	append = 0;
4735063Sbostic 	while ((ch = getopt(argc, argv, "ai")) != EOF)
4835063Sbostic 		switch((char)ch) {
491123Sbill 		case 'a':
5035063Sbostic 			append = 1;
511123Sbill 			break;
521123Sbill 		case 'i':
5335063Sbostic 			(void)signal(SIGINT, SIG_IGN);
5435063Sbostic 			break;
5535063Sbostic 		case '?':
5635063Sbostic 		default:
5738028Sbostic 			(void)fprintf(stderr, "usage: tee [-ai] [file ...]\n");
5838028Sbostic 			exit(1);
591123Sbill 		}
6035063Sbostic 	argv += optind;
6135063Sbostic 	argc -= optind;
6235063Sbostic 
6338028Sbostic 	if (!(buf = malloc((u_int)8 * 1024))) {
6438028Sbostic 		(void)fprintf(stderr, "tee: out of space.\n");
6538028Sbostic 		exit(1);
661123Sbill 	}
6739688Sbostic 	add(STDOUT_FILENO, "stdout");
6838028Sbostic 	for (; *argv; ++argv)
6938580Sbostic 		if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND :
70*49236Sbostic 		    O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0)
7138028Sbostic 			(void)fprintf(stderr, "tee: %s: %s.\n",
7238028Sbostic 			    *argv, strerror(errno));
7338580Sbostic 		else
7438028Sbostic 			add(fd, *argv);
7538028Sbostic 	exitval = 0;
7639688Sbostic 	while ((rval = read(STDIN_FILENO, buf, sizeof(buf))) > 0)
7738585Sbostic 		for (p = head; p; p = p->next) {
7838585Sbostic 			n = rval;
7938585Sbostic 			bp = buf;
8038585Sbostic 			do {
8138585Sbostic 				if ((wval = write(p->fd, bp, n)) == -1) {
8238585Sbostic 					(void)fprintf(stderr, "tee: %s: %s.\n",
8338585Sbostic 					    p->name, strerror(errno));
8438585Sbostic 					exitval = 1;
8538585Sbostic 					break;
8638585Sbostic 				}
8738585Sbostic 				bp += wval;
8838585Sbostic 			} while (n -= wval);
8938585Sbostic 		}
9038585Sbostic 	if (rval < 0) {
9138028Sbostic 		(void)fprintf(stderr, "tee: read: %s\n", strerror(errno));
9238028Sbostic 		exit(1);
9338028Sbostic 	}
9438028Sbostic 	exit(exitval);
951123Sbill }
9638028Sbostic 
9738028Sbostic add(fd, name)
9838028Sbostic 	int fd;
9938028Sbostic 	char *name;
10038028Sbostic {
10138028Sbostic 	LIST *p;
10238028Sbostic 
103*49236Sbostic 	if (!(p = malloc((u_int)sizeof(LIST)))) {
10438028Sbostic 		(void)fprintf(stderr, "tee: out of space.\n");
10538028Sbostic 		exit(1);
10638028Sbostic 	}
10738028Sbostic 	p->fd = fd;
10838028Sbostic 	p->name = name;
10938028Sbostic 	p->next = head;
11038028Sbostic 	head = p;
11138028Sbostic }
112