ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/devcomm.c
Revision: 2.17
Committed: Tue Jul 8 18:25:00 2014 UTC (9 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R2P2, rad5R0, rad4R2, rad4R2P1
Changes since 2.16: +8 -8 lines
Log Message:
Eliminated unnecessary "extern" and "register" modifiers

File Contents

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