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

# 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 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 #ifdef MSDOS
53 else
54 break;
55 *cp++ = '"'; /* double quotes only */
56 continue;
57 #else
58 break;
59 #endif
60 #ifndef MSDOS
61 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 break;
77 #endif
78 case ' ':
79 case '\t':
80 if (!quote)
81 while (isspace(cmd[1]))
82 cmd++;
83 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 eputs("popen: too many open files\n");
121 quit(1);
122 }
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 }