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