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