ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rtprocess.h
(Generate patch)

Comparing ray/src/common/rtprocess.h (file contents):
Revision 3.1 by schorsch, Thu Jun 26 00:58:09 2003 UTC vs.
Revision 3.21 by greg, Mon Jan 18 03:55:33 2021 UTC

# Line 7 | Line 7
7   */
8   #ifndef _RAD_PROCESS_H_
9   #define _RAD_PROCESS_H_
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
10  
11 <
12 < #include "copyright.h"
13 <
14 < #include  <sys/types.h>
15 < #ifdef _WIN32
16 <  #include <windows.h>
11 > #include  <errno.h>
12 > #include <stdio.h>
13 > #if defined(_WIN32) || defined(_WIN64)
14 >  #include <windows.h> /* DWORD etc. */
15 >  typedef DWORD RT_PID;
16 >  #include <process.h> /* getpid() and others */
17 >  #define getpid _getpid
18 >  #define execv _execv
19 >  #define execvp _execvp
20   #else
21    #include <sys/param.h>
22 <  #include <unistd.h>
22 >  typedef pid_t RT_PID;
23   #endif
24 < #ifndef BSD
25 < #include  <errno.h>
26 < #endif
24 > #include <sys/types.h>
25  
26   #include "paths.h"
27  
28 + #ifdef __cplusplus
29 + extern "C" {
30 + #endif
31  
32   /* On Windows, a process ID is a DWORD. That might actually be the
33     same thing as an int, but it's better not to assume anything.
34  
35     This means that we shouldn't rely on PIDs and file descriptors
36     being the same type, so we have to describe processes with a struct,
37 <   instead of the original int[3]. To keep things simple, we typedef
38 <   the posix pid_t on those systems that don't have it already.
37 >   instead of the original int[3]. For that purpose, we typedef a
38 >   platform independent RT_PID.
39 > */
40  
41 <   Some older Windows systems use negative PIDs. Open_process() and
42 <   close_process() will convert those to positive values during
43 <   runtime, so that client modules can still use -1 as invalid PID.
41 > /* On Unix, we can set flags and assign descriptors before opening a
42 >   process, coupling an existing input or output to the new process rather
43 >   than opening both pipes.  If PF_FILT_INP is passed in the flags member of
44 >   SUBPROC, then the given r stream will be attached to the standard input
45 >   of the child process, and subsequent reads from that descriptor in the
46 >   parent get data from the standard output of the child, instead.  The
47 >   returned w descriptor is set to -1, since there is no longer any way
48 >   to write to the input of the child.  The default r descriptor of 0 will
49 >   compel the child to act as a filter on the standard input of the parent.
50 >   Whatever r handle you specify, the child will filter its read operations.
51 >   Note that this should be called before anything has been buffered using r.
52 >   If PF_FILT_OUT is set in flags, then the given w stream will be
53 >   attached to the standard output of the child, and subsequent writes
54 >   to that descriptor in the parent send data to the standard input
55 >   of the child. The returned r descriptor is set to -1, since
56 >   there is no output to read from any longer in the child.  The
57 >   default w descriptor of 1 will cause the child to act as a filter
58 >   on the output of the parent.  Make sure to call fflush(stdout) first
59 >   if any data was buffered.  It is illegal to set both PF_FILT_INP and
60 >   PF_FILT_OUT, as a circular process is guaranteed to hang.
61 >  
62 >   If you want behavior similar to popen(cmd, "w") (again Unix-only),
63 >   keeping stdout open in parent, use a duplicate descriptor like so:
64 >   {
65 >        SUBPROC rtp = sp_inactive;
66 >        FILE    *fout;
67 >        fflush(stdout);
68 >        rtp.w = dup(fileno(stdout));
69 >        rtp.flags |= PF_FILT_OUT;
70 >        if (open_process(&rtp, cmd_argv) <= 0) {
71 >                perror(cmd_argv[0]); exit(1);
72 >        }
73 >        fout = fdopen(rtp.w, "w");
74 >        ...write data to filter using fout until finished...
75 >        fclose(fout);
76 >        if (close_process(&rtp)) {
77 >                perror(cmd_argv[0]); exit(1);
78 >        }
79 >        ...can continue sending data directly to stdout...
80 >    }
81 >    We could also have called open_process() after fdopen() above, or after
82 >    using fopen() on a file if we wanted to insert our filter before it.
83 >    A similar sequence may be used to filter from stdin without closing
84 >    it, though process termination becomes more difficult with two readers.
85 >    Filtering input from a file works better, since the file is then read by
86 >    the child only, as in:
87 >    {
88 >        SUBPROC rtp = sp_inactive;
89 >        FILE    *fin = fopen(fname, "r");
90 >        if (fin == NULL) {
91 >                open_error(fname); exit(1);
92 >        }
93 >        rtp.r = fileno(fin);
94 >        rtp.flags |= PF_FILT_INP;
95 >        if (open_process(&rtp, cmd_argv) <= 0) {
96 >                perror(cmd_argv[0]); fclose(fin); exit(1);
97 >        }
98 >        ...read filtered file data from fin until EOF...
99 >        fclose(fin);
100 >        if (close_process(&rtp)) {
101 >                perror(cmd_argv[0]); exit(1);
102 >        }
103 >    }
104   */
105  
44 #ifdef _WIN32
45  typedef DWORD pid_t;
46 #endif
106  
107   #ifndef PIPE_BUF
108    #ifdef PIPSIZ
# Line 56 | Line 115 | extern "C" {
115      #endif
116    #endif
117   #endif
118 +                                /* process flags */
119 + #define PF_RUNNING      1               /* process is running */
120 + #define PF_FILT_INP     2               /* use assigned read descriptor */
121 + #define PF_FILT_OUT     4               /* use assigned write descriptor */
122  
123   typedef struct {
124 <        int r; /* read handle */
125 <        int w; /* write handle */
126 <        int running; /* doing something */
127 <        pid_t pid; /* process ID */
124 >        int     flags;          /* what is being done */
125 >        int     r;              /* read handle */
126 >        int     w;              /* write handle */
127 >        RT_PID  pid;            /* process ID */
128   } SUBPROC;
129  
130 < #define SP_INACTIVE {-1,-1,0,0} /* for static initializations */
130 > #define SP_INACTIVE {0,0,1,-1}  /* for static initializations */
131  
132 + #define close_process(pd)       close_processes(pd,1)
133 +
134   extern int open_process(SUBPROC *pd, char *av[]);
135 < extern int close_process(SUBPROC *pd);
135 > extern int close_processes(SUBPROC pd[], int nproc);
136   extern int process(SUBPROC *pd, char *recvbuf, char *sendbuf, int nbr, int nbs);
137 < extern int readbuf(int fd, char *bpos, int siz);
138 < extern int writebuf(int fd, char *bpos, int siz);
137 > extern ssize_t readbuf(int fd, char *bpos, ssize_t siz);
138 > extern ssize_t writebuf(int fd, char *bpos, ssize_t siz);
139  
140 + #if defined(_WIN32) || defined(_WIN64)
141 + /* any non-negative increment will send the process to IDLE_PRIORITY_CLASS. */
142 + extern int win_kill(RT_PID pid, int sig /* ignored */);
143 + extern int win_nice(int inc);
144 + #endif
145 +
146 + extern SUBPROC  sp_inactive;
147  
148   #ifdef __cplusplus
149   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines