1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef APR_THREAD_PROC_H
18 #define APR_THREAD_PROC_H
19 
20 /**
21  * @file apr_thread_proc.h
22  * @brief APR Thread and Process Library
23  */
24 
25 #include "apr.h"
26 #include "apr_file_io.h"
27 #include "apr_pools.h"
28 #include "apr_errno.h"
29 
30 #if APR_HAVE_STRUCT_RLIMIT
31 #include <sys/time.h>
32 #include <sys/resource.h>
33 #endif
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif /* __cplusplus */
38 
39 /**
40  * @defgroup apr_thread_proc Threads and Process Functions
41  * @ingroup APR
42  * @{
43  */
44 
45 typedef enum {
46     APR_SHELLCMD,           /**< use the shell to invoke the program */
47     APR_PROGRAM,            /**< invoke the program directly, no copied env */
48     APR_PROGRAM_ENV,        /**< invoke the program, replicating our environment */
49     APR_PROGRAM_PATH,       /**< find program on PATH, use our environment */
50     APR_SHELLCMD_ENV        /**< use the shell to invoke the program,
51                              *   replicating our environment
52                              */
53 } apr_cmdtype_e;
54 
55 typedef enum {
56     APR_WAIT,           /**< wait for the specified process to finish */
57     APR_NOWAIT          /**< do not wait -- just see if it has finished */
58 } apr_wait_how_e;
59 
60 /* I am specifically calling out the values so that the macros below make
61  * more sense.  Yes, I know I don't need to, but I am hoping this makes what
62  * I am doing more clear.  If you want to add more reasons to exit, continue
63  * to use bitmasks.
64  */
65 typedef enum {
66     APR_PROC_EXIT = 1,          /**< process exited normally */
67     APR_PROC_SIGNAL = 2,        /**< process exited due to a signal */
68     APR_PROC_SIGNAL_CORE = 4    /**< process exited and dumped a core file */
69 } apr_exit_why_e;
70 
71 /** did we exit the process */
72 #define APR_PROC_CHECK_EXIT(x)        (x & APR_PROC_EXIT)
73 /** did we get a signal */
74 #define APR_PROC_CHECK_SIGNALED(x)    (x & APR_PROC_SIGNAL)
75 /** did we get core */
76 #define APR_PROC_CHECK_CORE_DUMP(x)   (x & APR_PROC_SIGNAL_CORE)
77 
78 /** @see apr_procattr_io_set */
79 #define APR_NO_PIPE          0
80 
81 /** @see apr_procattr_io_set */
82 #define APR_FULL_BLOCK       1
83 /** @see apr_procattr_io_set */
84 #define APR_FULL_NONBLOCK    2
85 /** @see apr_procattr_io_set */
86 #define APR_PARENT_BLOCK     3
87 /** @see apr_procattr_io_set */
88 #define APR_CHILD_BLOCK      4
89 
90 /** @see apr_procattr_limit_set */
91 #define APR_LIMIT_CPU        0
92 /** @see apr_procattr_limit_set */
93 #define APR_LIMIT_MEM        1
94 /** @see apr_procattr_limit_set */
95 #define APR_LIMIT_NPROC      2
96 /** @see apr_procattr_limit_set */
97 #define APR_LIMIT_NOFILE     3
98 
99 /**
100  * @defgroup APR_OC Other Child Flags
101  * @{
102  */
103 #define APR_OC_REASON_DEATH         0     /**< child has died, caller must call
104                                            * unregister still */
105 #define APR_OC_REASON_UNWRITABLE    1     /**< write_fd is unwritable */
106 #define APR_OC_REASON_RESTART       2     /**< a restart is occuring, perform
107                                            * any necessary cleanup (including
108                                            * sending a special signal to child)
109                                            */
110 #define APR_OC_REASON_UNREGISTER    3     /**< unregister has been called, do
111                                            * whatever is necessary (including
112                                            * kill the child) */
113 #define APR_OC_REASON_LOST          4     /**< somehow the child exited without
114                                            * us knowing ... buggy os? */
115 #define APR_OC_REASON_RUNNING       5     /**< a health check is occuring,
116                                            * for most maintainence functions
117                                            * this is a no-op.
118                                            */
119 /** @} */
120 
121 /** The APR process type */
122 typedef struct apr_proc_t {
123     /** The process ID */
124     pid_t pid;
125     /** Parent's side of pipe to child's stdin */
126     apr_file_t *in;
127     /** Parent's side of pipe to child's stdout */
128     apr_file_t *out;
129     /** Parent's side of pipe to child's stdouterr */
130     apr_file_t *err;
131 #if APR_HAS_PROC_INVOKED || defined(DOXYGEN)
132     /** Diagnositics/debugging string of the command invoked for
133      *  this process [only present if APR_HAS_PROC_INVOKED is true]
134      * @remark Only enabled on Win32 by default.
135      * @bug This should either always or never be present in release
136      * builds - since it breaks binary compatibility.  We may enable
137      * it always in APR 1.0 yet leave it undefined in most cases.
138      */
139     char *invoked;
140 #endif
141 #if defined(WIN32) || defined(DOXYGEN)
142     /** (Win32 only) Creator's handle granting access to the process
143      * @remark This handle is closed and reset to NULL in every case
144      * corresponding to a waitpid() on Unix which returns the exit status.
145      * Therefore Win32 correspond's to Unix's zombie reaping characteristics
146      * and avoids potential handle leaks.
147      */
148     HANDLE hproc;
149 #endif
150 } apr_proc_t;
151 
152 /**
153  * The prototype for APR child errfn functions.  (See the description
154  * of apr_procattr_child_errfn_set() for more information.)
155  * It is passed the following parameters:
156  * @param pool Pool associated with the apr_proc_t.  If your child
157  *             error function needs user data, associate it with this
158  *             pool.
159  * @param err APR error code describing the error
160  * @param description Text description of type of processing which failed
161  */
162 typedef void (apr_child_errfn_t)(apr_pool_t *proc, apr_status_t err,
163                                  const char *description);
164 
165 /** Opaque Thread structure. */
166 typedef struct apr_thread_t           apr_thread_t;
167 
168 /** Opaque Thread attributes structure. */
169 typedef struct apr_threadattr_t       apr_threadattr_t;
170 
171 /** Opaque Process attributes structure. */
172 typedef struct apr_procattr_t         apr_procattr_t;
173 
174 /** Opaque control variable for one-time atomic variables.  */
175 typedef struct apr_thread_once_t      apr_thread_once_t;
176 
177 /** Opaque thread private address space. */
178 typedef struct apr_threadkey_t        apr_threadkey_t;
179 
180 /** Opaque record of child process. */
181 typedef struct apr_other_child_rec_t  apr_other_child_rec_t;
182 
183 /**
184  * The prototype for any APR thread worker functions.
185  */
186 typedef void *(APR_THREAD_FUNC *apr_thread_start_t)(apr_thread_t*, void*);
187 
188 typedef enum {
189     APR_KILL_NEVER,             /**< process is never sent any signals */
190     APR_KILL_ALWAYS,            /**< process is sent SIGKILL on apr_pool_t cleanup */
191     APR_KILL_AFTER_TIMEOUT,     /**< SIGTERM, wait 3 seconds, SIGKILL */
192     APR_JUST_WAIT,              /**< wait forever for the process to complete */
193     APR_KILL_ONLY_ONCE          /**< send SIGTERM and then wait */
194 } apr_kill_conditions_e;
195 
196 /* Thread Function definitions */
197 
198 #if APR_HAS_THREADS
199 
200 /**
201  * Create and initialize a new threadattr variable
202  * @param new_attr The newly created threadattr.
203  * @param cont The pool to use
204  */
205 APR_DECLARE(apr_status_t) apr_threadattr_create(apr_threadattr_t **new_attr,
206                                                 apr_pool_t *cont);
207 
208 /**
209  * Set if newly created threads should be created in detached state.
210  * @param attr The threadattr to affect
211  * @param on Non-zero if detached threads should be created.
212  */
213 APR_DECLARE(apr_status_t) apr_threadattr_detach_set(apr_threadattr_t *attr,
214                                                     apr_int32_t on);
215 
216 /**
217  * Get the detach state for this threadattr.
218  * @param attr The threadattr to reference
219  * @return APR_DETACH if threads are to be detached, or APR_NOTDETACH
220  * if threads are to be joinable.
221  */
222 APR_DECLARE(apr_status_t) apr_threadattr_detach_get(apr_threadattr_t *attr);
223 
224 /**
225  * Set the stack size of newly created threads.
226  * @param attr The threadattr to affect
227  * @param stacksize The stack size in bytes
228  */
229 APR_DECLARE(apr_status_t) apr_threadattr_stacksize_set(apr_threadattr_t *attr,
230                                                        apr_size_t stacksize);
231 
232 /**
233  * Set the stack guard area size of newly created threads.
234  * @param attr The threadattr to affect
235  * @param guardsize The stack guard area size in bytes
236  * @note Thread library implementations commonly use a "guard area"
237  * after each thread's stack which is not readable or writable such that
238  * stack overflows cause a segfault; this consumes e.g. 4K of memory
239  * and increases memory management overhead.  Setting the guard area
240  * size to zero hence trades off reliable behaviour on stack overflow
241  * for performance. */
242 APR_DECLARE(apr_status_t) apr_threadattr_guardsize_set(apr_threadattr_t *attr,
243                                                        apr_size_t guardsize);
244 
245 /**
246  * Create a new thread of execution
247  * @param new_thread The newly created thread handle.
248  * @param attr The threadattr to use to determine how to create the thread
249  * @param func The function to start the new thread in
250  * @param data Any data to be passed to the starting function
251  * @param cont The pool to use
252  */
253 APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new_thread,
254                                             apr_threadattr_t *attr,
255                                             apr_thread_start_t func,
256                                             void *data, apr_pool_t *cont);
257 
258 /**
259  * stop the current thread
260  * @param thd The thread to stop
261  * @param retval The return value to pass back to any thread that cares
262  */
263 APR_DECLARE(apr_status_t) apr_thread_exit(apr_thread_t *thd,
264                                           apr_status_t retval);
265 
266 /**
267  * block until the desired thread stops executing.
268  * @param retval The return value from the dead thread.
269  * @param thd The thread to join
270  */
271 APR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval,
272                                           apr_thread_t *thd);
273 
274 /**
275  * force the current thread to yield the processor
276  */
277 APR_DECLARE(void) apr_thread_yield(void);
278 
279 /**
280  * Initialize the control variable for apr_thread_once.  If this isn't
281  * called, apr_initialize won't work.
282  * @param control The control variable to initialize
283  * @param p The pool to allocate data from.
284  */
285 APR_DECLARE(apr_status_t) apr_thread_once_init(apr_thread_once_t **control,
286                                                apr_pool_t *p);
287 
288 /**
289  * Run the specified function one time, regardless of how many threads
290  * call it.
291  * @param control The control variable.  The same variable should
292  *                be passed in each time the function is tried to be
293  *                called.  This is how the underlying functions determine
294  *                if the function has ever been called before.
295  * @param func The function to call.
296  */
297 APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
298                                           void (*func)(void));
299 
300 /**
301  * detach a thread
302  * @param thd The thread to detach
303  */
304 APR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd);
305 
306 /**
307  * Return the pool associated with the current thread.
308  * @param data The user data associated with the thread.
309  * @param key The key to associate with the data
310  * @param thread The currently open thread.
311  */
312 APR_DECLARE(apr_status_t) apr_thread_data_get(void **data, const char *key,
313                                              apr_thread_t *thread);
314 
315 /**
316  * Return the pool associated with the current thread.
317  * @param data The user data to associate with the thread.
318  * @param key The key to use for associating the data with the thread
319  * @param cleanup The cleanup routine to use when the thread is destroyed.
320  * @param thread The currently open thread.
321  */
322 APR_DECLARE(apr_status_t) apr_thread_data_set(void *data, const char *key,
323                                              apr_status_t (*cleanup) (void *),
324                                              apr_thread_t *thread);
325 
326 /**
327  * Create and initialize a new thread private address space
328  * @param key The thread private handle.
329  * @param dest The destructor to use when freeing the private memory.
330  * @param cont The pool to use
331  */
332 APR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key,
333                                                     void (*dest)(void *),
334                                                     apr_pool_t *cont);
335 
336 /**
337  * Get a pointer to the thread private memory
338  * @param new_mem The data stored in private memory
339  * @param key The handle for the desired thread private memory
340  */
341 APR_DECLARE(apr_status_t) apr_threadkey_private_get(void **new_mem,
342                                                  apr_threadkey_t *key);
343 
344 /**
345  * Set the data to be stored in thread private memory
346  * @param priv The data to be stored in private memory
347  * @param key The handle for the desired thread private memory
348  */
349 APR_DECLARE(apr_status_t) apr_threadkey_private_set(void *priv,
350                                                  apr_threadkey_t *key);
351 
352 /**
353  * Free the thread private memory
354  * @param key The handle for the desired thread private memory
355  */
356 APR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key);
357 
358 /**
359  * Return the pool associated with the current threadkey.
360  * @param data The user data associated with the threadkey.
361  * @param key The key associated with the data
362  * @param threadkey The currently open threadkey.
363  */
364 APR_DECLARE(apr_status_t) apr_threadkey_data_get(void **data, const char *key,
365                                                 apr_threadkey_t *threadkey);
366 
367 /**
368  * Return the pool associated with the current threadkey.
369  * @param data The data to set.
370  * @param key The key to associate with the data.
371  * @param cleanup The cleanup routine to use when the file is destroyed.
372  * @param threadkey The currently open threadkey.
373  */
374 APR_DECLARE(apr_status_t) apr_threadkey_data_set(void *data, const char *key,
375                                                 apr_status_t (*cleanup) (void *),
376                                                 apr_threadkey_t *threadkey);
377 
378 #endif
379 
380 /**
381  * Create and initialize a new procattr variable
382  * @param new_attr The newly created procattr.
383  * @param cont The pool to use
384  */
385 APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new_attr,
386                                                   apr_pool_t *cont);
387 
388 /**
389  * Determine if any of stdin, stdout, or stderr should be linked to pipes
390  * when starting a child process.
391  * @param attr The procattr we care about.
392  * @param in Should stdin be a pipe back to the parent?
393  * @param out Should stdout be a pipe back to the parent?
394  * @param err Should stderr be a pipe back to the parent?
395  */
396 APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr,
397                                              apr_int32_t in, apr_int32_t out,
398                                              apr_int32_t err);
399 
400 /**
401  * Set the child_in and/or parent_in values to existing apr_file_t values.
402  * @param attr The procattr we care about.
403  * @param child_in apr_file_t value to use as child_in. Must be a valid file.
404  * @param parent_in apr_file_t value to use as parent_in. Must be a valid file.
405  * @remark  This is NOT a required initializer function. This is
406  *          useful if you have already opened a pipe (or multiple files)
407  *          that you wish to use, perhaps persistently across multiple
408  *          process invocations - such as a log file. You can save some
409  *          extra function calls by not creating your own pipe since this
410  *          creates one in the process space for you.
411  */
412 APR_DECLARE(apr_status_t) apr_procattr_child_in_set(struct apr_procattr_t *attr,
413                                                   apr_file_t *child_in,
414                                                   apr_file_t *parent_in);
415 
416 /**
417  * Set the child_out and parent_out values to existing apr_file_t values.
418  * @param attr The procattr we care about.
419  * @param child_out apr_file_t value to use as child_out. Must be a valid file.
420  * @param parent_out apr_file_t value to use as parent_out. Must be a valid file.
421  * @remark This is NOT a required initializer function. This is
422  *         useful if you have already opened a pipe (or multiple files)
423  *         that you wish to use, perhaps persistently across multiple
424  *         process invocations - such as a log file.
425  */
426 APR_DECLARE(apr_status_t) apr_procattr_child_out_set(struct apr_procattr_t *attr,
427                                                    apr_file_t *child_out,
428                                                    apr_file_t *parent_out);
429 
430 /**
431  * Set the child_err and parent_err values to existing apr_file_t values.
432  * @param attr The procattr we care about.
433  * @param child_err apr_file_t value to use as child_err. Must be a valid file.
434  * @param parent_err apr_file_t value to use as parent_err. Must be a valid file.
435  * @remark This is NOT a required initializer function. This is
436  *         useful if you have already opened a pipe (or multiple files)
437  *         that you wish to use, perhaps persistently across multiple
438  *         process invocations - such as a log file.
439  */
440 APR_DECLARE(apr_status_t) apr_procattr_child_err_set(struct apr_procattr_t *attr,
441                                                    apr_file_t *child_err,
442                                                    apr_file_t *parent_err);
443 
444 /**
445  * Set which directory the child process should start executing in.
446  * @param attr The procattr we care about.
447  * @param dir Which dir to start in.  By default, this is the same dir as
448  *            the parent currently resides in, when the createprocess call
449  *            is made.
450  */
451 APR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr,
452                                               const char *dir);
453 
454 /**
455  * Set what type of command the child process will call.
456  * @param attr The procattr we care about.
457  * @param cmd The type of command.  One of:
458  * <PRE>
459  *            APR_SHELLCMD     --  Anything that the shell can handle
460  *            APR_PROGRAM      --  Executable program   (default)
461  *            APR_PROGRAM_ENV  --  Executable program, copy environment
462  *            APR_PROGRAM_PATH --  Executable program on PATH, copy env
463  * </PRE>
464  */
465 APR_DECLARE(apr_status_t) apr_procattr_cmdtype_set(apr_procattr_t *attr,
466                                                   apr_cmdtype_e cmd);
467 
468 /**
469  * Determine if the child should start in detached state.
470  * @param attr The procattr we care about.
471  * @param detach Should the child start in detached state?  Default is no.
472  */
473 APR_DECLARE(apr_status_t) apr_procattr_detach_set(apr_procattr_t *attr,
474                                                  apr_int32_t detach);
475 
476 #if APR_HAVE_STRUCT_RLIMIT
477 /**
478  * Set the Resource Utilization limits when starting a new process.
479  * @param attr The procattr we care about.
480  * @param what Which limit to set, one of:
481  * <PRE>
482  *                 APR_LIMIT_CPU
483  *                 APR_LIMIT_MEM
484  *                 APR_LIMIT_NPROC
485  *                 APR_LIMIT_NOFILE
486  * </PRE>
487  * @param limit Value to set the limit to.
488  */
489 APR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr,
490                                                 apr_int32_t what,
491                                                 struct rlimit *limit);
492 #endif
493 
494 /**
495  * Specify an error function to be called in the child process if APR
496  * encounters an error in the child prior to running the specified program.
497  * @param attr The procattr describing the child process to be created.
498  * @param errfn The function to call in the child process.
499  * @remark At the present time, it will only be called from apr_proc_create()
500  *         on platforms where fork() is used.  It will never be called on other
501  *         platforms, on those platforms apr_proc_create() will return the error
502  *         in the parent process rather than invoke the callback in the now-forked
503  *         child process.
504  */
505 APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
506                                                        apr_child_errfn_t *errfn);
507 
508 /**
509  * Specify that apr_proc_create() should do whatever it can to report
510  * failures to the caller of apr_proc_create(), rather than find out in
511  * the child.
512  * @param attr The procattr describing the child process to be created.
513  * @param chk Flag to indicate whether or not extra work should be done
514  *            to try to report failures to the caller.
515  * @remark This flag only affects apr_proc_create() on platforms where
516  *         fork() is used.  This leads to extra overhead in the calling
517  *         process, but that may help the application handle such
518  *         errors more gracefully.
519  */
520 APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
521                                                        apr_int32_t chk);
522 
523 /**
524  * Determine if the child should start in its own address space or using the
525  * current one from its parent
526  * @param attr The procattr we care about.
527  * @param addrspace Should the child start in its own address space?  Default
528  *                  is no on NetWare and yes on other platforms.
529  */
530 APR_DECLARE(apr_status_t) apr_procattr_addrspace_set(apr_procattr_t *attr,
531                                                        apr_int32_t addrspace);
532 
533 /**
534  * Set the username used for running process
535  * @param attr The procattr we care about.
536  * @param username The username used
537  * @param password User password if needed. Password is needed on WIN32
538  *                 or any other platform having
539  *                 APR_PROCATTR_USER_SET_REQUIRES_PASSWORD set.
540  */
541 APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr,
542                                                 const char *username,
543                                                 const char *password);
544 
545 /**
546  * Set the group used for running process
547  * @param attr The procattr we care about.
548  * @param groupname The group name  used
549  */
550 APR_DECLARE(apr_status_t) apr_procattr_group_set(apr_procattr_t *attr,
551                                                  const char *groupname);
552 
553 
554 #if APR_HAS_FORK
555 /**
556  * This is currently the only non-portable call in APR.  This executes
557  * a standard unix fork.
558  * @param proc The resulting process handle.
559  * @param cont The pool to use.
560  * @remark returns APR_INCHILD for the child, and APR_INPARENT for the parent
561  * or an error.
562  */
563 APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *cont);
564 #endif
565 
566 /**
567  * Create a new process and execute a new program within that process.
568  * @param new_proc The resulting process handle.
569  * @param progname The program to run
570  * @param args the arguments to pass to the new program.  The first
571  *             one should be the program name.
572  * @param env The new environment table for the new process.  This
573  *            should be a list of NULL-terminated strings. This argument
574  *            is ignored for APR_PROGRAM_ENV, APR_PROGRAM_PATH, and
575  *            APR_SHELLCMD_ENV types of commands.
576  * @param attr the procattr we should use to determine how to create the new
577  *         process
578  * @param pool The pool to use.
579  * @note This function returns without waiting for the new process to terminate;
580  * use apr_proc_wait for that.
581  */
582 APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new_proc,
583                                           const char *progname,
584                                           const char * const *args,
585                                           const char * const *env,
586                                           apr_procattr_t *attr,
587                                           apr_pool_t *pool);
588 
589 /**
590  * Wait for a child process to die
591  * @param proc The process handle that corresponds to the desired child process
592  * @param exitcode The returned exit status of the child, if a child process
593  *                 dies, or the signal that caused the child to die.
594  *                 On platforms that don't support obtaining this information,
595  *                 the status parameter will be returned as APR_ENOTIMPL.
596  * @param exitwhy Why the child died, the bitwise or of:
597  * <PRE>
598  *            APR_PROC_EXIT         -- process terminated normally
599  *            APR_PROC_SIGNAL       -- process was killed by a signal
600  *            APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
601  *                                     generated a core dump.
602  * </PRE>
603  * @param waithow How should we wait.  One of:
604  * <PRE>
605  *            APR_WAIT   -- block until the child process dies.
606  *            APR_NOWAIT -- return immediately regardless of if the
607  *                          child is dead or not.
608  * </PRE>
609  * @remark The childs status is in the return code to this process.  It is one of:
610  * <PRE>
611  *            APR_CHILD_DONE     -- child is no longer running.
612  *            APR_CHILD_NOTDONE  -- child is still running.
613  * </PRE>
614  */
615 APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
616                                         int *exitcode, apr_exit_why_e *exitwhy,
617                                         apr_wait_how_e waithow);
618 
619 /**
620  * Wait for any current child process to die and return information
621  * about that child.
622  * @param proc Pointer to NULL on entry, will be filled out with child's
623  *             information
624  * @param exitcode The returned exit status of the child, if a child process
625  *                 dies, or the signal that caused the child to die.
626  *                 On platforms that don't support obtaining this information,
627  *                 the status parameter will be returned as APR_ENOTIMPL.
628  * @param exitwhy Why the child died, the bitwise or of:
629  * <PRE>
630  *            APR_PROC_EXIT         -- process terminated normally
631  *            APR_PROC_SIGNAL       -- process was killed by a signal
632  *            APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
633  *                                     generated a core dump.
634  * </PRE>
635  * @param waithow How should we wait.  One of:
636  * <PRE>
637  *            APR_WAIT   -- block until the child process dies.
638  *            APR_NOWAIT -- return immediately regardless of if the
639  *                          child is dead or not.
640  * </PRE>
641  * @param p Pool to allocate child information out of.
642  * @bug Passing proc as a *proc rather than **proc was an odd choice
643  * for some platforms... this should be revisited in 1.0
644  */
645 APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc,
646                                                   int *exitcode,
647                                                   apr_exit_why_e *exitwhy,
648                                                   apr_wait_how_e waithow,
649                                                   apr_pool_t *p);
650 
651 #define APR_PROC_DETACH_FOREGROUND 0    /**< Do not detach */
652 #define APR_PROC_DETACH_DAEMONIZE 1     /**< Detach */
653 
654 /**
655  * Detach the process from the controlling terminal.
656  * @param daemonize set to non-zero if the process should daemonize
657  *                  and become a background process, else it will
658  *                  stay in the foreground.
659  */
660 APR_DECLARE(apr_status_t) apr_proc_detach(int daemonize);
661 
662 /**
663  * Register an other_child -- a child associated to its registered
664  * maintence callback.  This callback is invoked when the process
665  * dies, is disconnected or disappears.
666  * @param proc The child process to register.
667  * @param maintenance maintenance is a function that is invoked with a
668  *                    reason and the data pointer passed here.
669  * @param data Opaque context data passed to the maintenance function.
670  * @param write_fd An fd that is probed for writing.  If it is ever unwritable
671  *                 then the maintenance is invoked with reason
672  *                 OC_REASON_UNWRITABLE.
673  * @param p The pool to use for allocating memory.
674  * @bug write_fd duplicates the proc->out stream, it's really redundant
675  * and should be replaced in the APR 1.0 API with a bitflag of which
676  * proc->in/out/err handles should be health checked.
677  * @bug no platform currently tests the pipes health.
678  */
679 APR_DECLARE(void) apr_proc_other_child_register(apr_proc_t *proc,
680                                            void (*maintenance) (int reason,
681                                                                 void *,
682                                                                 int status),
683                                            void *data, apr_file_t *write_fd,
684                                            apr_pool_t *p);
685 
686 /**
687  * Stop watching the specified other child.
688  * @param data The data to pass to the maintenance function.  This is
689  *             used to find the process to unregister.
690  * @warning Since this can be called by a maintenance function while we're
691  *          scanning the other_children list, all scanners should protect
692  *          themself by loading ocr->next before calling any maintenance
693  *          function.
694  */
695 APR_DECLARE(void) apr_proc_other_child_unregister(void *data);
696 
697 /**
698  * Notify the maintenance callback of a registered other child process
699  * that application has detected an event, such as death.
700  * @param proc The process to check
701  * @param reason The reason code to pass to the maintenance function
702  * @param status The status to pass to the maintenance function
703  * @remark An example of code using this behavior;
704  * <pre>
705  * rv = apr_proc_wait_all_procs(&proc, &exitcode, &status, APR_WAIT, p);
706  * if (APR_STATUS_IS_CHILD_DONE(rv)) {
707  * #if APR_HAS_OTHER_CHILD
708  *     if (apr_proc_other_child_alert(&proc, APR_OC_REASON_DEATH, status)
709  *             == APR_SUCCESS) {
710  *         ;  (already handled)
711  *     }
712  *     else
713  * #endif
714  *         [... handling non-otherchild processes death ...]
715  * </pre>
716  */
717 APR_DECLARE(apr_status_t) apr_proc_other_child_alert(apr_proc_t *proc,
718                                                      int reason,
719                                                      int status);
720 
721 /**
722  * Test one specific other child processes and invoke the maintenance callback
723  * with the appropriate reason code, if still running, or the appropriate reason
724  * code if the process is no longer healthy.
725  * @param ocr The registered other child
726  * @param reason The reason code (e.g. APR_OC_REASON_RESTART) if still running
727  */
728 APR_DECLARE(void) apr_proc_other_child_refresh(apr_other_child_rec_t *ocr,
729                                                int reason);
730 
731 /**
732  * Test all registered other child processes and invoke the maintenance callback
733  * with the appropriate reason code, if still running, or the appropriate reason
734  * code if the process is no longer healthy.
735  * @param reason The reason code (e.g. APR_OC_REASON_RESTART) to running processes
736  */
737 APR_DECLARE(void) apr_proc_other_child_refresh_all(int reason);
738 
739 /**
740  * Terminate a process.
741  * @param proc The process to terminate.
742  * @param sig How to kill the process.
743  */
744 APR_DECLARE(apr_status_t) apr_proc_kill(apr_proc_t *proc, int sig);
745 
746 /**
747  * Register a process to be killed when a pool dies.
748  * @param a The pool to use to define the processes lifetime
749  * @param proc The process to register
750  * @param how How to kill the process, one of:
751  * <PRE>
752  *         APR_KILL_NEVER         -- process is never sent any signals
753  *         APR_KILL_ALWAYS        -- process is sent SIGKILL on apr_pool_t cleanup
754  *         APR_KILL_AFTER_TIMEOUT -- SIGTERM, wait 3 seconds, SIGKILL
755  *         APR_JUST_WAIT          -- wait forever for the process to complete
756  *         APR_KILL_ONLY_ONCE     -- send SIGTERM and then wait
757  * </PRE>
758  */
759 APR_DECLARE(void) apr_pool_note_subprocess(apr_pool_t *a, apr_proc_t *proc,
760                                            apr_kill_conditions_e how);
761 
762 #if APR_HAS_THREADS
763 
764 #if (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2)
765 
766 /**
767  * Setup the process for a single thread to be used for all signal handling.
768  * @warning This must be called before any threads are created
769  */
770 APR_DECLARE(apr_status_t) apr_setup_signal_thread(void);
771 
772 /**
773  * Make the current thread listen for signals.  This thread will loop
774  * forever, calling a provided function whenever it receives a signal.  That
775  * functions should return 1 if the signal has been handled, 0 otherwise.
776  * @param signal_handler The function to call when a signal is received
777  * apr_status_t apr_signal_thread((int)(*signal_handler)(int signum))
778  */
779 APR_DECLARE(apr_status_t) apr_signal_thread(int(*signal_handler)(int signum));
780 
781 #endif /* (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2) */
782 
783 /**
784  * Get the child-pool used by the thread from the thread info.
785  * @return apr_pool_t the pool
786  */
787 APR_POOL_DECLARE_ACCESSOR(thread);
788 
789 #endif /* APR_HAS_THREADS */
790 
791 /** @} */
792 
793 #ifdef __cplusplus
794 }
795 #endif
796 
797 #endif  /* ! APR_THREAD_PROC_H */
798 
799