home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / COMMON / POPEN.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  3KB  |  152 lines

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)popen.c 2.4 11/4/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  * popen() and pclose() calls for systems without pipe facilities
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include "paths.h"
  14.  
  15. #ifndef NFILE
  16. #define NFILE        32
  17. #endif
  18.  
  19. static struct {
  20.     char    *f;        /* file name, NULL if inactive */
  21.     char    *c;        /* command if writing */
  22. } pips[NFILE];
  23.  
  24.  
  25. FILE *
  26. popen(cmd, mode)        /* open command for reading or writing */
  27. register char    *cmd;
  28. char    *mode;
  29. {
  30.     extern char    *malloc(), *strcpy();
  31.     FILE    *fp;
  32.     char    *newcmd, *fname;
  33.     register char    *cp, *cp2 = NULL;
  34.     int    quote = '\0', paren = 0;
  35.     
  36.     while (isspace(*cmd))
  37.         cmd++;
  38.     if (!*cmd)
  39.         return(NULL);
  40.     fname = malloc(TEMPLEN+1);
  41.     newcmd = malloc(TEMPLEN+6+strlen(cmd));
  42.     if (fname == NULL | newcmd == NULL)
  43.         return(NULL);
  44.     mktemp(strcpy(fname,TEMPLATE));
  45.                 /* build our command */
  46.     for (cp = newcmd; ; cmd++) {
  47.         switch (*cmd) {
  48.         case '\'':
  49.         case '"':
  50.             if (!quote)
  51.                 quote = *cmd;
  52.             else if (quote == *cmd)
  53.                 quote = '\0';
  54. #ifdef MSDOS
  55.             else
  56.                 break;
  57.             *cp++ = '"';        /* double quotes only */
  58.             continue;
  59.         case '\\':
  60.             if (!quote && cmd[1] == '\n') {
  61.                 *cp++ = ' ';
  62.                 cmd++;
  63.                 continue;
  64.             }
  65.             cmd++;
  66.             break;
  67. #else
  68.             break;
  69.         case '\\':
  70.             *cp++ = *cmd++;
  71.             break;
  72.         case '(':
  73.             if (!quote)
  74.                 paren++;
  75.             break;
  76.         case ')':
  77.             if (!quote && paren)
  78.                 paren--;
  79.             break;
  80.         case ';':
  81. #endif
  82.         case '|':
  83.             if (!quote && !paren && cp2 == NULL)
  84.                 cp2 = fname;
  85.             break;
  86.         case ' ':
  87.         case '\t':
  88.             if (!quote)
  89.                 while (isspace(cmd[1]))
  90.                     cmd++;
  91.             break;
  92.         case '\n':
  93.         case '\0':
  94.             if (cp2 == NULL)
  95.                 cp2 = fname;
  96.             break;
  97.         }
  98.         if (cp2 == fname && *mode == 'w') {    /* add input file */
  99.             *cp++ = ' '; *cp++ = '<';
  100.             while (*cp2)
  101.                 *cp++ = *cp2++;
  102.             *cp++ = ' ';
  103.         }
  104.         if (!(*cp = *cmd))
  105.             break;
  106.         cp++;
  107.     }
  108.     if (*mode == 'r') {            /* add output file */
  109.         while (isspace(cp[-1]) || cp[-1] == ';')
  110.             cp--;
  111.         *cp++ = ' '; *cp++ = '>';
  112.         while (*cp2)
  113.             *cp++ = *cp2++;
  114.         *cp = '\0';
  115.         system(newcmd);            /* execute command first */
  116.     }
  117.     if ((fp = fopen(fname, mode)) == NULL) {    /* open file */
  118.         free(fname);
  119.         free(newcmd);
  120.         return(NULL);
  121.     }
  122.     if (fileno(fp) >= NFILE) {
  123.         eputs("popen: too many open files\n");
  124.         quit(1);
  125.     }
  126.     pips[fileno(fp)].f = fname;
  127.     if (*mode == 'r') {
  128.         free(newcmd);
  129.         pips[fileno(fp)].c = NULL;
  130.     } else
  131.         pips[fileno(fp)].c = newcmd;
  132.     return(fp);
  133. }
  134.  
  135.  
  136. pclose(fp)            /* close pipe and cleanup */
  137. FILE    *fp;
  138. {
  139.     register int    pn = fileno(fp);
  140.  
  141.     if (pn >= NFILE || pips[pn].f == NULL || fclose(fp) == -1)
  142.         return(-1);
  143.     if (pips[pn].c != NULL) {
  144.         system(pips[pn].c);        /* execute command last */
  145.         free(pips[pn].c);
  146.     }
  147.     unlink(pips[pn].f);        /* remove temp file */
  148.     free(pips[pn].f);
  149.     pips[pn].f = NULL;
  150.     return(0);
  151. }
  152.