11123Sbill /* 235063Sbostic * Copyright (c) 1988 Regents of the University of California. 335063Sbostic * All rights reserved. 435063Sbostic * 535063Sbostic * Redistribution and use in source and binary forms are permitted 635063Sbostic * provided that the above copyright notice and this paragraph are 735063Sbostic * duplicated in all such forms and that any documentation, 835063Sbostic * advertising materials, and other materials related to such 935063Sbostic * distribution and use acknowledge that the software was developed 1035063Sbostic * by the University of California, Berkeley. The name of the 1135063Sbostic * University may not be used to endorse or promote products derived 1235063Sbostic * from this software without specific prior written permission. 1335063Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1435063Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*38028Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 161123Sbill */ 171123Sbill 1835063Sbostic #ifndef lint 1935063Sbostic char copyright[] = 2035063Sbostic "@(#) Copyright (c) 1988 Regents of the University of California.\n\ 2135063Sbostic All rights reserved.\n"; 2235063Sbostic #endif /* not lint */ 231123Sbill 2435063Sbostic #ifndef lint 25*38028Sbostic static char sccsid[] = "@(#)tee.c 5.6 (Berkeley) 05/16/89"; 2635063Sbostic #endif /* not lint */ 2725600Ssam 2835063Sbostic #include <sys/types.h> 2935063Sbostic #include <sys/file.h> 3035063Sbostic #include <signal.h> 3135063Sbostic #include <stdio.h> 3225600Ssam 33*38028Sbostic typedef struct _list { 34*38028Sbostic struct _list *next; 35*38028Sbostic int fd; 36*38028Sbostic char *name; 37*38028Sbostic } LIST; 38*38028Sbostic LIST *head; 39*38028Sbostic 4035063Sbostic main(argc, argv) 4135063Sbostic int argc; 4235063Sbostic char **argv; 4335063Sbostic { 44*38028Sbostic extern int errno, optind; 45*38028Sbostic register LIST *p; 46*38028Sbostic register int append, n, fd; 47*38028Sbostic int ch, exitval; 48*38028Sbostic char *buf, *malloc(), *strerror(); 4935063Sbostic off_t lseek(); 5025600Ssam 5135063Sbostic append = 0; 5235063Sbostic while ((ch = getopt(argc, argv, "ai")) != EOF) 5335063Sbostic switch((char)ch) { 541123Sbill case 'a': 5535063Sbostic append = 1; 561123Sbill break; 571123Sbill case 'i': 5835063Sbostic (void)signal(SIGINT, SIG_IGN); 5935063Sbostic break; 6035063Sbostic case '?': 6135063Sbostic default: 62*38028Sbostic (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n"); 63*38028Sbostic exit(1); 641123Sbill } 6535063Sbostic argv += optind; 6635063Sbostic argc -= optind; 6735063Sbostic 68*38028Sbostic if (!(buf = malloc((u_int)8 * 1024))) { 69*38028Sbostic (void)fprintf(stderr, "tee: out of space.\n"); 70*38028Sbostic exit(1); 711123Sbill } 72*38028Sbostic add(1, "stdout"); 73*38028Sbostic for (; *argv; ++argv) 74*38028Sbostic if ((fd = open(*argv, append ? O_WRONLY|O_CREAT : 75*38028Sbostic O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) 76*38028Sbostic (void)fprintf(stderr, "tee: %s: %s.\n", 77*38028Sbostic *argv, strerror(errno)); 7835063Sbostic else { 7935063Sbostic if (append) 80*38028Sbostic (void)lseek(fd, 0L, L_XTND); 81*38028Sbostic add(fd, *argv); 8225600Ssam } 83*38028Sbostic exitval = 0; 84*38028Sbostic while ((n = read(0, buf, sizeof(buf))) > 0) 85*38028Sbostic for (p = head; p; p = p->next) 86*38028Sbostic if (write(p->fd, buf, n) != n) { 87*38028Sbostic (void)fprintf(stderr, "tee: %s: %s.\n", 88*38028Sbostic p->name, strerror(errno)); 89*38028Sbostic exitval = 1; 90*38028Sbostic } 91*38028Sbostic if (n < 0) { 92*38028Sbostic (void)fprintf(stderr, "tee: read: %s\n", strerror(errno)); 93*38028Sbostic exit(1); 94*38028Sbostic } 95*38028Sbostic exit(exitval); 961123Sbill } 97*38028Sbostic 98*38028Sbostic add(fd, name) 99*38028Sbostic int fd; 100*38028Sbostic char *name; 101*38028Sbostic { 102*38028Sbostic LIST *p; 103*38028Sbostic char *malloc(), *strerror(); 104*38028Sbostic 105*38028Sbostic /* NOSTRICT */ 106*38028Sbostic if (!(p = (LIST *)malloc((u_int)sizeof(LIST)))) { 107*38028Sbostic (void)fprintf(stderr, "tee: out of space.\n"); 108*38028Sbostic exit(1); 109*38028Sbostic } 110*38028Sbostic p->fd = fd; 111*38028Sbostic p->name = name; 112*38028Sbostic p->next = head; 113*38028Sbostic head = p; 114*38028Sbostic } 115