ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/popen.c
Revision: 2.1
Committed: Tue Sep 8 09:08:02 1992 UTC (31 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

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