ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/popen.c
Revision: 2.6
Committed: Tue Feb 25 02:47:21 2003 UTC (21 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6P1, rad3R5, rad3R6
Changes since 2.5: +1 -56 lines
Log Message:
Replaced inline copyright notice with #include "copyright.h"

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 /*
5 * popen() and pclose() calls for systems without pipe facilities
6 */
7
8 #include "copyright.h"
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include "paths.h"
15
16 #ifndef NFILE
17 #define NFILE 32
18 #endif
19
20 static struct {
21 char *f; /* file name, NULL if inactive */
22 char *c; /* command if writing */
23 } pips[NFILE];
24
25
26 FILE *
27 popen(cmd, mode) /* open command for reading or writing */
28 register char *cmd;
29 char *mode;
30 {
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 = (char *)malloc(TEMPLEN+1);
41 newcmd = (char *)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 }