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.11 (Berkeley) 05/06/91"; 16 #endif /* not lint */ 17 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 #include <fcntl.h> 21 #include <signal.h> 22 #include <unistd.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 27 typedef struct _list { 28 struct _list *next; 29 int fd; 30 char *name; 31 } LIST; 32 LIST *head; 33 34 main(argc, argv) 35 int argc; 36 char **argv; 37 { 38 extern int errno, optind; 39 register LIST *p; 40 register int n, fd, rval, wval; 41 register char *bp; 42 int append, ch, exitval; 43 char *buf; 44 off_t lseek(); 45 46 append = 0; 47 while ((ch = getopt(argc, argv, "ai")) != EOF) 48 switch((char)ch) { 49 case 'a': 50 append = 1; 51 break; 52 case 'i': 53 (void)signal(SIGINT, SIG_IGN); 54 break; 55 case '?': 56 default: 57 (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n"); 58 exit(1); 59 } 60 argv += optind; 61 argc -= optind; 62 63 if (!(buf = malloc((u_int)8 * 1024))) { 64 (void)fprintf(stderr, "tee: out of space.\n"); 65 exit(1); 66 } 67 add(STDOUT_FILENO, "stdout"); 68 for (; *argv; ++argv) 69 if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND : 70 O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0) 71 (void)fprintf(stderr, "tee: %s: %s.\n", 72 *argv, strerror(errno)); 73 else 74 add(fd, *argv); 75 exitval = 0; 76 while ((rval = read(STDIN_FILENO, buf, sizeof(buf))) > 0) 77 for (p = head; p; p = p->next) { 78 n = rval; 79 bp = buf; 80 do { 81 if ((wval = write(p->fd, bp, n)) == -1) { 82 (void)fprintf(stderr, "tee: %s: %s.\n", 83 p->name, strerror(errno)); 84 exitval = 1; 85 break; 86 } 87 bp += wval; 88 } while (n -= wval); 89 } 90 if (rval < 0) { 91 (void)fprintf(stderr, "tee: read: %s\n", strerror(errno)); 92 exit(1); 93 } 94 exit(exitval); 95 } 96 97 add(fd, name) 98 int fd; 99 char *name; 100 { 101 LIST *p; 102 103 if (!(p = malloc((u_int)sizeof(LIST)))) { 104 (void)fprintf(stderr, "tee: out of space.\n"); 105 exit(1); 106 } 107 p->fd = fd; 108 p->name = name; 109 p->next = head; 110 head = p; 111 } 112