ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/devcomm.c
Revision: 2.15
Committed: Thu Aug 21 07:05:58 2008 UTC (15 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R0
Changes since 2.14: +3 -1 lines
Log Message:
Added -n option to rvu for multiple rendering processes

File Contents

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