ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/process.c
Revision: 2.6
Committed: Tue Feb 25 02:47:21 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.5: +1 -56 lines
Log Message:
Replaced inline copyright notice with #include "copyright.h"

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.5 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4     /*
5     * Routines to communicate with separate process via dual pipes
6 greg 2.5 *
7     * External symbols declared in standard.h
8     */
9    
10 greg 2.6 #include "copyright.h"
11 greg 1.1
12     /* find pipe buffer limit */
13     #include <sys/param.h>
14    
15     #ifndef PIPE_BUF
16     #ifdef PIPSIZ
17     #define PIPE_BUF PIPSIZ
18     #else
19     #ifdef PIPE_MAX
20     #define PIPE_BUF PIPE_MAX
21     #else
22     #define PIPE_BUF 512 /* hyperconservative */
23     #endif
24     #endif
25     #endif
26    
27 greg 2.2 #include "vfork.h"
28 greg 1.1
29 greg 2.4 #ifndef BSD
30     #include <errno.h>
31     #endif
32 greg 1.1
33 greg 2.4
34 greg 1.1 int
35     open_process(pd, av) /* open communication to separate process */
36     int pd[3];
37     char *av[];
38     {
39     extern char *getpath(), *getenv();
40     char *compath;
41     int p0[2], p1[2];
42     /* find executable */
43     compath = getpath(av[0], getenv("PATH"), 1);
44     if (compath == 0)
45     return(0);
46     if (pipe(p0) < 0 || pipe(p1) < 0)
47     return(-1);
48     if ((pd[2] = vfork()) == 0) { /* if child */
49     close(p0[1]);
50     close(p1[0]);
51     if (p0[0] != 0) { /* connect p0 to stdin */
52     dup2(p0[0], 0);
53     close(p0[0]);
54     }
55     if (p1[1] != 1) { /* connect p1 to stdout */
56     dup2(p1[1], 1);
57     close(p1[1]);
58     }
59     execv(compath, av); /* exec command */
60     perror(compath);
61     _exit(127);
62     }
63     if (pd[2] == -1)
64     return(-1);
65     close(p0[0]);
66     close(p1[1]);
67     pd[0] = p1[0];
68     pd[1] = p0[1];
69     return(PIPE_BUF);
70     }
71    
72    
73     int
74     process(pd, recvbuf, sendbuf, nbr, nbs) /* process data through pd */
75     int pd[3];
76     char *recvbuf, *sendbuf;
77     int nbr, nbs;
78     {
79     if (nbs > PIPE_BUF)
80     return(-1);
81     if (writebuf(pd[1], sendbuf, nbs) < nbs)
82     return(-1);
83     return(readbuf(pd[0], recvbuf, nbr));
84     }
85    
86    
87     int
88     close_process(pd) /* close pipes and wait for process */
89     int pd[3];
90     {
91     int pid, status;
92    
93     close(pd[1]);
94     close(pd[0]);
95     while ((pid = wait(&status)) != -1)
96     if (pid == pd[2])
97     return(status>>8 & 0xff);
98     return(-1); /* ? unknown status */
99     }
100    
101    
102     int
103     readbuf(fd, bpos, siz) /* read all of requested buffer */
104     int fd;
105     char *bpos;
106     int siz;
107     {
108 greg 2.3 register int cc = 0, nrem = siz;
109 greg 2.4 retry:
110 greg 1.1 while (nrem > 0 && (cc = read(fd, bpos, nrem)) > 0) {
111     bpos += cc;
112     nrem -= cc;
113     }
114 greg 2.4 if (cc < 0) {
115     #ifndef BSD
116     if (errno == EINTR) /* we were interrupted! */
117     goto retry;
118     #endif
119 greg 1.1 return(cc);
120 greg 2.4 }
121 greg 1.1 return(siz-nrem);
122     }
123    
124    
125     int
126     writebuf(fd, bpos, siz) /* write all of requested buffer */
127     int fd;
128     char *bpos;
129     int siz;
130     {
131 greg 2.3 register int cc = 0, nrem = siz;
132 greg 2.4 retry:
133 greg 1.1 while (nrem > 0 && (cc = write(fd, bpos, nrem)) > 0) {
134     bpos += cc;
135     nrem -= cc;
136     }
137 greg 2.4 if (cc < 0) {
138     #ifndef BSD
139     if (errno == EINTR) /* we were interrupted! */
140     goto retry;
141     #endif
142 greg 1.1 return(cc);
143 greg 2.4 }
144 greg 1.1 return(siz-nrem);
145     }