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 1538028Sbostic * 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*38580Sbostic static char sccsid[] = "@(#)tee.c 5.7 (Berkeley) 08/10/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 3338028Sbostic typedef struct _list { 3438028Sbostic struct _list *next; 3538028Sbostic int fd; 3638028Sbostic char *name; 3738028Sbostic } LIST; 3838028Sbostic LIST *head; 3938028Sbostic 4035063Sbostic main(argc, argv) 4135063Sbostic int argc; 4235063Sbostic char **argv; 4335063Sbostic { 4438028Sbostic extern int errno, optind; 4538028Sbostic register LIST *p; 4638028Sbostic register int append, n, fd; 4738028Sbostic int ch, exitval; 4838028Sbostic 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: 6238028Sbostic (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n"); 6338028Sbostic exit(1); 641123Sbill } 6535063Sbostic argv += optind; 6635063Sbostic argc -= optind; 6735063Sbostic 6838028Sbostic if (!(buf = malloc((u_int)8 * 1024))) { 6938028Sbostic (void)fprintf(stderr, "tee: out of space.\n"); 7038028Sbostic exit(1); 711123Sbill } 7238028Sbostic add(1, "stdout"); 7338028Sbostic for (; *argv; ++argv) 74*38580Sbostic if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND : 7538028Sbostic O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) 7638028Sbostic (void)fprintf(stderr, "tee: %s: %s.\n", 7738028Sbostic *argv, strerror(errno)); 78*38580Sbostic else 7938028Sbostic add(fd, *argv); 8038028Sbostic exitval = 0; 8138028Sbostic while ((n = read(0, buf, sizeof(buf))) > 0) 8238028Sbostic for (p = head; p; p = p->next) 8338028Sbostic if (write(p->fd, buf, n) != n) { 8438028Sbostic (void)fprintf(stderr, "tee: %s: %s.\n", 8538028Sbostic p->name, strerror(errno)); 8638028Sbostic exitval = 1; 8738028Sbostic } 8838028Sbostic if (n < 0) { 8938028Sbostic (void)fprintf(stderr, "tee: read: %s\n", strerror(errno)); 9038028Sbostic exit(1); 9138028Sbostic } 9238028Sbostic exit(exitval); 931123Sbill } 9438028Sbostic 9538028Sbostic add(fd, name) 9638028Sbostic int fd; 9738028Sbostic char *name; 9838028Sbostic { 9938028Sbostic LIST *p; 10038028Sbostic char *malloc(), *strerror(); 10138028Sbostic 10238028Sbostic /* NOSTRICT */ 10338028Sbostic if (!(p = (LIST *)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