home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / tee.zip / tee.c < prev    next >
C/C++ Source or Header  |  1996-03-08  |  5KB  |  197 lines

  1. /* 
  2.    Changed a bit to be compiled under OS/2 using emx+gcc. Also -c option
  3.    added (don't create output files if there was nothing to read from
  4.    stdin).                    -- D.Maloff (maloff@tts.magadan.su), 1996 
  5. */
  6.  
  7. /*
  8.  * Copyright (c) 1988, 1993
  9.  *    The Regents of the University of California.  All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms, with or without
  12.  * modification, are permitted provided that the following conditions
  13.  * are met:
  14.  * 1. Redistributions of source code must retain the above copyright
  15.  *    notice, this list of conditions and the following disclaimer.
  16.  * 2. Redistributions in binary form must reproduce the above copyright
  17.  *    notice, this list of conditions and the following disclaimer in the
  18.  *    documentation and/or other materials provided with the distribution.
  19.  * 3. All advertising materials mentioning features or use of this software
  20.  *    must display the following acknowledgement:
  21.  *    This product includes software developed by the University of
  22.  *    California, Berkeley and its contributors.
  23.  * 4. Neither the name of the University nor the names of its contributors
  24.  *    may be used to endorse or promote products derived from this software
  25.  *    without specific prior written permission.
  26.  *
  27.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  28.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  31.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  33.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  34.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  36.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  37.  * SUCH DAMAGE.
  38.  */
  39.  
  40. #ifndef lint
  41. static char copyright[] =
  42. "@(#) Copyright (c) 1988, 1993\n\
  43.     The Regents of the University of California.  All rights reserved.\n";
  44. #endif /* not lint */
  45.  
  46. #ifndef lint
  47. static char sccsid[] = "@(#)tee.c    8.1 (Berkeley) 6/6/93";
  48. #endif /* not lint */
  49.  
  50. #include <sys/types.h>
  51. #include <sys/stat.h>
  52. #include <signal.h>
  53. #include <errno.h>
  54. #include <fcntl.h>
  55. #include <unistd.h>
  56. #include <stdio.h>
  57. #include <stdlib.h>
  58. #include <string.h>
  59.  
  60. #ifdef __EMX__ 
  61.     #define __P(x) x
  62.     #define DEFFILEMODE 0666
  63. #endif
  64.  
  65. typedef struct _list {
  66.     struct _list *next;
  67.     int fd;
  68.     char *name;
  69. } LIST;
  70. LIST *head;
  71.  
  72. int  append, create, exitval, opened = 0;
  73.  
  74. void add __P((int, char *));
  75. void err __P((int, const char *, ...));
  76. void openargs __P((char **));
  77.  
  78. int
  79. main(argc, argv)
  80.     int argc;
  81.     char *argv[];
  82. {
  83.     register LIST *p;
  84.     register int n, rval, wval;
  85.     register char *bp;
  86.     int ch;
  87.     char *buf;
  88. #define    BSIZE (8 * 1024)
  89.  
  90.     append = 0;
  91.     while ((ch = getopt(argc, argv, "aci")) != EOF)
  92.         switch((char)ch) {
  93.         case 'a':
  94.             append = 1;
  95.             break;
  96.         case 'c':
  97.             create = 1;
  98.             break;
  99.         case 'i':
  100.             (void)signal(SIGINT, SIG_IGN);
  101.             break;
  102.         case '?':
  103.         default:
  104.             (void)fprintf(stderr, "usage: tee [-aci] [file ...]\n");
  105.             exit(1);
  106.         }
  107.     argv += optind;
  108.     argc -= optind;
  109.  
  110.     if ((buf = malloc((u_int)BSIZE)) == NULL)
  111.         err(1, "%s", strerror(errno));
  112.  
  113.     add(STDOUT_FILENO, "stdout");
  114.  
  115.     if(!create) openargs(argv);
  116.  
  117.     while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0) {
  118.         if(!opened && create) openargs(argv);
  119.         for (p = head; p; p = p->next) {
  120.             n = rval;
  121.             bp = buf;
  122.             do {
  123.                 if ((wval = write(p->fd, bp, n)) == -1) {
  124.                     err(0, "%s: %s",
  125.                         p->name, strerror(errno));
  126.                     exitval = 1;
  127.                     break;
  128.                 }
  129.                 bp += wval;
  130.             } while (n -= wval);
  131.         }
  132.     }
  133.     if (rval < 0)
  134.         err(1, "read: %s", strerror(errno));
  135.     exit(exitval);
  136. }
  137.  
  138. void
  139. openargs(argv)
  140.     char *argv[];
  141. {
  142.     int fd;
  143.     for (exitval = 0; *argv; ++argv)
  144.         if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND :
  145.             O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0) {
  146.             err(0, "%s: %s", *argv, strerror(errno));
  147.             exitval = 1;
  148.         } else
  149.             add(fd, *argv);
  150.     opened = 1;
  151. }
  152.  
  153. void
  154. add(fd, name)
  155.     int fd;
  156.     char *name;
  157. {
  158.     LIST *p;
  159.  
  160.     if ((p = malloc((u_int)sizeof(LIST))) == NULL)
  161.         err(1, "%s", strerror(errno));
  162.     p->fd = fd;
  163.     p->name = name;
  164.     p->next = head;
  165.     head = p;
  166. }
  167.  
  168. #if __STDC__
  169. #include <stdarg.h>
  170. #else
  171. #include <varargs.h>
  172. #endif
  173.  
  174. void
  175. #if __STDC__
  176. err(int doexit, const char *fmt, ...)
  177. #else
  178. err(doexit, fmt, va_alist)
  179.     int doexit;
  180.     char *fmt;
  181.         va_dcl
  182. #endif
  183. {
  184.     va_list ap;
  185. #if __STDC__
  186.     va_start(ap, fmt);
  187. #else
  188.     va_start(ap);
  189. #endif
  190.     (void)fprintf(stderr, "tee: ");
  191.     (void)vfprintf(stderr, fmt, ap);
  192.     va_end(ap);
  193.     (void)fprintf(stderr, "\n");
  194.     if (doexit)
  195.         exit(1);
  196. }
  197.