ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/persist.c
Revision: 2.1
Committed: Wed Jan 20 15:19:00 1993 UTC (31 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

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