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, 2 months 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

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.5 static const char RCSid[] = "$Id$";
3 greg 2.1 #endif
4     /*
5     * popen() and pclose() calls for systems without pipe facilities
6     */
7    
8 greg 2.6 #include "copyright.h"
9 greg 2.5
10 greg 2.1 #include <stdio.h>
11 greg 2.5 #include <stdlib.h>
12     #include <string.h>
13 greg 2.1 #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 greg 2.4 while (isspace(*cmd))
37     cmd++;
38     if (!*cmd)
39     return(NULL);
40 greg 2.5 fname = (char *)malloc(TEMPLEN+1);
41     newcmd = (char *)malloc(TEMPLEN+6+strlen(cmd));
42 greg 2.1 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 greg 2.2 case '\'':
49 greg 2.1 case '"':
50     if (!quote)
51     quote = *cmd;
52     else if (quote == *cmd)
53     quote = '\0';
54 greg 2.2 #ifdef MSDOS
55     else
56     break;
57     *cp++ = '"'; /* double quotes only */
58     continue;
59 greg 2.4 case '\\':
60     if (!quote && cmd[1] == '\n') {
61     *cp++ = ' ';
62     cmd++;
63     continue;
64     }
65     cmd++;
66     break;
67 greg 2.2 #else
68 greg 2.1 break;
69 greg 2.4 case '\\':
70     *cp++ = *cmd++;
71     break;
72 greg 2.1 case '(':
73     if (!quote)
74     paren++;
75     break;
76     case ')':
77     if (!quote && paren)
78     paren--;
79     break;
80 greg 2.4 case ';':
81     #endif
82     case '|':
83     if (!quote && !paren && cp2 == NULL)
84     cp2 = fname;
85 greg 2.2 break;
86     case ' ':
87     case '\t':
88     if (!quote)
89     while (isspace(cmd[1]))
90     cmd++;
91 greg 2.1 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 greg 2.4 *cp++ = ' '; *cp++ = '<';
100 greg 2.1 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 greg 2.4 *cp++ = ' '; *cp++ = '>';
112 greg 2.1 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 greg 2.3 eputs("popen: too many open files\n");
124     quit(1);
125 greg 2.1 }
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     }