ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/popen.c
Revision: 2.2
Committed: Mon Sep 21 12:02:16 1992 UTC (31 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +14 -1 lines
Log Message:
Changes for PC port

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