1138593Ssam/* 2138593Ssam * Copyright (c) 1988, 1993 3138593Ssam * The Regents of the University of California. All rights reserved. 4138593Ssam * 5138593Ssam * Redistribution and use in source and binary forms, with or without 6138593Ssam * modification, are permitted provided that the following conditions 7138593Ssam * are met: 8138593Ssam * 1. Redistributions of source code must retain the above copyright 9138593Ssam * notice, this list of conditions and the following disclaimer. 10138593Ssam * 2. Redistributions in binary form must reproduce the above copyright 11138593Ssam * notice, this list of conditions and the following disclaimer in the 12138593Ssam * documentation and/or other materials provided with the distribution. 13138593Ssam * 4. Neither the name of the University nor the names of its contributors 14138593Ssam * may be used to endorse or promote products derived from this software 15138593Ssam * without specific prior written permission. 16138593Ssam * 17138593Ssam * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18138593Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19138593Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20138593Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21138593Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22138593Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23138593Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24138593Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25138593Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26138593Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27138593Ssam * SUCH DAMAGE. 28138593Ssam */ 29138593Ssam 30138593Ssam#ifndef lint 31138593Ssamstatic const char copyright[] = 32138593Ssam"@(#) Copyright (c) 1988, 1993\n\ 33138593Ssam The Regents of the University of California. All rights reserved.\n"; 34138593Ssam#endif /* not lint */ 35138593Ssam 36138593Ssam#ifndef lint 37138593Ssam#if 0 38138593Ssamstatic char sccsid[] = "@(#)tee.c 8.1 (Berkeley) 6/6/93"; 39138593Ssam#endif 40138593Ssamstatic const char rcsid[] = 41138593Ssam "$FreeBSD$"; 42138593Ssam#endif /* not lint */ 43138593Ssam 44138593Ssam#include <sys/types.h> 45166956Ssam#include <sys/stat.h> 46138593Ssam#include <err.h> 47138593Ssam#include <fcntl.h> 48138593Ssam#include <signal.h> 49138593Ssam#include <stdio.h> 50138593Ssam#include <stdlib.h> 51138593Ssam#include <string.h> 52138593Ssam#include <unistd.h> 53138593Ssam 54138593Ssamtypedef struct _list { 55191121Sbrooks struct _list *next; 56138593Ssam int fd; 57138593Ssam const char *name; 58138593Ssam} LIST; 59166956SsamLIST *head; 60138593Ssam 61138593Ssamvoid add(int, const char *); 62138593Ssamstatic void usage(void); 63138593Ssam 64138593Ssamint 65166956Ssammain(int argc, char *argv[]) 66138593Ssam{ 67138593Ssam LIST *p; 68138593Ssam int n, fd, rval, wval; 69138593Ssam char *bp; 70138593Ssam int append, ch, exitval; 71166956Ssam char *buf; 72166956Ssam#define BSIZE (8 * 1024) 73166956Ssam 74138593Ssam append = 0; 75138593Ssam while ((ch = getopt(argc, argv, "ai")) != -1) 76138593Ssam switch((char)ch) { 77138593Ssam case 'a': 78166956Ssam append = 1; 79166956Ssam break; 80138593Ssam case 'i': 81138593Ssam (void)signal(SIGINT, SIG_IGN); 82138593Ssam break; 83166956Ssam case '?': 84166956Ssam default: 85166956Ssam usage(); 86138593Ssam } 87138593Ssam argv += optind; 88138593Ssam argc -= optind; 89138593Ssam 90138593Ssam if ((buf = malloc(BSIZE)) == NULL) 91138593Ssam err(1, "malloc"); 92138593Ssam 93138593Ssam add(STDOUT_FILENO, "stdout"); 94138593Ssam 95138593Ssam for (exitval = 0; *argv; ++argv) 96138593Ssam if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND : 97138593Ssam O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0) { 98138593Ssam warn("%s", *argv); 99138593Ssam exitval = 1; 100138593Ssam } else 101138593Ssam add(fd, *argv); 102138593Ssam 103138593Ssam while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0) 104138593Ssam for (p = head; p; p = p->next) { 105138593Ssam n = rval; 106138593Ssam bp = buf; 107138593Ssam do { 108138593Ssam if ((wval = write(p->fd, bp, n)) == -1) { 109138593Ssam warn("%s", p->name); 110138593Ssam exitval = 1; 111138593Ssam break; 112138593Ssam } 113138593Ssam bp += wval; 114138593Ssam } while (n -= wval); 115138593Ssam } 116138593Ssam if (rval < 0) 117138593Ssam err(1, "read"); 118138593Ssam exit(exitval); 119138593Ssam} 120138593Ssam 121138593Ssamstatic void 122138593Ssamusage(void) 123138593Ssam{ 124138593Ssam (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n"); 125138593Ssam exit(1); 126138593Ssam} 127138593Ssam 128138593Ssamvoid 129138593Ssamadd(int fd, const char *name) 130138593Ssam{ 131138593Ssam LIST *p; 132138593Ssam 133138593Ssam if ((p = malloc(sizeof(LIST))) == NULL) 134138593Ssam err(1, "malloc"); 135138593Ssam p->fd = fd; 136138593Ssam p->name = name; 137138593Ssam p->next = head; 138138593Ssam head = p; 139138593Ssam} 140138593Ssam