ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/popen.c
Revision: 2.3
Committed: Tue Sep 29 09:25:54 1992 UTC (31 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +4 -2 lines
Log Message:
minor changes

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 greg 2.2 case '\'':
47 greg 2.1 case '"':
48     if (!quote)
49     quote = *cmd;
50     else if (quote == *cmd)
51     quote = '\0';
52 greg 2.2 #ifdef MSDOS
53     else
54     break;
55     *cp++ = '"'; /* double quotes only */
56     continue;
57     #else
58 greg 2.1 break;
59 greg 2.2 #endif
60 greg 2.3 #ifndef MSDOS
61 greg 2.1 case '(':
62     if (!quote)
63     paren++;
64     break;
65     case ')':
66     if (!quote && paren)
67     paren--;
68     break;
69     case '\\':
70     if (!quote && cmd[1] == '\n') {
71     *cp++ = ' ';
72     cmd++;
73     continue;
74     }
75     *cp++ = *cmd++;
76 greg 2.2 break;
77 greg 2.3 #endif
78 greg 2.2 case ' ':
79     case '\t':
80     if (!quote)
81     while (isspace(cmd[1]))
82     cmd++;
83 greg 2.1 break;
84     case '|':
85     case ';':
86     if (!quote && !paren && cp2 == NULL)
87     cp2 = fname;
88     break;
89     case '\n':
90     case '\0':
91     if (cp2 == NULL)
92     cp2 = fname;
93     break;
94     }
95     if (cp2 == fname && *mode == 'w') { /* add input file */
96     *cp++ = ' '; *cp++ = '<'; *cp++ = ' ';
97     while (*cp2)
98     *cp++ = *cp2++;
99     *cp++ = ' ';
100     }
101     if (!(*cp = *cmd))
102     break;
103     cp++;
104     }
105     if (*mode == 'r') { /* add output file */
106     while (isspace(cp[-1]) || cp[-1] == ';')
107     cp--;
108     *cp++ = ' '; *cp++ = '>'; *cp++ = ' ';
109     while (*cp2)
110     *cp++ = *cp2++;
111     *cp = '\0';
112     system(newcmd); /* execute command first */
113     }
114     if ((fp = fopen(fname, mode)) == NULL) { /* open file */
115     free(fname);
116     free(newcmd);
117     return(NULL);
118     }
119     if (fileno(fp) >= NFILE) {
120 greg 2.3 eputs("popen: too many open files\n");
121     quit(1);
122 greg 2.1 }
123     pips[fileno(fp)].f = fname;
124     if (*mode == 'r') {
125     free(newcmd);
126     pips[fileno(fp)].c = NULL;
127     } else
128     pips[fileno(fp)].c = newcmd;
129     return(fp);
130     }
131    
132    
133     pclose(fp) /* close pipe and cleanup */
134     FILE *fp;
135     {
136     register int pn = fileno(fp);
137    
138     if (pn >= NFILE || pips[pn].f == NULL || fclose(fp) == -1)
139     return(-1);
140     if (pips[pn].c != NULL) {
141     system(pips[pn].c); /* execute command last */
142     free(pips[pn].c);
143     }
144     unlink(pips[pn].f); /* remove temp file */
145     free(pips[pn].f);
146     pips[pn].f = NULL;
147     return(0);
148     }