apr_thread_proc.h revision 251875
1139825Simp/* Licensed to the Apache Software Foundation (ASF) under one or more
298542Smckusick * contributor license agreements.  See the NOTICE file distributed with
398542Smckusick * this work for additional information regarding copyright ownership.
498542Smckusick * The ASF licenses this file to You under the Apache License, Version 2.0
598542Smckusick * (the "License"); you may not use this file except in compliance with
698542Smckusick * the License.  You may obtain a copy of the License at
798542Smckusick *
898542Smckusick *     http://www.apache.org/licenses/LICENSE-2.0
998542Smckusick *
1098542Smckusick * Unless required by applicable law or agreed to in writing, software
11136721Srwatson * distributed under the License is distributed on an "AS IS" BASIS,
12136721Srwatson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13136721Srwatson * See the License for the specific language governing permissions and
14136721Srwatson * limitations under the License.
15136721Srwatson */
16136721Srwatson
17136721Srwatson#ifndef APR_THREAD_PROC_H
18136721Srwatson#define APR_THREAD_PROC_H
19136721Srwatson
20136721Srwatson/**
21136721Srwatson * @file apr_thread_proc.h
22136721Srwatson * @brief APR Thread and Process Library
23136721Srwatson */
24136721Srwatson
25136721Srwatson#include "apr.h"
26136721Srwatson#include "apr_file_io.h"
27136721Srwatson#include "apr_pools.h"
28136721Srwatson#include "apr_errno.h"
29136721Srwatson
30136721Srwatson#if APR_HAVE_STRUCT_RLIMIT
31136721Srwatson#include <sys/time.h>
321541Srgrimes#include <sys/resource.h>
331541Srgrimes#endif
341541Srgrimes
351541Srgrimes#ifdef __cplusplus
361541Srgrimesextern "C" {
371541Srgrimes#endif /* __cplusplus */
381541Srgrimes
391541Srgrimes/**
401541Srgrimes * @defgroup apr_thread_proc Threads and Process Functions
411541Srgrimes * @ingroup APR
421541Srgrimes * @{
431541Srgrimes */
441541Srgrimes
451541Srgrimestypedef enum {
461541Srgrimes    APR_SHELLCMD,           /**< use the shell to invoke the program */
471541Srgrimes    APR_PROGRAM,            /**< invoke the program directly, no copied env */
481541Srgrimes    APR_PROGRAM_ENV,        /**< invoke the program, replicating our environment */
491541Srgrimes    APR_PROGRAM_PATH,       /**< find program on PATH, use our environment */
501541Srgrimes    APR_SHELLCMD_ENV        /**< use the shell to invoke the program,
511541Srgrimes                             *   replicating our environment
521541Srgrimes                             */
531541Srgrimes} apr_cmdtype_e;
541541Srgrimes
551541Srgrimestypedef enum {
561541Srgrimes    APR_WAIT,           /**< wait for the specified process to finish */
571541Srgrimes    APR_NOWAIT          /**< do not wait -- just see if it has finished */
581541Srgrimes} apr_wait_how_e;
5922521Sdyson
601541Srgrimes/* I am specifically calling out the values so that the macros below make
611541Srgrimes * more sense.  Yes, I know I don't need to, but I am hoping this makes what
62116192Sobrien * I am doing more clear.  If you want to add more reasons to exit, continue
63116192Sobrien * to use bitmasks.
64116192Sobrien */
651541Srgrimestypedef enum {
661541Srgrimes    APR_PROC_EXIT = 1,          /**< process exited normally */
6760041Sphk    APR_PROC_SIGNAL = 2,        /**< process exited due to a signal */
681541Srgrimes    APR_PROC_SIGNAL_CORE = 4    /**< process exited and dumped a core file */
6931561Sbde} apr_exit_why_e;
7034266Sjulian
711541Srgrimes/** did we exit the process */
721541Srgrimes#define APR_PROC_CHECK_EXIT(x)        (x & APR_PROC_EXIT)
731541Srgrimes/** did we get a signal */
741541Srgrimes#define APR_PROC_CHECK_SIGNALED(x)    (x & APR_PROC_SIGNAL)
751541Srgrimes/** did we get core */
76118969Sphk#define APR_PROC_CHECK_CORE_DUMP(x)   (x & APR_PROC_SIGNAL_CORE)
77118969Sphk
781541Srgrimes/** @see apr_procattr_io_set */
791541Srgrimes#define APR_NO_PIPE          0
801541Srgrimes/** @see apr_procattr_io_set and apr_file_pipe_create_ex */
811541Srgrimes#define APR_FULL_BLOCK       1
821541Srgrimes/** @see apr_procattr_io_set and apr_file_pipe_create_ex */
8396755Strhodes#define APR_FULL_NONBLOCK    2
841541Srgrimes/** @see apr_procattr_io_set */
851541Srgrimes#define APR_PARENT_BLOCK     3
8698542Smckusick/** @see apr_procattr_io_set */
8798542Smckusick#define APR_CHILD_BLOCK      4
881541Srgrimes/** @see apr_procattr_io_set */
891549Srgrimes#define APR_NO_FILE          8
9098542Smckusick
9198542Smckusick/** @see apr_file_pipe_create_ex */
9234266Sjulian#define APR_READ_BLOCK       3
9355799Smckusick/** @see apr_file_pipe_create_ex */
94100344Smckusick#define APR_WRITE_BLOCK      4
9598542Smckusick
9634266Sjulian/** @see apr_procattr_io_set
9798542Smckusick * @note Win32 only effective with version 1.2.12, portably introduced in 1.3.0
981541Srgrimes */
99140705Sjeff#define APR_NO_FILE          8
1001541Srgrimes
10122521Sdyson/** @see apr_procattr_limit_set */
10298542Smckusick#define APR_LIMIT_CPU        0
10398542Smckusick/** @see apr_procattr_limit_set */
10498542Smckusick#define APR_LIMIT_MEM        1
105174973Skib/** @see apr_procattr_limit_set */
10657446Sdillon#define APR_LIMIT_NPROC      2
107180758Skib/** @see apr_procattr_limit_set */
108223114Smckusick#define APR_LIMIT_NOFILE     3
109223114Smckusick
110248521Skib/**
1111541Srgrimes * @defgroup APR_OC Other Child Flags
11234266Sjulian * @{
113100344Smckusick */
11434266Sjulian#define APR_OC_REASON_DEATH         0     /**< child has died, caller must call
115140705Sjeff                                           * unregister still */
11698542Smckusick#define APR_OC_REASON_UNWRITABLE    1     /**< write_fd is unwritable */
11798542Smckusick#define APR_OC_REASON_RESTART       2     /**< a restart is occuring, perform
118222958Sjeff                                           * any necessary cleanup (including
11934266Sjulian                                           * sending a special signal to child)
12098542Smckusick                                           */
12198542Smckusick#define APR_OC_REASON_UNREGISTER    3     /**< unregister has been called, do
122100344Smckusick                                           * whatever is necessary (including
123100344Smckusick                                           * kill the child) */
12422521Sdyson#define APR_OC_REASON_LOST          4     /**< somehow the child exited without
1251541Srgrimes                                           * us knowing ... buggy os? */
126248521Skib#define APR_OC_REASON_RUNNING       5     /**< a health check is occuring,
1271541Srgrimes                                           * for most maintainence functions
128207141Sjeff                                           * this is a no-op.
129207141Sjeff                                           */
1301541Srgrimes/** @} */
1311541Srgrimes
1321541Srgrimes/** The APR process type */
1331541Srgrimestypedef struct apr_proc_t {
1341541Srgrimes    /** The process ID */
13598542Smckusick    pid_t pid;
13698542Smckusick    /** Parent's side of pipe to child's stdin */
13798542Smckusick    apr_file_t *in;
1381541Srgrimes    /** Parent's side of pipe to child's stdout */
1391541Srgrimes    apr_file_t *out;
140140705Sjeff    /** Parent's side of pipe to child's stdouterr */
141100344Smckusick    apr_file_t *err;
142100344Smckusick#if APR_HAS_PROC_INVOKED || defined(DOXYGEN)
143187790Srwatson    /** Diagnositics/debugging string of the command invoked for
144187790Srwatson     *  this process [only present if APR_HAS_PROC_INVOKED is true]
1451541Srgrimes     * @remark Only enabled on Win32 by default.
1461541Srgrimes     * @bug This should either always or never be present in release
14734266Sjulian     * builds - since it breaks binary compatibility.  We may enable
14834266Sjulian     * it always in APR 1.0 yet leave it undefined in most cases.
149100344Smckusick     */
15034266Sjulian    char *invoked;
15124775Sbde#endif
152100344Smckusick#if defined(WIN32) || defined(DOXYGEN)
153100344Smckusick    /** (Win32 only) Creator's handle granting access to the process
1541541Srgrimes     * @remark This handle is closed and reset to NULL in every case
155100344Smckusick     * corresponding to a waitpid() on Unix which returns the exit status.
1561541Srgrimes     * Therefore Win32 correspond's to Unix's zombie reaping characteristics
1571541Srgrimes     * and avoids potential handle leaks.
1581541Srgrimes     */
1591541Srgrimes    HANDLE hproc;
1601541Srgrimes#endif
1611541Srgrimes} apr_proc_t;
1621541Srgrimes
1631541Srgrimes/**
16422521Sdyson * The prototype for APR child errfn functions.  (See the description
16598658Sdillon * of apr_procattr_child_errfn_set() for more information.)
16698658Sdillon * It is passed the following parameters:
167100344Smckusick * @param pool Pool associated with the apr_proc_t.  If your child
16824775Sbde *             error function needs user data, associate it with this
16922521Sdyson *             pool.
1701541Srgrimes * @param err APR error code describing the error
1711541Srgrimes * @param description Text description of type of processing which failed
1721541Srgrimes */
1731541Srgrimestypedef void (apr_child_errfn_t)(apr_pool_t *proc, apr_status_t err,
1746864Sdg                                 const char *description);
17598542Smckusick
1761541Srgrimes/** Opaque Thread structure. */
1771541Srgrimestypedef struct apr_thread_t           apr_thread_t;
1781541Srgrimes
1791541Srgrimes/** Opaque Thread attributes structure. */
1801541Srgrimestypedef struct apr_threadattr_t       apr_threadattr_t;
1811541Srgrimes
1821541Srgrimes/** Opaque Process attributes structure. */
1831541Srgrimestypedef struct apr_procattr_t         apr_procattr_t;
1841541Srgrimes
18522521Sdyson/** Opaque control variable for one-time atomic variables.  */
1861541Srgrimestypedef struct apr_thread_once_t      apr_thread_once_t;
1871541Srgrimes
1881541Srgrimes/** Opaque thread private address space. */
1891541Srgrimestypedef struct apr_threadkey_t        apr_threadkey_t;
1906864Sdg
1911541Srgrimes/** Opaque record of child process. */
192140705Sjefftypedef struct apr_other_child_rec_t  apr_other_child_rec_t;
193100344Smckusick
19498542Smckusick/**
195187790Srwatson * The prototype for any APR thread worker functions.
196187790Srwatson */
1971541Srgrimestypedef void *(APR_THREAD_FUNC *apr_thread_start_t)(apr_thread_t*, void*);
1981541Srgrimes
19934266Sjuliantypedef enum {
20034266Sjulian    APR_KILL_NEVER,             /**< process is never sent any signals */
20134266Sjulian    APR_KILL_ALWAYS,            /**< process is sent SIGKILL on apr_pool_t cleanup */
20234266Sjulian    APR_KILL_AFTER_TIMEOUT,     /**< SIGTERM, wait 3 seconds, SIGKILL */
2031541Srgrimes    APR_JUST_WAIT,              /**< wait forever for the process to complete */
2041541Srgrimes    APR_KILL_ONLY_ONCE          /**< send SIGTERM and then wait */
20524775Sbde} apr_kill_conditions_e;
2061541Srgrimes
2071541Srgrimes/* Thread Function definitions */
2081541Srgrimes
209140705Sjeff#if APR_HAS_THREADS
21022521Sdyson
211100344Smckusick/**
212187790Srwatson * Create and initialize a new threadattr variable
2131541Srgrimes * @param new_attr The newly created threadattr.
2141541Srgrimes * @param cont The pool to use
215248521Skib */
2161541SrgrimesAPR_DECLARE(apr_status_t) apr_threadattr_create(apr_threadattr_t **new_attr,
21798658Sdillon                                                apr_pool_t *cont);
2187695Sdg
21934266Sjulian/**
22034266Sjulian * Set if newly created threads should be created in detached state.
22134266Sjulian * @param attr The threadattr to affect
2221541Srgrimes * @param on Non-zero if detached threads should be created.
223100344Smckusick */
2241541SrgrimesAPR_DECLARE(apr_status_t) apr_threadattr_detach_set(apr_threadattr_t *attr,
22598542Smckusick                                                    apr_int32_t on);
2261541Srgrimes
2271541Srgrimes/**
2281541Srgrimes * Get the detach state for this threadattr.
2291541Srgrimes * @param attr The threadattr to reference
2301541Srgrimes * @return APR_DETACH if threads are to be detached, or APR_NOTDETACH
2311541Srgrimes * if threads are to be joinable.
23243311Sdillon */
2331541SrgrimesAPR_DECLARE(apr_status_t) apr_threadattr_detach_get(apr_threadattr_t *attr);
234173464Sobrien
2351541Srgrimes/**
23698542Smckusick * Set the stack size of newly created threads.
2371541Srgrimes * @param attr The threadattr to affect
238223888Skib * @param stacksize The stack size in bytes
2391541Srgrimes */
2401541SrgrimesAPR_DECLARE(apr_status_t) apr_threadattr_stacksize_set(apr_threadattr_t *attr,
2411541Srgrimes                                                       apr_size_t stacksize);
2421541Srgrimes
243100344Smckusick/**
24422521Sdyson * Set the stack guard area size of newly created threads.
24522521Sdyson * @param attr The threadattr to affect
246174973Skib * @param guardsize The stack guard area size in bytes
2471541Srgrimes * @note Thread library implementations commonly use a "guard area"
248140705Sjeff * after each thread's stack which is not readable or writable such that
249248623Smckusick * stack overflows cause a segfault; this consumes e.g. 4K of memory
250248623Smckusick * and increases memory management overhead.  Setting the guard area
251262779Spfg * size to zero hence trades off reliable behaviour on stack overflow
252187790Srwatson * for performance. */
253223888SkibAPR_DECLARE(apr_status_t) apr_threadattr_guardsize_set(apr_threadattr_t *attr,
2541541Srgrimes                                                       apr_size_t guardsize);
255180758Skib
256242520Smckusick/**
2571541Srgrimes * Create a new thread of execution
25822521Sdyson * @param new_thread The newly created thread handle.
259174973Skib * @param attr The threadattr to use to determine how to create the thread
260248521Skib * @param func The function to start the new thread in
26122521Sdyson * @param data Any data to be passed to the starting function
2627695Sdg * @param cont The pool to use
26334266Sjulian */
26434266SjulianAPR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new_thread,
26534266Sjulian                                            apr_threadattr_t *attr,
26634266Sjulian                                            apr_thread_start_t func,
26734266Sjulian                                            void *data, apr_pool_t *cont);
26834266Sjulian
26934266Sjulian/**
27034266Sjulian * stop the current thread
27134266Sjulian * @param thd The thread to stop
27248801Smckusick * @param retval The return value to pass back to any thread that cares
27348801Smckusick */
27448801SmckusickAPR_DECLARE(apr_status_t) apr_thread_exit(apr_thread_t *thd,
27534266Sjulian                                          apr_status_t retval);
27634266Sjulian
277100344Smckusick/**
27822521Sdyson * block until the desired thread stops executing.
2791541Srgrimes * @param retval The return value from the dead thread.
2801541Srgrimes * @param thd The thread to join
2811541Srgrimes */
2821541SrgrimesAPR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval,
2831541Srgrimes                                          apr_thread_t *thd);
284222958Sjeff
2851541Srgrimes/**
2861541Srgrimes * force the current thread to yield the processor
2871541Srgrimes */
2881541SrgrimesAPR_DECLARE(void) apr_thread_yield(void);
2891541Srgrimes
29022521Sdyson/**
2911541Srgrimes * Initialize the control variable for apr_thread_once.  If this isn't
29298542Smckusick * called, apr_initialize won't work.
2931541Srgrimes * @param control The control variable to initialize
2941541Srgrimes * @param p The pool to allocate data from.
2951541Srgrimes */
2961541SrgrimesAPR_DECLARE(apr_status_t) apr_thread_once_init(apr_thread_once_t **control,
2971541Srgrimes                                               apr_pool_t *p);
29813490Sdyson
2991541Srgrimes/**
3001541Srgrimes * Run the specified function one time, regardless of how many threads
301140705Sjeff * call it.
302252527Smckusick * @param control The control variable.  The same variable should
303252527Smckusick *                be passed in each time the function is tried to be
304252527Smckusick *                called.  This is how the underlying functions determine
305252527Smckusick *                if the function has ever been called before.
3061541Srgrimes * @param func The function to call.
307248623Smckusick */
308248623SmckusickAPR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
309187790Srwatson                                          void (*func)(void));
310222958Sjeff
3111541Srgrimes/**
312222958Sjeff * detach a thread
313222958Sjeff * @param thd The thread to detach
314222958Sjeff */
315222958SjeffAPR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd);
316222958Sjeff
317222958Sjeff/**
318222958Sjeff * Return the pool associated with the current thread.
319223114Smckusick * @param data The user data associated with the thread.
320223114Smckusick * @param key The key to associate with the data
321223114Smckusick * @param thread The currently open thread.
322223114Smckusick */
323223114SmckusickAPR_DECLARE(apr_status_t) apr_thread_data_get(void **data, const char *key,
32422521Sdyson                                             apr_thread_t *thread);
3251541Srgrimes
326242520Smckusick/**
3271541Srgrimes * Return the pool associated with the current thread.
32822521Sdyson * @param data The user data to associate with the thread.
329174973Skib * @param key The key to use for associating the data with the thread
330111856Sjeff * @param cleanup The cleanup routine to use when the thread is destroyed.
3311541Srgrimes * @param thread The currently open thread.
3327695Sdg */
33334266SjulianAPR_DECLARE(apr_status_t) apr_thread_data_set(void *data, const char *key,
33434266Sjulian                                             apr_status_t (*cleanup) (void *),
33534266Sjulian                                             apr_thread_t *thread);
33634266Sjulian
33734266Sjulian/**
33834266Sjulian * Create and initialize a new thread private address space
33934266Sjulian * @param key The thread private handle.
34034266Sjulian * @param dest The destructor to use when freeing the private memory.
34134266Sjulian * @param cont The pool to use
34243311Sdillon */
34334266SjulianAPR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key,
34434266Sjulian                                                    void (*dest)(void *),
34534266Sjulian                                                    apr_pool_t *cont);
3461541Srgrimes
3471541Srgrimes/**
34857446Sdillon * Get a pointer to the thread private memory
34957446Sdillon * @param new_mem The data stored in private memory
3501541Srgrimes * @param key The handle for the desired thread private memory
3511541Srgrimes */
3521541SrgrimesAPR_DECLARE(apr_status_t) apr_threadkey_private_get(void **new_mem,
3531541Srgrimes                                                 apr_threadkey_t *key);
354100344Smckusick
3551541Srgrimes/**
3561541Srgrimes * Set the data to be stored in thread private memory
35732286Sdyson * @param priv The data to be stored in private memory
35832286Sdyson * @param key The handle for the desired thread private memory
3591541Srgrimes */
3601541SrgrimesAPR_DECLARE(apr_status_t) apr_threadkey_private_set(void *priv,
3611541Srgrimes                                                 apr_threadkey_t *key);
3621541Srgrimes
36362976Smckusick/**
36462976Smckusick * Free the thread private memory
36598658Sdillon * @param key The handle for the desired thread private memory
366223888Skib */
36798542SmckusickAPR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key);
36862976Smckusick
36962976Smckusick/**
37062976Smckusick * Return the pool associated with the current threadkey.
3711541Srgrimes * @param data The user data associated with the threadkey.
3721541Srgrimes * @param key The key associated with the data
3731541Srgrimes * @param threadkey The currently open threadkey.
374140705Sjeff */
375252527SmckusickAPR_DECLARE(apr_status_t) apr_threadkey_data_get(void **data, const char *key,
376252527Smckusick                                                apr_threadkey_t *threadkey);
377252527Smckusick
378252527Smckusick/**
379252527Smckusick * Return the pool associated with the current threadkey.
380252527Smckusick * @param data The data to set.
381252527Smckusick * @param key The key to associate with the data.
382252527Smckusick * @param cleanup The cleanup routine to use when the file is destroyed.
383242520Smckusick * @param threadkey The currently open threadkey.
384242520Smckusick */
385222958SjeffAPR_DECLARE(apr_status_t) apr_threadkey_data_set(void *data, const char *key,
386222958Sjeff                                                apr_status_t (*cleanup) (void *),
3873487Sphk                                                apr_threadkey_t *threadkey);
3881541Srgrimes
389222958Sjeff#endif
390222958Sjeff
391222958Sjeff/**
392222958Sjeff * Create and initialize a new procattr variable
393222958Sjeff * @param new_attr The newly created procattr.
394222958Sjeff * @param cont The pool to use
395222958Sjeff */
396223114SmckusickAPR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new_attr,
397223114Smckusick                                                  apr_pool_t *cont);
398223114Smckusick
399223114Smckusick/**
400223114Smckusick * Determine if any of stdin, stdout, or stderr should be linked to pipes
40122521Sdyson * when starting a child process.
4021541Srgrimes * @param attr The procattr we care about.
4031541Srgrimes * @param in Should stdin be a pipe back to the parent?
40422521Sdyson * @param out Should stdout be a pipe back to the parent?
405174973Skib * @param err Should stderr be a pipe back to the parent?
406248521Skib * @note If APR_NO_PIPE, there will be no special channel, the child
4071541Srgrimes * inherits the parent's corresponding stdio stream.  If APR_NO_FILE is
40898658Sdillon * specified, that corresponding stream is closed in the child (and will
4097695Sdg * be INVALID_HANDLE_VALUE when inspected on Win32). This can have ugly
41034266Sjulian * side effects, as the next file opened in the child on Unix will fall
41134266Sjulian * into the stdio stream fd slot!
41234266Sjulian */
4131541SrgrimesAPR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr,
4141541Srgrimes                                             apr_int32_t in, apr_int32_t out,
4151541Srgrimes                                             apr_int32_t err);
4161541Srgrimes
4171541Srgrimes/**
418100344Smckusick * Set the child_in and/or parent_in values to existing apr_file_t values.
4191541Srgrimes * @param attr The procattr we care about.
4201541Srgrimes * @param child_in apr_file_t value to use as child_in. Must be a valid file.
42132286Sdyson * @param parent_in apr_file_t value to use as parent_in. Must be a valid file.
42232286Sdyson * @remark  This is NOT a required initializer function. This is
4231541Srgrimes *          useful if you have already opened a pipe (or multiple files)
4241541Srgrimes *          that you wish to use, perhaps persistently across multiple
425223888Skib *          process invocations - such as a log file. You can save some
42698542Smckusick *          extra function calls by not creating your own pipe since this
4271541Srgrimes *          creates one in the process space for you.
4281541Srgrimes * @bug Note that calling this function with two NULL files on some platforms
4291541Srgrimes * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
43098658Sdillon * is it supported.  @see apr_procattr_io_set instead for simple pipes.
431105422Sdillon */
432290638SkibAPR_DECLARE(apr_status_t) apr_procattr_child_in_set(struct apr_procattr_t *attr,
433290638Skib                                                  apr_file_t *child_in,
434290638Skib                                                  apr_file_t *parent_in);
435105422Sdillon
436105422Sdillon/**
437248521Skib * Set the child_out and parent_out values to existing apr_file_t values.
438105422Sdillon * @param attr The procattr we care about.
439248521Skib * @param child_out apr_file_t value to use as child_out. Must be a valid file.
440248521Skib * @param parent_out apr_file_t value to use as parent_out. Must be a valid file.
441105422Sdillon * @remark This is NOT a required initializer function. This is
4421541Srgrimes *         useful if you have already opened a pipe (or multiple files)
4431541Srgrimes *         that you wish to use, perhaps persistently across multiple
44422521Sdyson *         process invocations - such as a log file.
4451541Srgrimes * @bug Note that calling this function with two NULL files on some platforms
4461541Srgrimes * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
447248521Skib * is it supported.  @see apr_procattr_io_set instead for simple pipes.
4481541Srgrimes */
4491541SrgrimesAPR_DECLARE(apr_status_t) apr_procattr_child_out_set(struct apr_procattr_t *attr,
450223888Skib                                                   apr_file_t *child_out,
45198542Smckusick                                                   apr_file_t *parent_out);
4521541Srgrimes
45322521Sdyson/**
454223888Skib * Set the child_err and parent_err values to existing apr_file_t values.
45522521Sdyson * @param attr The procattr we care about.
456105669Smckusick * @param child_err apr_file_t value to use as child_err. Must be a valid file.
457105669Smckusick * @param parent_err apr_file_t value to use as parent_err. Must be a valid file.
458105669Smckusick * @remark This is NOT a required initializer function. This is
459105669Smckusick *         useful if you have already opened a pipe (or multiple files)
460105669Smckusick *         that you wish to use, perhaps persistently across multiple
461105669Smckusick *         process invocations - such as a log file.
46222521Sdyson * @bug Note that calling this function with two NULL files on some platforms
46322521Sdyson * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
46455799Smckusick * is it supported.  @see apr_procattr_io_set instead for simple pipes.
46555799Smckusick */
46655799SmckusickAPR_DECLARE(apr_status_t) apr_procattr_child_err_set(struct apr_procattr_t *attr,
46755799Smckusick                                                   apr_file_t *child_err,
46855799Smckusick                                                   apr_file_t *parent_err);
469249582Sgabor
47055799Smckusick/**
471207141Sjeff * Set which directory the child process should start executing in.
472207141Sjeff * @param attr The procattr we care about.
47322521Sdyson * @param dir Which dir to start in.  By default, this is the same dir as
474233438Smckusick *            the parent currently resides in, when the createprocess call
475174973Skib *            is made.
476174973Skib */
477174973SkibAPR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr,
478174973Skib                                              const char *dir);
479174973Skib
480174973Skib/**
481174973Skib * Set what type of command the child process will call.
482174973Skib * @param attr The procattr we care about.
483174973Skib * @param cmd The type of command.  One of:
484174973Skib * <PRE>
485174973Skib *            APR_SHELLCMD     --  Anything that the shell can handle
486174973Skib *            APR_PROGRAM      --  Executable program   (default)
48722521Sdyson *            APR_PROGRAM_ENV  --  Executable program, copy environment
48822521Sdyson *            APR_PROGRAM_PATH --  Executable program on PATH, copy env
48957446Sdillon * </PRE>
49022521Sdyson */
49157446SdillonAPR_DECLARE(apr_status_t) apr_procattr_cmdtype_set(apr_procattr_t *attr,
49257446Sdillon                                                  apr_cmdtype_e cmd);
49357446Sdillon
49457446Sdillon/**
49557446Sdillon * Determine if the child should start in detached state.
49657446Sdillon * @param attr The procattr we care about.
49757446Sdillon * @param detach Should the child start in detached state?  Default is no.
49857446Sdillon */
49957446SdillonAPR_DECLARE(apr_status_t) apr_procattr_detach_set(apr_procattr_t *attr,
50098542Smckusick                                                 apr_int32_t detach);
50157446Sdillon
502100344Smckusick#if APR_HAVE_STRUCT_RLIMIT
50357446Sdillon/**
50457446Sdillon * Set the Resource Utilization limits when starting a new process.
50557446Sdillon * @param attr The procattr we care about.
50657446Sdillon * @param what Which limit to set, one of:
50757446Sdillon * <PRE>
50857446Sdillon *                 APR_LIMIT_CPU
50957446Sdillon *                 APR_LIMIT_MEM
51057446Sdillon *                 APR_LIMIT_NPROC
51122521Sdyson *                 APR_LIMIT_NOFILE
51222521Sdyson * </PRE>
51322521Sdyson * @param limit Value to set the limit to.
51422521Sdyson */
51522521SdysonAPR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr,
51698542Smckusick                                                apr_int32_t what,
51722521Sdyson                                                struct rlimit *limit);
518100344Smckusick#endif
51922521Sdyson
52022521Sdyson/**
521233438Smckusick * Specify an error function to be called in the child process if APR
522175068Skib * encounters an error in the child prior to running the specified program.
523175068Skib * @param attr The procattr describing the child process to be created.
524175068Skib * @param errfn The function to call in the child process.
525175068Skib * @remark At the present time, it will only be called from apr_proc_create()
526175068Skib *         on platforms where fork() is used.  It will never be called on other
527175068Skib *         platforms, on those platforms apr_proc_create() will return the error
528223127Smckusick *         in the parent process rather than invoke the callback in the now-forked
529175068Skib *         child process.
53022521Sdyson */
5311541SrgrimesAPR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
53298542Smckusick                                                       apr_child_errfn_t *errfn);
53398542Smckusick
53498542Smckusick/**
53598542Smckusick * Specify that apr_proc_create() should do whatever it can to report
53698542Smckusick * failures to the caller of apr_proc_create(), rather than find out in
53798542Smckusick * the child.
53898542Smckusick * @param attr The procattr describing the child process to be created.
53998542Smckusick * @param chk Flag to indicate whether or not extra work should be done
54098542Smckusick *            to try to report failures to the caller.
54198542Smckusick * @remark This flag only affects apr_proc_create() on platforms where
54298542Smckusick *         fork() is used.  This leads to extra overhead in the calling
54398542Smckusick *         process, but that may help the application handle such
54498542Smckusick *         errors more gracefully.
545100344Smckusick */
54698542SmckusickAPR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
54798542Smckusick                                                       apr_int32_t chk);
54898542Smckusick
549140705Sjeff/**
55098542Smckusick * Determine if the child should start in its own address space or using the
55198542Smckusick * current one from its parent
55298542Smckusick * @param attr The procattr we care about.
553174973Skib * @param addrspace Should the child start in its own address space?  Default
55498542Smckusick *                  is no on NetWare and yes on other platforms.
55598542Smckusick */
556180758SkibAPR_DECLARE(apr_status_t) apr_procattr_addrspace_set(apr_procattr_t *attr,
557223114Smckusick                                                       apr_int32_t addrspace);
558223114Smckusick
559248521Skib/**
56098542Smckusick * Set the username used for running process
56198542Smckusick * @param attr The procattr we care about.
562100344Smckusick * @param username The username used
56398542Smckusick * @param password User password if needed. Password is needed on WIN32
564140705Sjeff *                 or any other platform having
56598542Smckusick *                 APR_PROCATTR_USER_SET_REQUIRES_PASSWORD set.
56698542Smckusick */
567222958SjeffAPR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr,
56898542Smckusick                                                const char *username,
56998542Smckusick                                                const char *password);
57098542Smckusick
57198542Smckusick/**
57298542Smckusick * Set the group used for running process
573248521Skib * @param attr The procattr we care about.
57498542Smckusick * @param groupname The group name  used
575207141Sjeff */
576207141SjeffAPR_DECLARE(apr_status_t) apr_procattr_group_set(apr_procattr_t *attr,
577207141Sjeff                                                 const char *groupname);
57898542Smckusick
579100344Smckusick
580100344Smckusick#if APR_HAS_FORK
581100344Smckusick/**
582100344Smckusick * This is currently the only non-portable call in APR.  This executes
583100344Smckusick * a standard unix fork.
584100344Smckusick * @param proc The resulting process handle.
585100344Smckusick * @param cont The pool to use.
586100344Smckusick * @remark returns APR_INCHILD for the child, and APR_INPARENT for the parent
587100344Smckusick * or an error.
588100344Smckusick */
589100344SmckusickAPR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *cont);
590100344Smckusick#endif
591100344Smckusick
592100344Smckusick/**
593100344Smckusick * Create a new process and execute a new program within that process.
594140705Sjeff * @param new_proc The resulting process handle.
595100344Smckusick * @param progname The program to run
596100344Smckusick * @param args the arguments to pass to the new program.  The first
597100344Smckusick *             one should be the program name.
598100344Smckusick * @param env The new environment table for the new process.  This
599187790Srwatson *            should be a list of NULL-terminated strings. This argument
600100344Smckusick *            is ignored for APR_PROGRAM_ENV, APR_PROGRAM_PATH, and
601100344Smckusick *            APR_SHELLCMD_ENV types of commands.
602100344Smckusick * @param attr the procattr we should use to determine how to create the new
603100344Smckusick *         process
604100344Smckusick * @param pool The pool to use.
605100344Smckusick * @note This function returns without waiting for the new process to terminate;
606100344Smckusick * use apr_proc_wait for that.
607100344Smckusick */
608100344SmckusickAPR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new_proc,
609100344Smckusick                                          const char *progname,
610187790Srwatson                                          const char * const *args,
611100344Smckusick                                          const char * const *env,
612100344Smckusick                                          apr_procattr_t *attr,
613100344Smckusick                                          apr_pool_t *pool);
614100344Smckusick
615100344Smckusick/**
616100344Smckusick * Wait for a child process to die
617100344Smckusick * @param proc The process handle that corresponds to the desired child process
618100344Smckusick * @param exitcode The returned exit status of the child, if a child process
619100344Smckusick *                 dies, or the signal that caused the child to die.
620100344Smckusick *                 On platforms that don't support obtaining this information,
621100344Smckusick *                 the status parameter will be returned as APR_ENOTIMPL.
622100344Smckusick * @param exitwhy Why the child died, the bitwise or of:
623100344Smckusick * <PRE>
624248521Skib *            APR_PROC_EXIT         -- process terminated normally
625248521Skib *            APR_PROC_SIGNAL       -- process was killed by a signal
626100344Smckusick *            APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
627100344Smckusick *                                     generated a core dump.
628100344Smckusick * </PRE>
629100344Smckusick * @param waithow How should we wait.  One of:
630100344Smckusick * <PRE>
631100344Smckusick *            APR_WAIT   -- block until the child process dies.
632100344Smckusick *            APR_NOWAIT -- return immediately regardless of if the
633100344Smckusick *                          child is dead or not.
634100344Smckusick * </PRE>
635100344Smckusick * @remark The childs status is in the return code to this process.  It is one of:
636100344Smckusick * <PRE>
637100344Smckusick *            APR_CHILD_DONE     -- child is no longer running.
638100344Smckusick *            APR_CHILD_NOTDONE  -- child is still running.
639100344Smckusick * </PRE>
640100344Smckusick */
641100344SmckusickAPR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
642248521Skib                                        int *exitcode, apr_exit_why_e *exitwhy,
643248521Skib                                        apr_wait_how_e waithow);
644100344Smckusick
645100344Smckusick/**
646100344Smckusick * Wait for any current child process to die and return information
647100344Smckusick * about that child.
648100344Smckusick * @param proc Pointer to NULL on entry, will be filled out with child's
649100344Smckusick *             information
650100344Smckusick * @param exitcode The returned exit status of the child, if a child process
651140705Sjeff *                 dies, or the signal that caused the child to die.
652100344Smckusick *                 On platforms that don't support obtaining this information,
653100344Smckusick *                 the status parameter will be returned as APR_ENOTIMPL.
654100344Smckusick * @param exitwhy Why the child died, the bitwise or of:
655187790Srwatson * <PRE>
656187790Srwatson *            APR_PROC_EXIT         -- process terminated normally
657100344Smckusick *            APR_PROC_SIGNAL       -- process was killed by a signal
658100344Smckusick *            APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
659100344Smckusick *                                     generated a core dump.
660100344Smckusick * </PRE>
661100344Smckusick * @param waithow How should we wait.  One of:
662100344Smckusick * <PRE>
663100344Smckusick *            APR_WAIT   -- block until the child process dies.
664100344Smckusick *            APR_NOWAIT -- return immediately regardless of if the
665100344Smckusick *                          child is dead or not.
666100344Smckusick * </PRE>
667100344Smckusick * @param p Pool to allocate child information out of.
668100344Smckusick * @bug Passing proc as a *proc rather than **proc was an odd choice
669100344Smckusick * for some platforms... this should be revisited in 1.0
670140705Sjeff */
671100344SmckusickAPR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc,
672100344Smckusick                                                  int *exitcode,
673187790Srwatson                                                  apr_exit_why_e *exitwhy,
674100344Smckusick                                                  apr_wait_how_e waithow,
675100344Smckusick                                                  apr_pool_t *p);
676248521Skib
677100344Smckusick#define APR_PROC_DETACH_FOREGROUND 0    /**< Do not detach */
678100344Smckusick#define APR_PROC_DETACH_DAEMONIZE 1     /**< Detach */
679100344Smckusick
680100344Smckusick/**
681100344Smckusick * Detach the process from the controlling terminal.
682100344Smckusick * @param daemonize set to non-zero if the process should daemonize
683100344Smckusick *                  and become a background process, else it will
684100344Smckusick *                  stay in the foreground.
685100344Smckusick */
686187790SrwatsonAPR_DECLARE(apr_status_t) apr_proc_detach(int daemonize);
687100344Smckusick
688100344Smckusick/**
689100344Smckusick * Register an other_child -- a child associated to its registered
690100344Smckusick * maintence callback.  This callback is invoked when the process
69198542Smckusick * dies, is disconnected or disappears.
69298542Smckusick * @param proc The child process to register.
69398542Smckusick * @param maintenance maintenance is a function that is invoked with a
69498542Smckusick *                    reason and the data pointer passed here.
69598542Smckusick * @param data Opaque context data passed to the maintenance function.
69698542Smckusick * @param write_fd An fd that is probed for writing.  If it is ever unwritable
69798542Smckusick *                 then the maintenance is invoked with reason
69898542Smckusick *                 OC_REASON_UNWRITABLE.
69998542Smckusick * @param p The pool to use for allocating memory.
700140705Sjeff * @bug write_fd duplicates the proc->out stream, it's really redundant
701100344Smckusick * and should be replaced in the APR 1.0 API with a bitflag of which
702248283Skib * proc->in/out/err handles should be health checked.
703248283Skib * @bug no platform currently tests the pipes health.
704248283Skib */
70598542SmckusickAPR_DECLARE(void) apr_proc_other_child_register(apr_proc_t *proc,
70698542Smckusick                                           void (*maintenance) (int reason,
70798542Smckusick                                                                void *,
70898542Smckusick                                                                int status),
70998542Smckusick                                           void *data, apr_file_t *write_fd,
710100344Smckusick                                           apr_pool_t *p);
71198542Smckusick
71298542Smckusick/**
713100344Smckusick * Stop watching the specified other child.
714100344Smckusick * @param data The data to pass to the maintenance function.  This is
71598542Smckusick *             used to find the process to unregister.
716100344Smckusick * @warning Since this can be called by a maintenance function while we're
71798542Smckusick *          scanning the other_children list, all scanners should protect
71898542Smckusick *          themself by loading ocr->next before calling any maintenance
71998542Smckusick *          function.
72098542Smckusick */
72198542SmckusickAPR_DECLARE(void) apr_proc_other_child_unregister(void *data);
72298542Smckusick
72398542Smckusick/**
72498542Smckusick * Notify the maintenance callback of a registered other child process
72598542Smckusick * that application has detected an event, such as death.
72698658Sdillon * @param proc The process to check
72798658Sdillon * @param reason The reason code to pass to the maintenance function
728100344Smckusick * @param status The status to pass to the maintenance function
72998542Smckusick * @remark An example of code using this behavior;
730248521Skib * <pre>
731248521Skib * rv = apr_proc_wait_all_procs(&proc, &exitcode, &status, APR_WAIT, p);
73298542Smckusick * if (APR_STATUS_IS_CHILD_DONE(rv)) {
73398542Smckusick * \#if APR_HAS_OTHER_CHILD
73498542Smckusick *     if (apr_proc_other_child_alert(&proc, APR_OC_REASON_DEATH, status)
73598542Smckusick *             == APR_SUCCESS) {
73698542Smckusick *         ;  (already handled)
73798542Smckusick *     }
73898542Smckusick *     else
73998542Smckusick * \#endif
74098542Smckusick *         [... handling non-otherchild processes death ...]
74198542Smckusick * </pre>
74298542Smckusick */
74398542SmckusickAPR_DECLARE(apr_status_t) apr_proc_other_child_alert(apr_proc_t *proc,
74498542Smckusick                                                     int reason,
74598542Smckusick                                                     int status);
74698542Smckusick
747248521Skib/**
748248521Skib * Test one specific other child processes and invoke the maintenance callback
74998542Smckusick * with the appropriate reason code, if still running, or the appropriate reason
75098542Smckusick * code if the process is no longer healthy.
75198542Smckusick * @param ocr The registered other child
75298542Smckusick * @param reason The reason code (e.g. APR_OC_REASON_RESTART) if still running
75398542Smckusick */
75498542SmckusickAPR_DECLARE(void) apr_proc_other_child_refresh(apr_other_child_rec_t *ocr,
755140705Sjeff                                               int reason);
756100344Smckusick
75798542Smckusick/**
758248283Skib * Test all registered other child processes and invoke the maintenance callback
759187790Srwatson * with the appropriate reason code, if still running, or the appropriate reason
76098542Smckusick * code if the process is no longer healthy.
76198542Smckusick * @param reason The reason code (e.g. APR_OC_REASON_RESTART) to running processes
76298542Smckusick */
76398542SmckusickAPR_DECLARE(void) apr_proc_other_child_refresh_all(int reason);
76498542Smckusick
76598542Smckusick/**
76698542Smckusick * Terminate a process.
76798542Smckusick * @param proc The process to terminate.
76898542Smckusick * @param sig How to kill the process.
76998542Smckusick */
77098542SmckusickAPR_DECLARE(apr_status_t) apr_proc_kill(apr_proc_t *proc, int sig);
77198542Smckusick
772140705Sjeff/**
77398542Smckusick * Register a process to be killed when a pool dies.
77498542Smckusick * @param a The pool to use to define the processes lifetime
775187790Srwatson * @param proc The process to register
77698542Smckusick * @param how How to kill the process, one of:
77798542Smckusick * <PRE>
778248521Skib *         APR_KILL_NEVER         -- process is never sent any signals
77998542Smckusick *         APR_KILL_ALWAYS        -- process is sent SIGKILL on apr_pool_t cleanup
78098658Sdillon *         APR_KILL_AFTER_TIMEOUT -- SIGTERM, wait 3 seconds, SIGKILL
78198542Smckusick *         APR_JUST_WAIT          -- wait forever for the process to complete
78298542Smckusick *         APR_KILL_ONLY_ONCE     -- send SIGTERM and then wait
78398542Smckusick * </PRE>
78498542Smckusick */
78598542SmckusickAPR_DECLARE(void) apr_pool_note_subprocess(apr_pool_t *a, apr_proc_t *proc,
786100344Smckusick                                           apr_kill_conditions_e how);
78798542Smckusick
78898542Smckusick#if APR_HAS_THREADS
78998542Smckusick
79098542Smckusick#if (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2)
79198542Smckusick
79298542Smckusick/**
79398542Smckusick * Setup the process for a single thread to be used for all signal handling.
79498542Smckusick * @warning This must be called before any threads are created
79598542Smckusick */
79698542SmckusickAPR_DECLARE(apr_status_t) apr_setup_signal_thread(void);
797173464Sobrien
79898542Smckusick/**
79998542Smckusick * Make the current thread listen for signals.  This thread will loop
80098542Smckusick * forever, calling a provided function whenever it receives a signal.  That
801223888Skib * functions should return 1 if the signal has been handled, 0 otherwise.
80298542Smckusick * @param signal_handler The function to call when a signal is received
80398542Smckusick * apr_status_t apr_signal_thread((int)(*signal_handler)(int signum))
80498542Smckusick */
80598542SmckusickAPR_DECLARE(apr_status_t) apr_signal_thread(int(*signal_handler)(int signum));
806100344Smckusick
80798542Smckusick#endif /* (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2) */
80898542Smckusick
809174973Skib/**
81098542Smckusick * Get the child-pool used by the thread from the thread info.
811140705Sjeff * @return apr_pool_t the pool
812248623Smckusick */
813248623SmckusickAPR_POOL_DECLARE_ACCESSOR(thread);
814262779Spfg
815187790Srwatson#endif /* APR_HAS_THREADS */
816223888Skib
81798542Smckusick/** @} */
818180758Skib
819242520Smckusick#ifdef __cplusplus
82098542Smckusick}
82198542Smckusick#endif
822174973Skib
823248521Skib#endif  /* ! APR_THREAD_PROC_H */
824248521Skib
82598542Smckusick