ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/devcomm.c
Revision: 2.8
Committed: Wed Jul 2 01:15:20 2003 UTC (20 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +10 -1 lines
Log Message:
Fixed broken use of RHAS_FORK_EXEC

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: devcomm.c,v 2.7 2003/02/25 02:47:22 greg Exp $";
3 #endif
4 /*
5 * devcomm.c - communication routines for separate drivers.
6 *
7 * External symbols declared in driver.h
8 */
9
10 #include "copyright.h"
11
12 #include "standard.h"
13
14 #include "color.h"
15
16 #include "driver.h"
17
18 #include "vfork.h"
19
20 #ifndef DEVPATH
21 #define DEVPATH getenv("PATH") /* device search path */
22 #endif
23
24 static int comm_getcur();
25 static void comm_close(), comm_clear(), comm_paintr(),
26 comm_comin(), comm_comout(), comm_flush();
27
28 struct driver comm_driver = {
29 comm_close, comm_clear, comm_paintr, comm_getcur,
30 comm_comout, comm_comin, comm_flush
31 };
32
33 static void mygets(), myputs(), reply_error(), getstate();
34
35 FILE *devin, *devout;
36
37 int devchild;
38
39
40 static struct driver *
41 final_connect() /* verify and initialize connection */
42 {
43 putw(COM_SENDM, devout);
44 fflush(devout);
45 if (getw(devin) != COM_RECVM)
46 return(NULL);
47 /* get driver parameters */
48 getstate();
49 /* set error vectors */
50 erract[COMMAND].pf = comm_comout;
51 if (erract[WARNING].pf != NULL)
52 erract[WARNING].pf = comm_comout;
53 return(&comm_driver);
54 }
55
56
57 struct driver *
58 slave_init(dname, id) /* run rview in slave mode */
59 char *dname, *id;
60 {
61 devchild = -1; /* we're the slave here */
62 devout = stdout; /* use standard input */
63 devin = stdin; /* and standard output */
64 return(final_connect()); /* verify initialization */
65 }
66
67
68 struct driver *
69 comm_init(dname, id) /* set up and execute driver */
70 char *dname, *id;
71 {
72 char *dvcname;
73 int p1[2], p2[2];
74 char pin[16], pout[16];
75 /* find driver program */
76 if ((dvcname = getpath(dname, DEVPATH, X_OK)) == NULL) {
77 eputs(dname);
78 eputs(": not found\n");
79 return(NULL);
80 }
81 #ifdef RHAS_FORK_EXEC
82 /* open communication pipes */
83 if (pipe(p1) == -1 || pipe(p2) == -1)
84 goto syserr;
85 if ((devchild = vfork()) == 0) { /* fork driver process */
86 close(p1[1]);
87 close(p2[0]);
88 sprintf(pin, "%d", p1[0]);
89 sprintf(pout, "%d", p2[1]);
90 execl(dvcname, dname, pin, pout, id, 0);
91 perror(dvcname);
92 _exit(127);
93 }
94 if (devchild == -1)
95 goto syserr;
96 close(p1[0]);
97 close(p2[1]);
98 if ((devout = fdopen(p1[1], "w")) == NULL)
99 goto syserr;
100 if ((devin = fdopen(p2[0], "r")) == NULL)
101 goto syserr;
102 return(final_connect()); /* verify initialization */
103 syserr:
104 perror(dname);
105 return(NULL);
106
107 #else /* ! RHAS_FORK_EXEC */
108
109 eputs(dname);
110 eputs(": no fork/exec\n");
111 return(NULL);
112
113 #endif /* ! RHAS_FORK_EXEC */
114 }
115
116
117 static void
118 comm_close() /* done with driver */
119 {
120 int pid;
121
122 erract[COMMAND].pf = NULL; /* reset error vectors */
123 if (erract[WARNING].pf != NULL)
124 erract[WARNING].pf = wputs;
125 fclose(devout);
126 fclose(devin);
127 if (devchild < 0)
128 return;
129 while ((pid = wait(0)) != -1 && pid != devchild)
130 ;
131 }
132
133
134 static void
135 comm_clear(xres, yres) /* clear screen */
136 int xres, yres;
137 {
138 putc(COM_CLEAR, devout);
139 putw(xres, devout);
140 putw(yres, devout);
141 fflush(devout);
142 }
143
144
145 static void
146 comm_paintr(col, xmin, ymin, xmax, ymax) /* paint a rectangle */
147 COLOR col;
148 int xmin, ymin, xmax, ymax;
149 {
150 putc(COM_PAINTR, devout);
151 fwrite((char *)col, sizeof(COLOR), 1, devout);
152 putw(xmin, devout);
153 putw(ymin, devout);
154 putw(xmax, devout);
155 putw(ymax, devout);
156 }
157
158
159 static void
160 comm_flush() /* flush output to driver */
161 {
162 putc(COM_FLUSH, devout);
163 fflush(devout);
164 if (getc(devin) != COM_FLUSH)
165 reply_error("flush");
166 getstate();
167 }
168
169
170 static int
171 comm_getcur(xp, yp) /* get and return cursor position */
172 int *xp, *yp;
173 {
174 int c;
175
176 putc(COM_GETCUR, devout);
177 fflush(devout);
178 if (getc(devin) != COM_GETCUR)
179 reply_error("getcur");
180 c = getc(devin);
181 *xp = getw(devin);
182 *yp = getw(devin);
183 return(c);
184 }
185
186
187 static void
188 comm_comout(str) /* print string to command line */
189 char *str;
190 {
191 putc(COM_COMOUT, devout);
192 myputs(str, devout);
193 if (str[strlen(str)-1] == '\n')
194 fflush(devout);
195 }
196
197
198 static void
199 comm_comin(buf, prompt) /* read string from command line */
200 char *buf;
201 char *prompt;
202 {
203 putc(COM_COMIN, devout);
204 if (prompt == NULL)
205 putc(0, devout);
206 else {
207 putc(1, devout);
208 myputs(prompt, devout);
209 }
210 fflush(devout);
211 if (getc(devin) != COM_COMIN)
212 reply_error("comin");
213 mygets(buf, devin);
214 getstate();
215 }
216
217
218 static void
219 mygets(s, fp) /* get string from file (with nul) */
220 register char *s;
221 register FILE *fp;
222 {
223 register int c;
224
225 while ((c = getc(fp)) != EOF)
226 if ((*s++ = c) == '\0')
227 return;
228 *s = '\0';
229 }
230
231
232 static void
233 myputs(s, fp) /* put string to file (with nul) */
234 register char *s;
235 register FILE *fp;
236 {
237 do
238 putc(*s, fp);
239 while (*s++);
240 }
241
242
243 static void
244 reply_error(routine) /* what should we do here? */
245 char *routine;
246 {
247 eputs(routine);
248 eputs(": driver reply error\n");
249 quit(1);
250 }
251
252
253 static void
254 getstate() /* get driver state variables */
255 {
256 fread((char *)&comm_driver.pixaspect,
257 sizeof(comm_driver.pixaspect), 1, devin);
258 comm_driver.xsiz = getw(devin);
259 comm_driver.ysiz = getw(devin);
260 comm_driver.inpready = getw(devin);
261 }