xref: /csrg-svn/usr.bin/tee/tee.c (revision 62303)
11123Sbill /*
2*62303Sbostic  * Copyright (c) 1988, 1993
3*62303Sbostic  *	The Regents of the University of California.  All rights reserved.
435063Sbostic  *
542770Sbostic  * %sccs.include.redist.c%
61123Sbill  */
71123Sbill 
835063Sbostic #ifndef lint
9*62303Sbostic static char copyright[] =
10*62303Sbostic "@(#) Copyright (c) 1988, 1993\n\
11*62303Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1235063Sbostic #endif /* not lint */
131123Sbill 
1435063Sbostic #ifndef lint
15*62303Sbostic static char sccsid[] = "@(#)tee.c	8.1 (Berkeley) 06/06/93";
1635063Sbostic #endif /* not lint */
1725600Ssam 
1835063Sbostic #include <sys/types.h>
1949236Sbostic #include <sys/stat.h>
2051979Sbostic #include <signal.h>
2151979Sbostic #include <errno.h>
2249236Sbostic #include <fcntl.h>
2349236Sbostic #include <unistd.h>
2435063Sbostic #include <stdio.h>
2549236Sbostic #include <stdlib.h>
2649236Sbostic #include <string.h>
2725600Ssam 
2838028Sbostic typedef struct _list {
2938028Sbostic 	struct _list *next;
3038028Sbostic 	int fd;
3138028Sbostic 	char *name;
3238028Sbostic } LIST;
3338028Sbostic LIST *head;
3438028Sbostic 
3551979Sbostic void add __P((int, char *));
3651979Sbostic void err __P((int, const char *, ...));
3751979Sbostic 
3851979Sbostic int
main(argc,argv)3935063Sbostic main(argc, argv)
4035063Sbostic 	int argc;
4151979Sbostic 	char *argv[];
4235063Sbostic {
4338028Sbostic 	register LIST *p;
4438585Sbostic 	register int n, fd, rval, wval;
4538585Sbostic 	register char *bp;
4638585Sbostic 	int append, ch, exitval;
4749236Sbostic 	char *buf;
4851971Storek #define	BSIZE (8 * 1024)
4925600Ssam 
5035063Sbostic 	append = 0;
5135063Sbostic 	while ((ch = getopt(argc, argv, "ai")) != EOF)
5235063Sbostic 		switch((char)ch) {
531123Sbill 		case 'a':
5435063Sbostic 			append = 1;
551123Sbill 			break;
561123Sbill 		case 'i':
5735063Sbostic 			(void)signal(SIGINT, SIG_IGN);
5835063Sbostic 			break;
5935063Sbostic 		case '?':
6035063Sbostic 		default:
6138028Sbostic 			(void)fprintf(stderr, "usage: tee [-ai] [file ...]\n");
6238028Sbostic 			exit(1);
631123Sbill 		}
6435063Sbostic 	argv += optind;
6535063Sbostic 	argc -= optind;
6635063Sbostic 
6751979Sbostic 	if ((buf = malloc((u_int)BSIZE)) == NULL)
6851979Sbostic 		err(1, "%s", strerror(errno));
6951979Sbostic 
7039688Sbostic 	add(STDOUT_FILENO, "stdout");
7151979Sbostic 
7251979Sbostic 	for (exitval = 0; *argv; ++argv)
7338580Sbostic 		if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND :
7451979Sbostic 		    O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0) {
7551979Sbostic 			err(0, "%s: %s", *argv, strerror(errno));
7651979Sbostic 			exitval = 1;
7751979Sbostic 		} else
7838028Sbostic 			add(fd, *argv);
7951979Sbostic 
8051971Storek 	while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0)
8138585Sbostic 		for (p = head; p; p = p->next) {
8238585Sbostic 			n = rval;
8338585Sbostic 			bp = buf;
8438585Sbostic 			do {
8538585Sbostic 				if ((wval = write(p->fd, bp, n)) == -1) {
8651979Sbostic 					err(0, "%s: %s",
8738585Sbostic 					    p->name, strerror(errno));
8838585Sbostic 					exitval = 1;
8938585Sbostic 					break;
9038585Sbostic 				}
9138585Sbostic 				bp += wval;
9238585Sbostic 			} while (n -= wval);
9338585Sbostic 		}
9451979Sbostic 	if (rval < 0)
9551979Sbostic 		err(1, "read: %s", strerror(errno));
9638028Sbostic 	exit(exitval);
971123Sbill }
9838028Sbostic 
9951979Sbostic void
add(fd,name)10038028Sbostic add(fd, name)
10138028Sbostic 	int fd;
10238028Sbostic 	char *name;
10338028Sbostic {
10438028Sbostic 	LIST *p;
10538028Sbostic 
10651979Sbostic 	if ((p = malloc((u_int)sizeof(LIST))) == NULL)
10751979Sbostic 		err(1, "%s", strerror(errno));
10838028Sbostic 	p->fd = fd;
10938028Sbostic 	p->name = name;
11038028Sbostic 	p->next = head;
11138028Sbostic 	head = p;
11238028Sbostic }
11351979Sbostic 
11451979Sbostic #if __STDC__
11551979Sbostic #include <stdarg.h>
11651979Sbostic #else
11751979Sbostic #include <varargs.h>
11851979Sbostic #endif
11951979Sbostic 
12051979Sbostic void
12151979Sbostic #if __STDC__
err(int doexit,const char * fmt,...)12251979Sbostic err(int doexit, const char *fmt, ...)
12351979Sbostic #else
12451979Sbostic err(doexit, fmt, va_alist)
12551979Sbostic 	int doexit;
12651979Sbostic 	char *fmt;
12751979Sbostic         va_dcl
12851979Sbostic #endif
12951979Sbostic {
13051979Sbostic 	va_list ap;
13151979Sbostic #if __STDC__
13251979Sbostic 	va_start(ap, fmt);
13351979Sbostic #else
13451979Sbostic 	va_start(ap);
13551979Sbostic #endif
13651979Sbostic 	(void)fprintf(stderr, "tee: ");
13751979Sbostic 	(void)vfprintf(stderr, fmt, ap);
13851979Sbostic 	va_end(ap);
13951979Sbostic 	(void)fprintf(stderr, "\n");
14051979Sbostic 	if (doexit)
14151979Sbostic 		exit(1);
14251979Sbostic }
143