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