|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1988 Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)tee.c 5.10 (Berkeley) 6/1/90"; ! 28: #endif /* not lint */ ! 29: ! 30: #include <sys/types.h> ! 31: #include <sys/file.h> ! 32: #include <signal.h> ! 33: #include <stdio.h> ! 34: #include <unistd.h> ! 35: ! 36: typedef struct _list { ! 37: struct _list *next; ! 38: int fd; ! 39: char *name; ! 40: } LIST; ! 41: LIST *head; ! 42: ! 43: main(argc, argv) ! 44: int argc; ! 45: char **argv; ! 46: { ! 47: extern int errno, optind; ! 48: register LIST *p; ! 49: register int n, fd, rval, wval; ! 50: register char *bp; ! 51: int append, ch, exitval; ! 52: char *buf, *malloc(), *strerror(); ! 53: off_t lseek(); ! 54: ! 55: append = 0; ! 56: while ((ch = getopt(argc, argv, "ai")) != EOF) ! 57: switch((char)ch) { ! 58: case 'a': ! 59: append = 1; ! 60: break; ! 61: case 'i': ! 62: (void)signal(SIGINT, SIG_IGN); ! 63: break; ! 64: case '?': ! 65: default: ! 66: (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n"); ! 67: exit(1); ! 68: } ! 69: argv += optind; ! 70: argc -= optind; ! 71: ! 72: if (!(buf = malloc((u_int)8 * 1024))) { ! 73: (void)fprintf(stderr, "tee: out of space.\n"); ! 74: exit(1); ! 75: } ! 76: add(STDOUT_FILENO, "stdout"); ! 77: for (; *argv; ++argv) ! 78: if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND : ! 79: O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) ! 80: (void)fprintf(stderr, "tee: %s: %s.\n", ! 81: *argv, strerror(errno)); ! 82: else ! 83: add(fd, *argv); ! 84: exitval = 0; ! 85: while ((rval = read(STDIN_FILENO, buf, sizeof(buf))) > 0) ! 86: for (p = head; p; p = p->next) { ! 87: n = rval; ! 88: bp = buf; ! 89: do { ! 90: if ((wval = write(p->fd, bp, n)) == -1) { ! 91: (void)fprintf(stderr, "tee: %s: %s.\n", ! 92: p->name, strerror(errno)); ! 93: exitval = 1; ! 94: break; ! 95: } ! 96: bp += wval; ! 97: } while (n -= wval); ! 98: } ! 99: if (rval < 0) { ! 100: (void)fprintf(stderr, "tee: read: %s\n", strerror(errno)); ! 101: exit(1); ! 102: } ! 103: exit(exitval); ! 104: } ! 105: ! 106: add(fd, name) ! 107: int fd; ! 108: char *name; ! 109: { ! 110: LIST *p; ! 111: char *malloc(), *strerror(); ! 112: ! 113: /* NOSTRICT */ ! 114: if (!(p = (LIST *)malloc((u_int)sizeof(LIST)))) { ! 115: (void)fprintf(stderr, "tee: out of space.\n"); ! 116: exit(1); ! 117: } ! 118: p->fd = fd; ! 119: p->name = name; ! 120: p->next = head; ! 121: head = p; ! 122: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.