home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / amiga / vim46src.lha / vim-4.6 / src / tee / tee.c < prev   
Encoding:
C/C++ Source or Header  |  1996-07-24  |  3.6 KB  |  154 lines

  1. /*  vim:set ts=4 sw=4:
  2.  *
  3.  *    Copyright (c) 1996, Paul Slootman
  4.  *
  5.  *    Author: Paul Slootman
  6.  *            (paul@wurtel.hobby.nl, paul@murphy.nl, paulS@toecompst.nl)
  7.  *
  8.  *    This source code is released into the public domain. It is provided on an
  9.  *    as-is basis and no responsibility is accepted for its failure to perform
  10.  *    as expected. It is worth at least as much as you paid for it!
  11.  *
  12.  * tee.c - pipe fitting
  13.  *
  14.  * tee reads stdin, and writes what it reads to each of the specified
  15.  * files. The primary reason of existence for this version is a quick
  16.  * and dirty implementation to distribute with Vim, to make one of the
  17.  * most useful features of Vim possible on OS/2: quickfix.
  18.  *
  19.  * Of course, not using tee but instead redirecting make's output directly
  20.  * into a temp file and then processing that is possible, but if we have a
  21.  * system capable of correctly piping (unlike DOS, for example), why not
  22.  * use it as well as possible? This tee should also work on other systems,
  23.  * but it's not been tested there, only on OS/2.
  24.  *
  25.  * tee is also available in the GNU shellutils package, which is available
  26.  * precompiled for OS/2. That one probably works better.
  27.  */
  28.  
  29. #include <unistd.h>
  30. #include <malloc.h>
  31. #include <stdio.h>
  32.  
  33. void usage(void)
  34. {
  35.     fprintf(stderr,
  36. "tee usage:\n\
  37. \ttee [-a] file ... file_n\n\
  38. \n\
  39. \t-a\tappend to files instead of truncating\n\
  40. \nTee reads its input, and writes to each of the specified files,\n\
  41. as well as to the standard output.\n\
  42. \n\
  43. This version supplied with Vim 4.2 to make ':make' possible.\n\
  44. For a more complete and stable version, consider getting\n\
  45. [a port of] the GNU shellutils package.\n\
  46. ");
  47. }
  48.  
  49. /*
  50.  * fread only returns when count is read or at EOF.
  51.  * We could use fgets, but I want to be able to handle binary blubber.
  52.  */
  53.  
  54. int
  55. myfread(char *buf, int elsize /*ignored*/, int max, FILE *fp)
  56. {
  57.     int    c;
  58.     int    n = 0;
  59.  
  60.     while ((n < max) && ((c = getchar()) != EOF))
  61.     {
  62.         *(buf++) = c;
  63.         n++;
  64.         if (c == '\n' || c == '\r')
  65.             break;
  66.     }
  67.     return n;
  68. }
  69.  
  70.  
  71. void
  72. main(int argc, char *argv[])
  73. {
  74.     int    append = 0;
  75.     int    numfiles;
  76.     int    opt;
  77.     int    maxfiles;
  78.     FILE    **filepointers;
  79.     int    i;
  80.     char    buf[BUFSIZ];
  81.     int    n;
  82.     extern int    optind;
  83.     
  84.     while ((opt = getopt(argc, argv, "a")) != EOF)
  85.     {
  86.         switch (opt)
  87.         {
  88.             case 'a':    append++;
  89.                     break;
  90.             default:    usage();
  91.                     exit(2);
  92.         }
  93.     }
  94.     
  95.     numfiles = argc - optind;
  96.     
  97.     if (numfiles == 0)
  98.     {
  99.         fprintf(stderr, "doesn't make much sense using tee without any file name arguments...\n");
  100.         usage();
  101.         exit(2);
  102.     }
  103.     
  104.     maxfiles = sysconf(_SC_OPEN_MAX);    /* or fill in 10 or so */
  105.     if (maxfiles < 0)
  106.         maxfiles = 10;
  107.     if (numfiles + 3 > maxfiles)    /* +3 accounts for stdin, out, err */
  108.     {
  109.         fprintf(stderr, "Sorry, there is a limit of max %d files.\n", maxfiles - 3);
  110.         exit(1);
  111.     }
  112.     filepointers = calloc(numfiles, sizeof(FILE *));
  113.     if (filepointers == NULL)
  114.     {
  115.         fprintf(stderr, "Error allocating memory for %d files\n", numfiles);
  116.         exit(1);
  117.     }
  118.     for (i = 0; i < numfiles; i++)
  119.     {
  120.         filepointers[i] = fopen(argv[i+optind], append ? "ab" : "wb");
  121.         if (filepointers[i] == NULL)
  122.         {
  123.             fprintf(stderr, "Can't open \"%s\"\n", argv[i+optind]);
  124.             exit(1);
  125.         }
  126.     }
  127.     _fsetmode(stdin,  "b");
  128.     fflush(stdout);    /* needed for _fsetmode(stdout) */
  129.     _fsetmode(stdout, "b");
  130.  
  131.     while ((n = myfread(buf, sizeof(char), sizeof(buf), stdin)) > 0)
  132.     {
  133.         fwrite(buf, sizeof(char), n, stdout);
  134.         fflush(stdout);
  135.         for (i = 0; i < numfiles; i++)
  136.         {
  137.             if (filepointers[i] &&
  138.                  fwrite(buf, sizeof(char), n, filepointers[i]) != n)
  139.             {
  140.                 fprintf(stderr, "Error writing to file \"%s\"\n", argv[i+optind]);
  141.                 fclose(filepointers[i]);
  142.                 filepointers[i] = NULL;
  143.             }
  144.         }
  145.     }
  146.     for (i = 0; i < numfiles; i++)
  147.     {
  148.         if (filepointers[i])
  149.             fclose(filepointers[i]);
  150.     }
  151.  
  152.     exit(0);
  153. }
  154.