ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/persist.c
Revision: 2.10
Committed: Fri May 28 13:37:39 1993 UTC (30 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.9: +3 -3 lines
Log Message:
fixed potential bug in persist file function

File Contents

# Content
1 /* Copyright (c) 1993 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Routines for persistent rtrace and rpict processes.
9 */
10
11 #include "standard.h"
12
13 #ifdef F_SETLKW
14
15 #include "paths.h"
16 #include <signal.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19
20 #ifndef TIMELIM
21 #define TIMELIM (8*3600) /* time limit for holding pattern */
22 #endif
23
24 extern char *strcpy(), *index();
25
26 extern int headismine; /* boolean true if header belongs to me */
27
28 static char *persistfname = NULL; /* persist file name */
29 static int persistfd = -1; /* persist file descriptor */
30
31 static char inpname[TEMPLEN+1], outpname[TEMPLEN+1];
32
33
34 pfdetach() /* release persist (and header) resources */
35 {
36 if (persistfd >= 0)
37 close(persistfd);
38 persistfd = -1;
39 persistfname = NULL;
40 inpname[0] = '\0';
41 outpname[0] = '\0';
42 headismine = 0;
43 }
44
45
46 pfclean() /* clean up persist files */
47 {
48 if (persistfd >= 0)
49 close(persistfd);
50 if (persistfname != NULL)
51 unlink(persistfname);
52 if (inpname[0])
53 unlink(inpname);
54 if (outpname[0])
55 unlink(outpname);
56 }
57
58
59 pflock(lf) /* place or release exclusive lock on file */
60 int lf;
61 {
62 struct flock fls;
63
64 fls.l_type = lf ? F_WRLCK : F_UNLCK;
65 fls.l_whence = 0;
66 fls.l_start = 0L;
67 fls.l_len = 0L;
68 if (fcntl(persistfd, F_SETLKW, &fls) < 0)
69 error(SYSTEM, "cannot (un)lock persist file");
70 }
71
72
73 persistfile(pfn) /* open persist file and lock it */
74 char *pfn;
75 {
76 persistfd = open(pfn, O_WRONLY|O_CREAT|O_EXCL, 0666);
77 if (persistfd >= 0) {
78 persistfname = pfn;
79 pflock(1);
80 return;
81 }
82 /* file exists -- switch to i/o process */
83 persistfd = open(pfn, O_RDWR);
84 if (persistfd < 0) {
85 sprintf(errmsg, "cannot open persist file \"%s\"", pfn);
86 error(SYSTEM, errmsg);
87 }
88 pflock(1);
89 io_process(); /* never returns */
90 }
91
92
93 int sig_noop() {}
94
95
96 pfhold() /* holding pattern for idle rendering process */
97 {
98 char buf[128];
99 register int n;
100 /* close input and output descriptors */
101 close(fileno(stdin));
102 close(fileno(stdout));
103 /* create named pipes for input and output */
104 if (mknod(mktemp(strcpy(inpname,TEMPLATE)), S_IFIFO|0600) < 0)
105 goto createrr;
106 if (mknod(mktemp(strcpy(outpname,TEMPLATE)), S_IFIFO|0600) < 0)
107 goto createrr;
108 sprintf(buf, "%d\n%s\n%s\n", getpid(), inpname, outpname);
109 if (lseek(persistfd, 0L, 0) < 0 || ftruncate(persistfd, 0L) < 0)
110 error(SYSTEM, "seek/truncate error on persist file");
111 n = strlen(buf);
112 if (write(persistfd, buf, n) < n)
113 error(SYSTEM, "error writing persist file");
114 /* wait TIMELIM for someone to signal us */
115 signal(SIGIO, sig_noop);
116 alarm(TIMELIM);
117 pflock(0);
118 pause();
119 alarm(0);
120 signal(SIGIO, SIG_DFL);
121 pflock(1);
122 /* someone wants us; reopen stdin and stdout */
123 if (freopen(inpname, "r", stdin) == NULL)
124 goto openerr;
125 if (freopen(outpname, "w", stdout) == NULL)
126 goto openerr;
127 unlink(inpname);
128 inpname[0] = '\0';
129 unlink(outpname);
130 outpname[0] = '\0';
131 return;
132 createrr:
133 error(SYSTEM, "cannot create named pipes in pfhold");
134 openerr:
135 error(SYSTEM, "cannot open named pipes in pfhold");
136 }
137
138
139 io_process() /* just act as conduits to and from actual process */
140 {
141 register char *cp;
142 register int nr, n;
143 char buf[4096], *pfin, *pfout;
144 int pid;
145 /* load and close persist file */
146 nr = read(persistfd, buf, sizeof(buf));
147 pfdetach();
148 if (nr < 0)
149 error(SYSTEM, "cannot read persist file");
150 buf[nr] = '\0';
151 if ((cp = index(buf, '\n')) == NULL)
152 goto formerr;
153 *cp++ = '\0';
154 if ((pid = atoi(buf)) <= 0)
155 goto formerr;
156 pfin = cp;
157 if ((cp = index(cp, '\n')) == NULL)
158 goto formerr;
159 *cp++ = '\0';
160 pfout = cp;
161 if ((cp = index(cp, '\n')) == NULL)
162 goto formerr;
163 *cp++ = '\0';
164 if (cp-buf != nr)
165 goto formerr;
166 /* wake up rendering process */
167 if (kill(pid, SIGIO) < 0)
168 error(SYSTEM, "cannot signal rendering process in io_process");
169 pid = fork(); /* fork i/o process */
170 if (pid < 0)
171 error(SYSTEM, "fork failed in io_process");
172 /* connect to appropriate pipe */
173 if (pid) { /* parent passes renderer output */
174 close(0);
175 if (open(pfout, O_RDONLY) != 0)
176 error(SYSTEM, "cannot open input pipe in io_process");
177 } else { /* child passes renderer input */
178 close(1);
179 if (open(pfin, O_WRONLY) != 1)
180 error(SYSTEM, "cannot open output pipe in io_process");
181 }
182 /* pass input to output */
183 /* read as much as we can, write all of it */
184 while ((nr = read(0, cp=buf, sizeof(buf))) > 0)
185 do {
186 if ((n = write(1, cp, nr)) <= 0)
187 goto writerr;
188 cp += n;
189 } while ((nr -= n) > 0);
190 if (nr < 0)
191 error(SYSTEM, "read error in io_process");
192 close(0); /* close input */
193 close(1); /* close output */
194 if (pid) /* parent waits for child */
195 wait(0);
196 exit(0); /* all done, exit (not quit!) */
197 formerr:
198 error(USER, "format error in persist file");
199 writerr:
200 error(SYSTEM, "write error in io_process");
201 }
202
203 #else
204
205 pfclean() {}
206
207 #endif