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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.17 static const char RCSid[] = "$Id: devcomm.c,v 2.16 2011/10/05 17:20:55 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * devcomm.c - communication routines for separate drivers.
6     *
7 greg 2.6 * External symbols declared in driver.h
8     */
9    
10 greg 2.7 #include "copyright.h"
11 greg 2.9
12 schorsch 2.12 #include <sys/types.h>
13 greg 2.16 #ifndef _WIN32
14     #include <sys/wait.h>
15     #endif
16 schorsch 2.12
17 greg 2.16 #include "paths.h"
18 greg 2.10 #include "platform.h"
19 greg 1.10 #include "standard.h"
20 greg 1.1 #include "driver.h"
21 greg 2.2
22 greg 1.1 #ifndef DEVPATH
23     #define DEVPATH getenv("PATH") /* device search path */
24     #endif
25    
26 schorsch 2.12 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 greg 1.1
43 greg 1.12 struct driver comm_driver = {
44 greg 1.1 comm_close, comm_clear, comm_paintr, comm_getcur,
45 greg 1.12 comm_comout, comm_comin, comm_flush
46 greg 1.1 };
47    
48    
49 greg 2.3 static struct driver *
50 schorsch 2.12 final_connect(void) /* verify and initialize connection */
51 greg 2.3 {
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 gregl 2.5 erract[COMMAND].pf = comm_comout;
60 greg 2.15 /* doesn't work with raypcalls.c
61 gregl 2.5 if (erract[WARNING].pf != NULL)
62     erract[WARNING].pf = comm_comout;
63 greg 2.15 */
64 greg 2.3 return(&comm_driver);
65     }
66    
67    
68 greg 2.17 struct driver *
69 schorsch 2.12 slave_init( /* run rview in slave mode */
70     char *dname,
71     char *id
72     )
73 greg 2.3 {
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 greg 2.17 struct driver *
82 schorsch 2.12 comm_init( /* set up and execute driver */
83     char *dname,
84     char *id
85     )
86 greg 1.1 {
87 greg 2.6 char *dvcname;
88 greg 1.1 int p1[2], p2[2];
89 greg 1.7 char pin[16], pout[16];
90     /* find driver program */
91 greg 2.6 if ((dvcname = getpath(dname, DEVPATH, X_OK)) == NULL) {
92 gregl 2.5 eputs(dname);
93     eputs(": not found\n");
94 greg 1.1 return(NULL);
95     }
96 greg 2.8 #ifdef RHAS_FORK_EXEC
97 greg 1.7 /* open communication pipes */
98 greg 1.1 if (pipe(p1) == -1 || pipe(p2) == -1)
99     goto syserr;
100 greg 2.11 if ((devchild = fork()) == 0) { /* fork driver process */
101 greg 1.1 close(p1[1]);
102     close(p2[0]);
103 greg 1.7 sprintf(pin, "%d", p1[0]);
104     sprintf(pout, "%d", p2[1]);
105 greg 2.14 execl(dvcname, dname, pin, pout, id, NULL);
106 greg 2.6 perror(dvcname);
107 greg 1.1 _exit(127);
108     }
109     if (devchild == -1)
110     goto syserr;
111     close(p1[0]);
112     close(p2[1]);
113 greg 2.13 /*
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 greg 1.1 if ((devout = fdopen(p1[1], "w")) == NULL)
120     goto syserr;
121     if ((devin = fdopen(p2[0], "r")) == NULL)
122     goto syserr;
123 greg 2.3 return(final_connect()); /* verify initialization */
124 greg 1.1 syserr:
125 greg 1.7 perror(dname);
126 greg 1.1 return(NULL);
127 greg 2.8
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 greg 1.1 }
136    
137    
138 greg 2.6 static void
139 schorsch 2.12 comm_close(void) /* done with driver */
140 greg 1.1 {
141     int pid;
142    
143 gregl 2.5 erract[COMMAND].pf = NULL; /* reset error vectors */
144     if (erract[WARNING].pf != NULL)
145     erract[WARNING].pf = wputs;
146 greg 1.1 fclose(devout);
147     fclose(devin);
148 greg 2.3 if (devchild < 0)
149     return;
150 greg 2.16 #ifndef _WIN32
151 greg 1.1 while ((pid = wait(0)) != -1 && pid != devchild)
152     ;
153 greg 2.16 #endif
154 greg 1.1 }
155    
156    
157 greg 2.6 static void
158 schorsch 2.12 comm_clear( /* clear screen */
159     int xres,
160     int yres
161     )
162 greg 1.1 {
163     putc(COM_CLEAR, devout);
164 greg 1.8 putw(xres, devout);
165     putw(yres, devout);
166 greg 1.1 fflush(devout);
167     }
168    
169    
170 greg 2.6 static void
171 schorsch 2.12 comm_paintr( /* paint a rectangle */
172     COLOR col,
173     int xmin,
174     int ymin,
175     int xmax,
176     int ymax
177     )
178 greg 1.1 {
179     putc(COM_PAINTR, devout);
180 greg 1.10 fwrite((char *)col, sizeof(COLOR), 1, devout);
181 greg 1.8 putw(xmin, devout);
182     putw(ymin, devout);
183     putw(xmax, devout);
184     putw(ymax, devout);
185 greg 1.12 }
186    
187    
188 greg 2.6 static void
189 schorsch 2.12 comm_flush(void) /* flush output to driver */
190 greg 1.12 {
191     putc(COM_FLUSH, devout);
192     fflush(devout);
193 greg 1.13 if (getc(devin) != COM_FLUSH)
194     reply_error("flush");
195 greg 1.17 getstate();
196 greg 1.1 }
197    
198    
199     static int
200 schorsch 2.12 comm_getcur( /* get and return cursor position */
201     int *xp,
202     int *yp
203     )
204 greg 1.1 {
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 greg 1.8 *xp = getw(devin);
213     *yp = getw(devin);
214 greg 1.1 return(c);
215     }
216    
217    
218 greg 2.6 static void
219 schorsch 2.12 comm_comout( /* print string to command line */
220     char *str
221     )
222 greg 1.1 {
223     putc(COM_COMOUT, devout);
224     myputs(str, devout);
225 greg 1.18 if (str[strlen(str)-1] == '\n')
226     fflush(devout);
227 greg 1.1 }
228    
229    
230 greg 2.6 static void
231 schorsch 2.12 comm_comin( /* read string from command line */
232     char *buf,
233     char *prompt
234     )
235 greg 1.1 {
236     putc(COM_COMIN, devout);
237 greg 1.11 if (prompt == NULL)
238     putc(0, devout);
239     else {
240     putc(1, devout);
241     myputs(prompt, devout);
242     }
243 greg 1.1 fflush(devout);
244     if (getc(devin) != COM_COMIN)
245     reply_error("comin");
246     mygets(buf, devin);
247 greg 1.17 getstate();
248 greg 1.1 }
249    
250    
251 greg 2.6 static void
252 schorsch 2.12 mygets( /* get string from file (with nul) */
253 greg 2.17 char *s,
254     FILE *fp
255 schorsch 2.12 )
256 greg 1.1 {
257 greg 2.17 int c;
258 greg 1.1
259     while ((c = getc(fp)) != EOF)
260     if ((*s++ = c) == '\0')
261     return;
262     *s = '\0';
263     }
264    
265    
266 greg 2.6 static void
267 schorsch 2.12 myputs( /* put string to file (with nul) */
268 greg 2.17 char *s,
269     FILE *fp
270 schorsch 2.12 )
271 greg 1.1 {
272     do
273     putc(*s, fp);
274     while (*s++);
275     }
276    
277    
278 greg 2.6 static void
279 schorsch 2.12 reply_error( /* what should we do here? */
280     char *routine
281     )
282 greg 1.1 {
283 gregl 2.5 eputs(routine);
284     eputs(": driver reply error\n");
285 greg 1.1 quit(1);
286 greg 1.17 }
287    
288    
289 greg 2.6 static void
290 schorsch 2.12 getstate(void) /* get driver state variables */
291 greg 1.17 {
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 greg 1.1 }