1\function{new_process}
2\synopsis{Create a subprocess object}
3\usage{Struct_Type new_process (String_Type argv[]; qualifiers)}
4\description
5  This function executes the program specified by the \exmp{argv}
6  parameter in a subprocess.  If \exmp{argv} is an array, the first
7  element (\exmp{argv[0]}) of the array gives the name of the program
8  to be executed, and the remaining elements serve as arguments passed
9  to the program.  The program returns a structure that may be used to
10  interact with the process.  Upon error, an exception will be thrown.
11
12  The calling program may interact with the subprocess by reading from
13  or writing to the file descriptor fields of the structure returned
14  by the \sfun{new_process} function.  The specific file descriptors
15  are dictated via the \exmp{read}, \exmp{write}, and \exmp{dupN}
16  qualifiers, as described in detail below.
17
18  The function returns a structure containing zero or more fields of the form
19  \exmp{fdN} where \exmp{N} is an integer derived from the qualifiers,
20  e.g., \exmp{fd0} and \exmp{fd1} correspond to the child's stdin and
21  stdout, respectively.  The structure also contains fields of the
22  form \exmp{fpN} whose values are stdio \dtype{File_Type} objects
23  obtained using \exmp{fdopen} with the corresponding \exmp{fdN} value.
24
25  Other important fields include \exmp{pid} whose value is
26  the process-id of the newly created process.
27
28  The status of the process may be checked or collected using the
29  \sfun{wait} method.  It is very important to call this method to
30  avoid the creation of zombie processes.
31
32\qualifiers
33  The following qualifiers are supported:
34#v+
35   read=fds
36#v-
37    fds is a list of integer file descriptors that are open for read
38    access in the subprocess, and may be written to by the calling
39    process using the fdN or fpN fields of the structure.
40#v+
41   write=fds
42#v-
43    fds is a list of integer file descriptors that are open for write
44    access in the subprocess, and may be read to by the calling
45    process using the fdN or fpN fields of the structure.
46#v+
47   stdin=filename
48   stdout=filename
49   stderr=filename
50#v-
51    These qualifiers allow the stdin, stdout, and stderr file
52    descriptors in the subprocess to be redirected to a file.  Note:
53    The filenames are interpreted relative to the value of the
54    \exmp{dir} qualifier.
55#v+
56   fdN=string
57#v-
58    This qualifier will cause the integer file descriptor N to be open
59    in the subprocess and redirected to the filename represented by
60    the string, which is interpreted relative to the value of the \exmp{dir}
61    qualifier.  The access mode is dictated by the first few
62    characters of the string as described in more detail below.
63#v+
64   stdin=File_Type|FD_Type
65   stdout=File_Type|FD_Type
66   stderr=File_Type|FD_Type
67   fdN=FD_Type|FD_Type
68#v-
69     If the stdin, stdout, stderr, or fdN qualifiers have File_Type or
70     FD_Type values, then corresponding file descriptors in the
71     subprocess will be dup'd to FD_Type or FP_Type file descriptor.
72     This form of the qualifier may be used to setup pipelines.
73#v+
74   dupN=int
75#v-
76     The file descriptor corresponding to the integer N in the
77     subprocess is created by duping the descriptor given by the
78     integer value of the qualifier.  For example, dup2=1 would cause
79     stderr (fd=2) in the subprocess to be redirected to stdout (fd=1).
80#v+
81   dir=string
82#v-
83     Change to the specified directory in the child process.  This
84     will happen after the child process is started, but before any
85     files have been opened.  Hence, files attached to \ivar{stdin},
86     \ivar{stdout}, etc will be opened relative to this directory.
87#v+
88   pre_exec_hook=&func
89#v-
90     This qualifier will cause the function corresponding to \exmp{func} to
91     be called prior to closing unused file descriptors and invoking
92     the executable.  The function will be passed a list of integer
93     valued file descriptors that will be kept open.  Additional
94     integers may be added to the list by the function.  If the
95     qualifier \exmp{pre_exec_hook_optarg} exists, it will also be
96     passed as an addtional argument.
97#v+
98   pre_exec_hook_optarg=VALUE
99#v-
100     If this qualifier exists, its value will be passed as the second
101     argument to the \exmp{pre_exec_hook} callback function.
102
103  Note that the read and write qualifiers specify the nature of the
104  file descriptors from the child process's view.  That is, those
105  opened in the child process using the read qualifier, may be written
106  to by the parent.  Similarly, those opened using the write qualifier
107  may be read by the parent.
108
109\methods
110#v+
111    Struct_Type .wait ( [ options ] )
112#v-
113  The \exmp{.wait} method may be used to collect the exist status of
114  the process.  When called without arguments, it will cause the
115  parent process to wait for the subprocess to exit and return its
116  exit status in the form of a \ifun{waitpid} structure.  The optional
117  \exmp{options} argument corresponds to the options argument of the
118  \ifun{waitpid} function.  The most common is the WNOHANG option,
119  which will cause the \exmp{.wait} method to return immediately if
120  the process has not exited.
121
122  If an error occurs, the function will return NULL and set
123  \ivar{errno} accordingly.  Otherwise it will return a \exmp{waitpid}
124  structure.  See the documentation for \exmp{waitpid} for more
125  information.
126
127\example
128  In the following examples, \exmp{pgm} represents the program to be
129  invoked in the subprocess.  For simplicity, no addition arguments are
130  shown
131
132  Create subprocess that inherits stdin, stdout, stderr from the caller:
133#v+
134   obj = new_process (pgm);
135#v-
136
137  Create a subprocess that inherits stdin, stdout, and writes stderr
138  to a file:
139#v+
140   obj = new_process (pgm; stderr="/tmp/file");   % form 1
141   obj = new_process (pgm; fd2=">/tmp/file");     % form 2
142#v-
143
144  Mimic popen(pgm, "r"):
145#v+
146   obj = new_process (pgm; write=1);   % Read from obj.fp1
147#v-
148
149  Mimic popen(pgm, "w"):
150#v+
151   obj = new_process (pgm; read=0);  % Write to obj.fp0
152#v-
153
154  Mimic popen("pgm 2>&1", "r"):
155#v+
156   obj = new_process (pgm; write=1, dup2=1);  % Read from fp1
157#v-
158
159  Send stdout to a file, read from the subprocess's stderr:
160#v+
161   obj = new_process (pgm; stdout="/tmp/file", write=2);
162   % Read from obj.fp2
163#v-
164
165  Create a process with handles to its stdin, stdout, stderr
166#v+
167   obj = new_process (pgm; write={1,2}, read=0);
168   % Use obj.fp0 for stdin, obj.fp1 for stdout, and obj.fp2 for stderr
169#v-
170
171  Create a process with a write handle to the process's fd=27 and a
172  read handle to the process's stdout.
173#v+
174   obj = new_process (pgm; read=27, write=1);
175   % write to fp27, read from fp1
176#v-
177
178  Create a pipeline: pgm1 | pgm2 > /tmp/log :
179#v+
180  obj1 = new_process (pgm1; write=1);
181  obj2 = new_process (pgm2; stdin=obj1.fp1, stdout="/tmp/log");
182#v-
183
184  Create a pipeline with fd=27 from pgm1 redirected to stdin of pgm2:
185#v+
186  obj1 = new_process (pgm1; write=27);
187  obj2 = new_process (pgm2; stdin=obj1.fp27);
188#v-
189
190  Create a pipeline with fd=27 from pgm1 redirected to fd=9 of pgm2:
191#v+
192  obj1 = new_process (pgm1; write=27);
193  obj2 = new_process (pgm2; fp9=obj1.fp27);
194#v-
195
196  Mimic: pgm 2>&1 1>/dev/null
197#v+
198  obj = new_process (pgm; fp2=1, stdout="/dev/null");
199#v-
200
201  Mimic: pgm >/dev/null 2>&1
202#v+
203  obj = new_process (pgm; stdout="/dev/null", dup2=1);
204#v-
205
206  Append the output of pgm to /tmp/file.log:
207#v+
208   obj = new_process (pgm; stdout=">>/tmp/file.log");
209#v-
210
211\notes
212  Care must be exercised when reading or writing to multiple file
213  descriptors of a subprocess to avoid deadlock.  In such cases, the
214  select module should be used, or the file descriptors could be put in
215  non-blocking mode via the fcntl module.
216
217  It is important to call the \exmp{.wait} method prevent the process
218  from becoming a zombie and clogging the process table.
219\seealso{popen, system}
220\done
221