1 /* 2 * Copyright (c) 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1988 Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)tee.c 5.13 (Berkeley) 12/16/91"; 16 #endif /* not lint */ 17 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 #include <signal.h> 21 #include <errno.h> 22 #include <fcntl.h> 23 #include <unistd.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 28 typedef struct _list { 29 struct _list *next; 30 int fd; 31 char *name; 32 } LIST; 33 LIST *head; 34 35 void add __P((int, char *)); 36 void err __P((int, const char *, ...)); 37 38 int 39 main(argc, argv) 40 int argc; 41 char *argv[]; 42 { 43 register LIST *p; 44 register int n, fd, rval, wval; 45 register char *bp; 46 int append, ch, exitval; 47 char *buf; 48 #define BSIZE (8 * 1024) 49 50 append = 0; 51 while ((ch = getopt(argc, argv, "ai")) != EOF) 52 switch((char)ch) { 53 case 'a': 54 append = 1; 55 break; 56 case 'i': 57 (void)signal(SIGINT, SIG_IGN); 58 break; 59 case '?': 60 default: 61 (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n"); 62 exit(1); 63 } 64 argv += optind; 65 argc -= optind; 66 67 if ((buf = malloc((u_int)BSIZE)) == NULL) 68 err(1, "%s", strerror(errno)); 69 70 add(STDOUT_FILENO, "stdout"); 71 72 for (exitval = 0; *argv; ++argv) 73 if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND : 74 O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0) { 75 err(0, "%s: %s", *argv, strerror(errno)); 76 exitval = 1; 77 } else 78 add(fd, *argv); 79 80 while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0) 81 for (p = head; p; p = p->next) { 82 n = rval; 83 bp = buf; 84 do { 85 if ((wval = write(p->fd, bp, n)) == -1) { 86 err(0, "%s: %s", 87 p->name, strerror(errno)); 88 exitval = 1; 89 break; 90 } 91 bp += wval; 92 } while (n -= wval); 93 } 94 if (rval < 0) 95 err(1, "read: %s", strerror(errno)); 96 exit(exitval); 97 } 98 99 void 100 add(fd, name) 101 int fd; 102 char *name; 103 { 104 LIST *p; 105 106 if ((p = malloc((u_int)sizeof(LIST))) == NULL) 107 err(1, "%s", strerror(errno)); 108 p->fd = fd; 109 p->name = name; 110 p->next = head; 111 head = p; 112 } 113 114 #if __STDC__ 115 #include <stdarg.h> 116 #else 117 #include <varargs.h> 118 #endif 119 120 void 121 #if __STDC__ 122 err(int doexit, const char *fmt, ...) 123 #else 124 err(doexit, fmt, va_alist) 125 int doexit; 126 char *fmt; 127 va_dcl 128 #endif 129 { 130 va_list ap; 131 #if __STDC__ 132 va_start(ap, fmt); 133 #else 134 va_start(ap); 135 #endif 136 (void)fprintf(stderr, "tee: "); 137 (void)vfprintf(stderr, fmt, ap); 138 va_end(ap); 139 (void)fprintf(stderr, "\n"); 140 if (doexit) 141 exit(1); 142 } 143