ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/devcomm.c
Revision: 2.11
Committed: Tue Nov 11 16:24:06 2003 UTC (20 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.10: +2 -4 lines
Log Message:
Replaced all calls to vfork() with regular fork() calls

File Contents

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