ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/popen.c
Revision: 2.1
Committed: Tue Sep 8 09:08:02 1992 UTC (31 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# User Rev Content
1 greg 2.1 /* Copyright (c) 1992 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ 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 FILE *fopen();
31     extern char *malloc(), *mktemp(), *strcpy();
32     static int fnum = 0;
33     FILE *fp;
34     char *newcmd, *fname;
35     register char *cp, *cp2 = NULL;
36     int quote = '\0', paren = 0;
37    
38     fname = malloc(TEMPLEN+1);
39     newcmd = malloc(TEMPLEN+6+strlen(cmd));
40     if (fname == NULL | newcmd == NULL)
41     return(NULL);
42     mktemp(strcpy(fname,TEMPLATE));
43     /* build our command */
44     for (cp = newcmd; ; cmd++) {
45     switch (*cmd) {
46     case '"':
47     case '\'':
48     if (!quote)
49     quote = *cmd;
50     else if (quote == *cmd)
51     quote = '\0';
52     break;
53     case '(':
54     if (!quote)
55     paren++;
56     break;
57     case ')':
58     if (!quote && paren)
59     paren--;
60     break;
61     case '\\':
62     if (!quote && cmd[1] == '\n') {
63     *cp++ = ' ';
64     cmd++;
65     continue;
66     }
67     *cp++ = *cmd++;
68     break;
69     case '|':
70     case ';':
71     if (!quote && !paren && cp2 == NULL)
72     cp2 = fname;
73     break;
74     case '\n':
75     case '\0':
76     if (cp2 == NULL)
77     cp2 = fname;
78     break;
79     }
80     if (cp2 == fname && *mode == 'w') { /* add input file */
81     *cp++ = ' '; *cp++ = '<'; *cp++ = ' ';
82     while (*cp2)
83     *cp++ = *cp2++;
84     *cp++ = ' ';
85     }
86     if (!(*cp = *cmd))
87     break;
88     cp++;
89     }
90     if (*mode == 'r') { /* add output file */
91     while (isspace(cp[-1]) || cp[-1] == ';')
92     cp--;
93     *cp++ = ' '; *cp++ = '>'; *cp++ = ' ';
94     while (*cp2)
95     *cp++ = *cp2++;
96     *cp = '\0';
97     system(newcmd); /* execute command first */
98     }
99     if ((fp = fopen(fname, mode)) == NULL) { /* open file */
100     free(fname);
101     free(newcmd);
102     return(NULL);
103     }
104     if (fileno(fp) >= NFILE) {
105     fputs("popen: too many open files\n", stderr);
106     exit(1);
107     }
108     pips[fileno(fp)].f = fname;
109     if (*mode == 'r') {
110     free(newcmd);
111     pips[fileno(fp)].c = NULL;
112     } else
113     pips[fileno(fp)].c = newcmd;
114     return(fp);
115     }
116    
117    
118     pclose(fp) /* close pipe and cleanup */
119     FILE *fp;
120     {
121     register int pn = fileno(fp);
122    
123     if (pn >= NFILE || pips[pn].f == NULL || fclose(fp) == -1)
124     return(-1);
125     if (pips[pn].c != NULL) {
126     system(pips[pn].c); /* execute command last */
127     free(pips[pn].c);
128     }
129     unlink(pips[pn].f); /* remove temp file */
130     free(pips[pn].f);
131     pips[pn].f = NULL;
132     return(0);
133     }