home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / unix / unixtools / util / c / popen < prev    next >
Text File  |  1992-07-21  |  3KB  |  188 lines

  1. /* C.Popen: Simulation of pipes */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "utils.h"
  7.  
  8. #define MAX_PIPE 20
  9.  
  10. typedef enum
  11. {
  12.     unopened = 0,
  13.     reading,
  14.     writing
  15. }
  16. pipemode;
  17.  
  18. static struct pipe
  19. {
  20.     char *command;    /* The command being executed    */
  21.     char *name;    /* The name of the pipe file    */
  22.     FILE *fd;    /* The file used as a pipe    */
  23.     pipemode pmode;    /* The open mode of the pipe    */
  24. }
  25. pipes[MAX_PIPE];
  26.  
  27. FILE *popen (char *command, char *mode)
  28. {
  29.     FILE *current;
  30.     char *name;
  31.     int i;
  32.     pipemode curmode;
  33.     char tmp[11];
  34.  
  35.     /* decide on mode */
  36.     if ( mode[1] != 0 )
  37.         return NULL;
  38.     else if ( *mode == 'r' )
  39.         curmode = reading;
  40.     else if ( *mode == 'w' )
  41.         curmode = writing;
  42.     else
  43.         return NULL;
  44.  
  45.     /* Get a slot in thbe pipes structure */
  46.     for ( i = 0; i < MAX_PIPE; ++i )
  47.     {
  48.         if ( pipes[i].pmode == unopened )
  49.             break;
  50.     }
  51.  
  52.     if ( i >= MAX_PIPE )
  53.         return NULL;
  54.  
  55.     /* Get a file name to use */
  56.     sprintf(tmp, "Pipe%.2d", i);
  57.     name = mktemp(tmp);
  58.  
  59.     if ( name == NULL )
  60.         return NULL;
  61.  
  62.     /*
  63.      * If we're reading, just call system() to get a file filled
  64.      * with output.
  65.      */
  66.  
  67.     if ( curmode == reading )
  68.     {
  69.         char cmd[256];
  70.         char *p;
  71.         char *q;
  72.         char *p1 = 0;
  73.  
  74.         for (p = command, q = cmd; *p;)
  75.         {
  76.             /* Replace '%o' with output filename */
  77.             if (*p == '%' && p[1] == 'o')
  78.             {
  79.                 for (p1 = name; *p1;)
  80.                     *q++ = *p1++;
  81.                 p += 2;
  82.             }
  83.             else
  84.                 *q++ = *p++;
  85.         }
  86.  
  87.         /* If there was no '%o', append '>pipe' */
  88.         if (p1 == 0)
  89.         {
  90.             *q++ = ' ';
  91.             *q++ = '>';
  92.             for (p1 = name; *p1;)
  93.                 *q++ = *p1++;
  94.         }
  95.  
  96.         /* Terminate the string */
  97.         *q = 0;
  98.  
  99.         system(cmd);
  100.  
  101.         if ( (current = fopen(name,"r")) == NULL )
  102.             return NULL;
  103.     }
  104.     else
  105.     {
  106.         if ( (current = fopen(name,"w")) == NULL )
  107.             return NULL;
  108.     }
  109.  
  110.     pipes[i].command = strdup(command);
  111.     pipes[i].name = name;
  112.     pipes[i].fd = current;
  113.     pipes[i].pmode = curmode;
  114.     return current;
  115. }
  116.  
  117. int pclose (FILE *current)
  118. {
  119.     int rval;
  120.     int i;
  121.  
  122.     /* Get the appropriate slot in thbe pipes structure */
  123.     for ( i = 0; i < MAX_PIPE; ++i )
  124.     {
  125.         if ( pipes[i].fd == current )
  126.             break;
  127.     }
  128.  
  129.     if ( i >= MAX_PIPE )
  130.         return -1;
  131.  
  132.     if ( pipes[i].pmode == reading )
  133.     {
  134.         /* Input pipes are just files we're done with */
  135.         rval = fclose(current);
  136.         remove(pipes[i].name);
  137.     }
  138.     else
  139.     {
  140.         /*
  141.          * Output pipes are temporary files we have
  142.          * to cram down the throats of programs.
  143.          */
  144.         char command[256];
  145.         char *p1 = 0;
  146.         char *p;
  147.         char *q;
  148.  
  149.         /* Close the pipe file */
  150.         fclose(current);
  151.  
  152.         /* Create the required command string */
  153.         for (p = pipes[i].command, q = command; *p;)
  154.         {
  155.                 /* Replace '%i' with the pipe filename */
  156.                 if (*p == '%' && p[1] == 'i')
  157.                 {
  158.                 for (p1 = pipes[i].name; *p1;)
  159.                     *q++ = *p1++;
  160.                 p += 2;
  161.             }
  162.             else
  163.                 *q++ = *p++;
  164.         }
  165.  
  166.         /* If there was no '%i', append '<pipe' */
  167.         if (p1 == 0)
  168.         {
  169.             *q++ = ' ';
  170.             *q++ = '<';
  171.             for (p1 = pipes[i].name; *p1;)
  172.                 *q++ = *p1++;
  173.         }
  174.  
  175.         /* Terminate the string */
  176.         *q = 0;
  177.  
  178.         rval = system(command);
  179.         remove(pipes[i].name);
  180.     }
  181.  
  182.     /* clean up current pipe */
  183.     pipes[i].pmode = unopened;
  184.     free(pipes[i].name);
  185.     free(pipes[i].command);
  186.     return rval;
  187. }
  188.