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

# User Rev Content
1 greg 2.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 greg 2.2 case '\'':
47 greg 2.1 case '"':
48     if (!quote)
49     quote = *cmd;
50     else if (quote == *cmd)
51     quote = '\0';
52 greg 2.2 #ifdef MSDOS
53     else
54     break;
55     *cp++ = '"'; /* double quotes only */
56     continue;
57     #else
58 greg 2.1 break;
59 greg 2.2 #endif
60 greg 2.1 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 greg 2.2 break;
76     case ' ':
77     case '\t':
78     if (!quote)
79     while (isspace(cmd[1]))
80     cmd++;
81 greg 2.1 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     }