ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/popen.c
Revision: 2.4
Committed: Wed Nov 4 12:59:17 1992 UTC (31 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.3: +23 -20 lines
Log Message:
bug fixes for MSDOS

File Contents

# Content
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 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 }