ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/unix_process.c
Revision: 3.10
Committed: Thu Jun 14 05:13:25 2012 UTC (11 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R2P2, rad5R0, rad4R2, rad4R2P1
Changes since 3.9: +13 -10 lines
Log Message:
Simplified creation of child process

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: unix_process.c,v 3.9 2009/12/12 23:08:13 greg Exp $";
3 #endif
4 /*
5 * Routines to communicate with separate process via dual pipes
6 * Unix version
7 *
8 * External symbols declared in standard.h
9 */
10
11 #include "copyright.h"
12
13 #include <sys/types.h>
14 #include <sys/wait.h>
15 #include <fcntl.h>
16 #include <stdlib.h>
17
18 #include "rtprocess.h"
19 #include "rtio.h"
20
21
22 int
23 open_process( /* open communication to separate process */
24 SUBPROC *pd,
25 char *av[]
26 )
27 {
28 char *compath;
29 int p0[2], p1[2];
30
31 pd->running = 0; /* not going yet */
32
33 if (av == NULL) /* cloning operation? */
34 compath = NULL;
35 else if ((compath = getpath(av[0], getenv("PATH"), X_OK)) == NULL)
36 return(0);
37 if (pipe(p0) < 0 || pipe(p1) < 0)
38 return(-1);
39 if ((pd->pid = fork()) == 0) { /* if child... */
40 close(p0[1]);
41 close(p1[0]);
42 if (p0[0] != 0) { /* connect p0 to stdin */
43 dup2(p0[0], 0);
44 close(p0[0]);
45 }
46 if (p1[1] != 1) { /* connect p1 to stdout */
47 dup2(p1[1], 1);
48 close(p1[1]);
49 }
50 if (compath == NULL) /* just cloning? */
51 return(0);
52 execv(compath, av); /* else exec command */
53 perror(compath);
54 _exit(127);
55 }
56 if (pd->pid == -1)
57 return(-1);
58 close(p0[0]);
59 close(p1[1]);
60 pd->r = p1[0];
61 pd->w = p0[1];
62 /*
63 * Close write stream on exec to avoid multiprocessing deadlock.
64 * No use in read stream without it, so set flag there as well.
65 * GW: This bug took me two days to figure out!!
66 */
67 fcntl(pd->r, F_SETFD, FD_CLOEXEC);
68 fcntl(pd->w, F_SETFD, FD_CLOEXEC);
69 pd->running = 1;
70 return(PIPE_BUF);
71 }
72
73
74
75 int
76 close_process( /* close pipes and wait for process */
77 SUBPROC *pd
78 )
79 {
80 int status;
81
82 if (!pd->running)
83 return(0);
84 close(pd->w);
85 close(pd->r);
86 pd->running = 0;
87 if (waitpid(pd->pid, &status, 0) == pd->pid)
88 return(status>>8 & 0xff);
89
90 return(-1); /* ? unknown status */
91 }
92
93