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

# User Rev Content
1 greg 2.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     }