tee.c revision 28199
1168404Spjd/*
2168404Spjd * Copyright (c) 1988, 1993
3168404Spjd *	The Regents of the University of California.  All rights reserved.
4168404Spjd *
5168404Spjd * Redistribution and use in source and binary forms, with or without
6168404Spjd * modification, are permitted provided that the following conditions
7168404Spjd * are met:
8168404Spjd * 1. Redistributions of source code must retain the above copyright
9168404Spjd *    notice, this list of conditions and the following disclaimer.
10168404Spjd * 2. Redistributions in binary form must reproduce the above copyright
11168404Spjd *    notice, this list of conditions and the following disclaimer in the
12168404Spjd *    documentation and/or other materials provided with the distribution.
13168404Spjd * 3. All advertising materials mentioning features or use of this software
14168404Spjd *    must display the following acknowledgement:
15168404Spjd *	This product includes software developed by the University of
16168404Spjd *	California, Berkeley and its contributors.
17168404Spjd * 4. Neither the name of the University nor the names of its contributors
18168404Spjd *    may be used to endorse or promote products derived from this software
19168404Spjd *    without specific prior written permission.
20168404Spjd *
21168404Spjd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22219089Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23229565Smm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24229565Smm * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25168404Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26168404Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27168404Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28168404Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29168404Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30168404Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31168404Spjd * SUCH DAMAGE.
32168404Spjd */
33219089Spjd
34185029Spjd#ifndef lint
35185029Spjdstatic const char copyright[] =
36168404Spjd"@(#) Copyright (c) 1988, 1993\n\
37168404Spjd	The Regents of the University of California.  All rights reserved.\n";
38168404Spjd#endif /* not lint */
39168404Spjd
40168404Spjd#ifndef lint
41168404Spjd#if 0
42219089Spjdstatic char sccsid[] = "@(#)tee.c	8.1 (Berkeley) 6/6/93";
43168404Spjd#endif
44168404Spjdstatic const char rcsid[] =
45168404Spjd	"$Id$";
46168404Spjd#endif /* not lint */
47168404Spjd
48168404Spjd#include <sys/types.h>
49168404Spjd#include <sys/stat.h>
50168404Spjd#include <err.h>
51185029Spjd#include <fcntl.h>
52185029Spjd#include <signal.h>
53185029Spjd#include <stdio.h>
54185029Spjd#include <stdlib.h>
55185029Spjd#include <string.h>
56185029Spjd#include <unistd.h>
57209962Smm
58185029Spjdtypedef struct _list {
59168404Spjd	struct _list *next;
60224174Smm	int fd;
61168404Spjd	char *name;
62185029Spjd} LIST;
63185029SpjdLIST *head;
64185029Spjd
65168404Spjdvoid add __P((int, char *));
66185029Spjdstatic void usage __P((void));
67185029Spjd
68185029Spjdint
69168404Spjdmain(argc, argv)
70168404Spjd	int argc;
71168404Spjd	char *argv[];
72168404Spjd{
73168404Spjd	register LIST *p;
74185029Spjd	register int n, fd, rval, wval;
75185029Spjd	register char *bp;
76209962Smm	int append, ch, exitval;
77219089Spjd	char *buf;
78185029Spjd#define	BSIZE (8 * 1024)
79209962Smm
80209962Smm	append = 0;
81209962Smm	while ((ch = getopt(argc, argv, "ai")) != -1)
82209962Smm		switch((char)ch) {
83219089Spjd		case 'a':
84219089Spjd			append = 1;
85168404Spjd			break;
86168404Spjd		case 'i':
87168404Spjd			(void)signal(SIGINT, SIG_IGN);
88168404Spjd			break;
89168404Spjd		case '?':
90185029Spjd		default:
91185029Spjd			usage();
92185029Spjd		}
93185029Spjd	argv += optind;
94185029Spjd	argc -= optind;
95185029Spjd
96185029Spjd	if ((buf = malloc((u_int)BSIZE)) == NULL)
97168404Spjd		errx(1, "malloc");
98185029Spjd
99168404Spjd	add(STDOUT_FILENO, "stdout");
100168404Spjd
101168404Spjd	for (exitval = 0; *argv; ++argv)
102185029Spjd		if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND :
103168404Spjd		    O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0) {
104168404Spjd			warn("%s", *argv);
105168404Spjd			exitval = 1;
106168404Spjd		} else
107168404Spjd			add(fd, *argv);
108168404Spjd
109168404Spjd	while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0)
110168404Spjd		for (p = head; p; p = p->next) {
111168404Spjd			n = rval;
112185029Spjd			bp = buf;
113185029Spjd			do {
114185029Spjd				if ((wval = write(p->fd, bp, n)) == -1) {
115185029Spjd					warn("%s", p->name);
116185029Spjd					exitval = 1;
117185029Spjd					break;
118185029Spjd				}
119185029Spjd				bp += wval;
120185029Spjd			} while (n -= wval);
121185029Spjd		}
122185029Spjd	if (rval < 0)
123185029Spjd		err(1, "read");
124185029Spjd	exit(exitval);
125185029Spjd}
126185029Spjd
127185029Spjdstatic void
128168404Spjdusage()
129168404Spjd{
130168404Spjd	(void)fprintf(stderr, "usage: tee [-ai] [file ...]\n");
131168404Spjd	exit(1);
132168404Spjd}
133168404Spjd
134168404Spjdvoid
135168404Spjdadd(fd, name)
136168404Spjd	int fd;
137185029Spjd	char *name;
138185029Spjd{
139185029Spjd	LIST *p;
140219089Spjd
141219089Spjd	if ((p = malloc((u_int)sizeof(LIST))) == NULL)
142209962Smm		errx(1, "malloc");
143209962Smm	p->fd = fd;
144209962Smm	p->name = name;
145209962Smm	p->next = head;
146209962Smm	head = p;
147209962Smm}
148219089Spjd