xref: /csrg-svn/usr.bin/tee/tee.c (revision 42770)
11123Sbill /*
235063Sbostic  * Copyright (c) 1988 Regents of the University of California.
335063Sbostic  * All rights reserved.
435063Sbostic  *
5*42770Sbostic  * %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*42770Sbostic static char sccsid[] = "@(#)tee.c	5.10 (Berkeley) 06/01/90";
1635063Sbostic #endif /* not lint */
1725600Ssam 
1835063Sbostic #include <sys/types.h>
1935063Sbostic #include <sys/file.h>
2035063Sbostic #include <signal.h>
2135063Sbostic #include <stdio.h>
2239688Sbostic #include <unistd.h>
2325600Ssam 
2438028Sbostic typedef struct _list {
2538028Sbostic 	struct _list *next;
2638028Sbostic 	int fd;
2738028Sbostic 	char *name;
2838028Sbostic } LIST;
2938028Sbostic LIST *head;
3038028Sbostic 
3135063Sbostic main(argc, argv)
3235063Sbostic 	int argc;
3335063Sbostic 	char **argv;
3435063Sbostic {
3538028Sbostic 	extern int errno, optind;
3638028Sbostic 	register LIST *p;
3738585Sbostic 	register int n, fd, rval, wval;
3838585Sbostic 	register char *bp;
3938585Sbostic 	int append, ch, exitval;
4038028Sbostic 	char *buf, *malloc(), *strerror();
4135063Sbostic 	off_t lseek();
4225600Ssam 
4335063Sbostic 	append = 0;
4435063Sbostic 	while ((ch = getopt(argc, argv, "ai")) != EOF)
4535063Sbostic 		switch((char)ch) {
461123Sbill 		case 'a':
4735063Sbostic 			append = 1;
481123Sbill 			break;
491123Sbill 		case 'i':
5035063Sbostic 			(void)signal(SIGINT, SIG_IGN);
5135063Sbostic 			break;
5235063Sbostic 		case '?':
5335063Sbostic 		default:
5438028Sbostic 			(void)fprintf(stderr, "usage: tee [-ai] [file ...]\n");
5538028Sbostic 			exit(1);
561123Sbill 		}
5735063Sbostic 	argv += optind;
5835063Sbostic 	argc -= optind;
5935063Sbostic 
6038028Sbostic 	if (!(buf = malloc((u_int)8 * 1024))) {
6138028Sbostic 		(void)fprintf(stderr, "tee: out of space.\n");
6238028Sbostic 		exit(1);
631123Sbill 	}
6439688Sbostic 	add(STDOUT_FILENO, "stdout");
6538028Sbostic 	for (; *argv; ++argv)
6638580Sbostic 		if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND :
6738028Sbostic 		    O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0)
6838028Sbostic 			(void)fprintf(stderr, "tee: %s: %s.\n",
6938028Sbostic 			    *argv, strerror(errno));
7038580Sbostic 		else
7138028Sbostic 			add(fd, *argv);
7238028Sbostic 	exitval = 0;
7339688Sbostic 	while ((rval = read(STDIN_FILENO, buf, sizeof(buf))) > 0)
7438585Sbostic 		for (p = head; p; p = p->next) {
7538585Sbostic 			n = rval;
7638585Sbostic 			bp = buf;
7738585Sbostic 			do {
7838585Sbostic 				if ((wval = write(p->fd, bp, n)) == -1) {
7938585Sbostic 					(void)fprintf(stderr, "tee: %s: %s.\n",
8038585Sbostic 					    p->name, strerror(errno));
8138585Sbostic 					exitval = 1;
8238585Sbostic 					break;
8338585Sbostic 				}
8438585Sbostic 				bp += wval;
8538585Sbostic 			} while (n -= wval);
8638585Sbostic 		}
8738585Sbostic 	if (rval < 0) {
8838028Sbostic 		(void)fprintf(stderr, "tee: read: %s\n", strerror(errno));
8938028Sbostic 		exit(1);
9038028Sbostic 	}
9138028Sbostic 	exit(exitval);
921123Sbill }
9338028Sbostic 
9438028Sbostic add(fd, name)
9538028Sbostic 	int fd;
9638028Sbostic 	char *name;
9738028Sbostic {
9838028Sbostic 	LIST *p;
9938028Sbostic 	char *malloc(), *strerror();
10038028Sbostic 
10138028Sbostic 	/* NOSTRICT */
10238028Sbostic 	if (!(p = (LIST *)malloc((u_int)sizeof(LIST)))) {
10338028Sbostic 		(void)fprintf(stderr, "tee: out of space.\n");
10438028Sbostic 		exit(1);
10538028Sbostic 	}
10638028Sbostic 	p->fd = fd;
10738028Sbostic 	p->name = name;
10838028Sbostic 	p->next = head;
10938028Sbostic 	head = p;
11038028Sbostic }
111