tee.c revision 28199
1168404Spjd/* 2168404Spjd * Copyright (c) 1988, 1993 3168404Spjd * The Regents of the University of California. All rights reserved. 4168404Spjd * 5168404Spjd * Redistribution and use in source and binary forms, with or without 6168404Spjd * modification, are permitted provided that the following conditions 7168404Spjd * are met: 8168404Spjd * 1. Redistributions of source code must retain the above copyright 9168404Spjd * notice, this list of conditions and the following disclaimer. 10168404Spjd * 2. Redistributions in binary form must reproduce the above copyright 11168404Spjd * notice, this list of conditions and the following disclaimer in the 12168404Spjd * documentation and/or other materials provided with the distribution. 13168404Spjd * 3. All advertising materials mentioning features or use of this software 14168404Spjd * must display the following acknowledgement: 15168404Spjd * This product includes software developed by the University of 16168404Spjd * California, Berkeley and its contributors. 17168404Spjd * 4. Neither the name of the University nor the names of its contributors 18168404Spjd * may be used to endorse or promote products derived from this software 19168404Spjd * without specific prior written permission. 20168404Spjd * 21168404Spjd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22219089Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23229565Smm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24229565Smm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25168404Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26168404Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27168404Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28168404Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29168404Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30168404Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31168404Spjd * SUCH DAMAGE. 32168404Spjd */ 33219089Spjd 34185029Spjd#ifndef lint 35185029Spjdstatic const char copyright[] = 36168404Spjd"@(#) Copyright (c) 1988, 1993\n\ 37168404Spjd The Regents of the University of California. All rights reserved.\n"; 38168404Spjd#endif /* not lint */ 39168404Spjd 40168404Spjd#ifndef lint 41168404Spjd#if 0 42219089Spjdstatic char sccsid[] = "@(#)tee.c 8.1 (Berkeley) 6/6/93"; 43168404Spjd#endif 44168404Spjdstatic const char rcsid[] = 45168404Spjd "$Id$"; 46168404Spjd#endif /* not lint */ 47168404Spjd 48168404Spjd#include <sys/types.h> 49168404Spjd#include <sys/stat.h> 50168404Spjd#include <err.h> 51185029Spjd#include <fcntl.h> 52185029Spjd#include <signal.h> 53185029Spjd#include <stdio.h> 54185029Spjd#include <stdlib.h> 55185029Spjd#include <string.h> 56185029Spjd#include <unistd.h> 57209962Smm 58185029Spjdtypedef struct _list { 59168404Spjd struct _list *next; 60224174Smm int fd; 61168404Spjd char *name; 62185029Spjd} LIST; 63185029SpjdLIST *head; 64185029Spjd 65168404Spjdvoid add __P((int, char *)); 66185029Spjdstatic void usage __P((void)); 67185029Spjd 68185029Spjdint 69168404Spjdmain(argc, argv) 70168404Spjd int argc; 71168404Spjd char *argv[]; 72168404Spjd{ 73168404Spjd register LIST *p; 74185029Spjd register int n, fd, rval, wval; 75185029Spjd register char *bp; 76209962Smm int append, ch, exitval; 77219089Spjd char *buf; 78185029Spjd#define BSIZE (8 * 1024) 79209962Smm 80209962Smm append = 0; 81209962Smm while ((ch = getopt(argc, argv, "ai")) != -1) 82209962Smm switch((char)ch) { 83219089Spjd case 'a': 84219089Spjd append = 1; 85168404Spjd break; 86168404Spjd case 'i': 87168404Spjd (void)signal(SIGINT, SIG_IGN); 88168404Spjd break; 89168404Spjd case '?': 90185029Spjd default: 91185029Spjd usage(); 92185029Spjd } 93185029Spjd argv += optind; 94185029Spjd argc -= optind; 95185029Spjd 96185029Spjd if ((buf = malloc((u_int)BSIZE)) == NULL) 97168404Spjd errx(1, "malloc"); 98185029Spjd 99168404Spjd add(STDOUT_FILENO, "stdout"); 100168404Spjd 101168404Spjd for (exitval = 0; *argv; ++argv) 102185029Spjd if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND : 103168404Spjd O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0) { 104168404Spjd warn("%s", *argv); 105168404Spjd exitval = 1; 106168404Spjd } else 107168404Spjd add(fd, *argv); 108168404Spjd 109168404Spjd while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0) 110168404Spjd for (p = head; p; p = p->next) { 111168404Spjd n = rval; 112185029Spjd bp = buf; 113185029Spjd do { 114185029Spjd if ((wval = write(p->fd, bp, n)) == -1) { 115185029Spjd warn("%s", p->name); 116185029Spjd exitval = 1; 117185029Spjd break; 118185029Spjd } 119185029Spjd bp += wval; 120185029Spjd } while (n -= wval); 121185029Spjd } 122185029Spjd if (rval < 0) 123185029Spjd err(1, "read"); 124185029Spjd exit(exitval); 125185029Spjd} 126185029Spjd 127185029Spjdstatic void 128168404Spjdusage() 129168404Spjd{ 130168404Spjd (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n"); 131168404Spjd exit(1); 132168404Spjd} 133168404Spjd 134168404Spjdvoid 135168404Spjdadd(fd, name) 136168404Spjd int fd; 137185029Spjd char *name; 138185029Spjd{ 139185029Spjd LIST *p; 140219089Spjd 141219089Spjd if ((p = malloc((u_int)sizeof(LIST))) == NULL) 142209962Smm errx(1, "malloc"); 143209962Smm p->fd = fd; 144209962Smm p->name = name; 145209962Smm p->next = head; 146209962Smm head = p; 147209962Smm} 148219089Spjd