1251875Speter/* Licensed to the Apache Software Foundation (ASF) under one or more
2251875Speter * contributor license agreements.  See the NOTICE file distributed with
3251875Speter * this work for additional information regarding copyright ownership.
4251875Speter * The ASF licenses this file to You under the Apache License, Version 2.0
5251875Speter * (the "License"); you may not use this file except in compliance with
6251875Speter * the License.  You may obtain a copy of the License at
7251875Speter *
8251875Speter *     http://www.apache.org/licenses/LICENSE-2.0
9251875Speter *
10251875Speter * Unless required by applicable law or agreed to in writing, software
11251875Speter * distributed under the License is distributed on an "AS IS" BASIS,
12251875Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13251875Speter * See the License for the specific language governing permissions and
14251875Speter * limitations under the License.
15251875Speter */
16251875Speter
17251875Speter#ifndef APR_THREAD_PROC_H
18251875Speter#define APR_THREAD_PROC_H
19251875Speter
20251875Speter/**
21251875Speter * @file apr_thread_proc.h
22251875Speter * @brief APR Thread and Process Library
23251875Speter */
24251875Speter
25251875Speter#include "apr.h"
26251875Speter#include "apr_file_io.h"
27251875Speter#include "apr_pools.h"
28251875Speter#include "apr_errno.h"
29251875Speter
30251875Speter#if APR_HAVE_STRUCT_RLIMIT
31251875Speter#include <sys/time.h>
32251875Speter#include <sys/resource.h>
33251875Speter#endif
34251875Speter
35251875Speter#ifdef __cplusplus
36251875Speterextern "C" {
37251875Speter#endif /* __cplusplus */
38251875Speter
39251875Speter/**
40251875Speter * @defgroup apr_thread_proc Threads and Process Functions
41251875Speter * @ingroup APR
42251875Speter * @{
43251875Speter */
44251875Speter
45251875Spetertypedef enum {
46251875Speter    APR_SHELLCMD,           /**< use the shell to invoke the program */
47251875Speter    APR_PROGRAM,            /**< invoke the program directly, no copied env */
48251875Speter    APR_PROGRAM_ENV,        /**< invoke the program, replicating our environment */
49251875Speter    APR_PROGRAM_PATH,       /**< find program on PATH, use our environment */
50251875Speter    APR_SHELLCMD_ENV        /**< use the shell to invoke the program,
51251875Speter                             *   replicating our environment
52251875Speter                             */
53251875Speter} apr_cmdtype_e;
54251875Speter
55251875Spetertypedef enum {
56251875Speter    APR_WAIT,           /**< wait for the specified process to finish */
57251875Speter    APR_NOWAIT          /**< do not wait -- just see if it has finished */
58251875Speter} apr_wait_how_e;
59251875Speter
60251875Speter/* I am specifically calling out the values so that the macros below make
61251875Speter * more sense.  Yes, I know I don't need to, but I am hoping this makes what
62251875Speter * I am doing more clear.  If you want to add more reasons to exit, continue
63251875Speter * to use bitmasks.
64251875Speter */
65251875Spetertypedef enum {
66251875Speter    APR_PROC_EXIT = 1,          /**< process exited normally */
67251875Speter    APR_PROC_SIGNAL = 2,        /**< process exited due to a signal */
68251875Speter    APR_PROC_SIGNAL_CORE = 4    /**< process exited and dumped a core file */
69251875Speter} apr_exit_why_e;
70251875Speter
71251875Speter/** did we exit the process */
72251875Speter#define APR_PROC_CHECK_EXIT(x)        (x & APR_PROC_EXIT)
73251875Speter/** did we get a signal */
74251875Speter#define APR_PROC_CHECK_SIGNALED(x)    (x & APR_PROC_SIGNAL)
75251875Speter/** did we get core */
76251875Speter#define APR_PROC_CHECK_CORE_DUMP(x)   (x & APR_PROC_SIGNAL_CORE)
77251875Speter
78251875Speter/** @see apr_procattr_io_set */
79251875Speter#define APR_NO_PIPE          0
80251875Speter/** @see apr_procattr_io_set and apr_file_pipe_create_ex */
81251875Speter#define APR_FULL_BLOCK       1
82251875Speter/** @see apr_procattr_io_set and apr_file_pipe_create_ex */
83251875Speter#define APR_FULL_NONBLOCK    2
84251875Speter/** @see apr_procattr_io_set */
85251875Speter#define APR_PARENT_BLOCK     3
86251875Speter/** @see apr_procattr_io_set */
87251875Speter#define APR_CHILD_BLOCK      4
88251875Speter/** @see apr_procattr_io_set */
89251875Speter#define APR_NO_FILE          8
90251875Speter
91251875Speter/** @see apr_file_pipe_create_ex */
92251875Speter#define APR_READ_BLOCK       3
93251875Speter/** @see apr_file_pipe_create_ex */
94251875Speter#define APR_WRITE_BLOCK      4
95251875Speter
96251875Speter/** @see apr_procattr_io_set
97251875Speter * @note Win32 only effective with version 1.2.12, portably introduced in 1.3.0
98251875Speter */
99251875Speter#define APR_NO_FILE          8
100251875Speter
101251875Speter/** @see apr_procattr_limit_set */
102251875Speter#define APR_LIMIT_CPU        0
103251875Speter/** @see apr_procattr_limit_set */
104251875Speter#define APR_LIMIT_MEM        1
105251875Speter/** @see apr_procattr_limit_set */
106251875Speter#define APR_LIMIT_NPROC      2
107251875Speter/** @see apr_procattr_limit_set */
108251875Speter#define APR_LIMIT_NOFILE     3
109251875Speter
110251875Speter/**
111251875Speter * @defgroup APR_OC Other Child Flags
112251875Speter * @{
113251875Speter */
114251875Speter#define APR_OC_REASON_DEATH         0     /**< child has died, caller must call
115251875Speter                                           * unregister still */
116251875Speter#define APR_OC_REASON_UNWRITABLE    1     /**< write_fd is unwritable */
117269847Speter#define APR_OC_REASON_RESTART       2     /**< a restart is occurring, perform
118251875Speter                                           * any necessary cleanup (including
119251875Speter                                           * sending a special signal to child)
120251875Speter                                           */
121251875Speter#define APR_OC_REASON_UNREGISTER    3     /**< unregister has been called, do
122251875Speter                                           * whatever is necessary (including
123251875Speter                                           * kill the child) */
124251875Speter#define APR_OC_REASON_LOST          4     /**< somehow the child exited without
125251875Speter                                           * us knowing ... buggy os? */
126269847Speter#define APR_OC_REASON_RUNNING       5     /**< a health check is occurring,
127251875Speter                                           * for most maintainence functions
128251875Speter                                           * this is a no-op.
129251875Speter                                           */
130251875Speter/** @} */
131251875Speter
132251875Speter/** The APR process type */
133251875Spetertypedef struct apr_proc_t {
134251875Speter    /** The process ID */
135251875Speter    pid_t pid;
136251875Speter    /** Parent's side of pipe to child's stdin */
137251875Speter    apr_file_t *in;
138251875Speter    /** Parent's side of pipe to child's stdout */
139251875Speter    apr_file_t *out;
140251875Speter    /** Parent's side of pipe to child's stdouterr */
141251875Speter    apr_file_t *err;
142251875Speter#if APR_HAS_PROC_INVOKED || defined(DOXYGEN)
143251875Speter    /** Diagnositics/debugging string of the command invoked for
144251875Speter     *  this process [only present if APR_HAS_PROC_INVOKED is true]
145251875Speter     * @remark Only enabled on Win32 by default.
146251875Speter     * @bug This should either always or never be present in release
147251875Speter     * builds - since it breaks binary compatibility.  We may enable
148251875Speter     * it always in APR 1.0 yet leave it undefined in most cases.
149251875Speter     */
150251875Speter    char *invoked;
151251875Speter#endif
152251875Speter#if defined(WIN32) || defined(DOXYGEN)
153251875Speter    /** (Win32 only) Creator's handle granting access to the process
154251875Speter     * @remark This handle is closed and reset to NULL in every case
155251875Speter     * corresponding to a waitpid() on Unix which returns the exit status.
156251875Speter     * Therefore Win32 correspond's to Unix's zombie reaping characteristics
157251875Speter     * and avoids potential handle leaks.
158251875Speter     */
159251875Speter    HANDLE hproc;
160251875Speter#endif
161251875Speter} apr_proc_t;
162251875Speter
163251875Speter/**
164251875Speter * The prototype for APR child errfn functions.  (See the description
165251875Speter * of apr_procattr_child_errfn_set() for more information.)
166251875Speter * It is passed the following parameters:
167251875Speter * @param pool Pool associated with the apr_proc_t.  If your child
168251875Speter *             error function needs user data, associate it with this
169251875Speter *             pool.
170251875Speter * @param err APR error code describing the error
171251875Speter * @param description Text description of type of processing which failed
172251875Speter */
173251875Spetertypedef void (apr_child_errfn_t)(apr_pool_t *proc, apr_status_t err,
174251875Speter                                 const char *description);
175251875Speter
176251875Speter/** Opaque Thread structure. */
177251875Spetertypedef struct apr_thread_t           apr_thread_t;
178251875Speter
179251875Speter/** Opaque Thread attributes structure. */
180251875Spetertypedef struct apr_threadattr_t       apr_threadattr_t;
181251875Speter
182251875Speter/** Opaque Process attributes structure. */
183251875Spetertypedef struct apr_procattr_t         apr_procattr_t;
184251875Speter
185251875Speter/** Opaque control variable for one-time atomic variables.  */
186251875Spetertypedef struct apr_thread_once_t      apr_thread_once_t;
187251875Speter
188251875Speter/** Opaque thread private address space. */
189251875Spetertypedef struct apr_threadkey_t        apr_threadkey_t;
190251875Speter
191251875Speter/** Opaque record of child process. */
192251875Spetertypedef struct apr_other_child_rec_t  apr_other_child_rec_t;
193251875Speter
194251875Speter/**
195251875Speter * The prototype for any APR thread worker functions.
196251875Speter */
197251875Spetertypedef void *(APR_THREAD_FUNC *apr_thread_start_t)(apr_thread_t*, void*);
198251875Speter
199251875Spetertypedef enum {
200269847Speter    APR_KILL_NEVER,             /**< process is never killed (i.e., never sent
201269847Speter                                 * any signals), but it will be reaped if it exits
202269847Speter                                 * before the pool is cleaned up */
203251875Speter    APR_KILL_ALWAYS,            /**< process is sent SIGKILL on apr_pool_t cleanup */
204251875Speter    APR_KILL_AFTER_TIMEOUT,     /**< SIGTERM, wait 3 seconds, SIGKILL */
205251875Speter    APR_JUST_WAIT,              /**< wait forever for the process to complete */
206251875Speter    APR_KILL_ONLY_ONCE          /**< send SIGTERM and then wait */
207251875Speter} apr_kill_conditions_e;
208251875Speter
209251875Speter/* Thread Function definitions */
210251875Speter
211251875Speter#if APR_HAS_THREADS
212251875Speter
213251875Speter/**
214251875Speter * Create and initialize a new threadattr variable
215251875Speter * @param new_attr The newly created threadattr.
216251875Speter * @param cont The pool to use
217251875Speter */
218251875SpeterAPR_DECLARE(apr_status_t) apr_threadattr_create(apr_threadattr_t **new_attr,
219251875Speter                                                apr_pool_t *cont);
220251875Speter
221251875Speter/**
222251875Speter * Set if newly created threads should be created in detached state.
223251875Speter * @param attr The threadattr to affect
224251875Speter * @param on Non-zero if detached threads should be created.
225251875Speter */
226251875SpeterAPR_DECLARE(apr_status_t) apr_threadattr_detach_set(apr_threadattr_t *attr,
227251875Speter                                                    apr_int32_t on);
228251875Speter
229251875Speter/**
230251875Speter * Get the detach state for this threadattr.
231251875Speter * @param attr The threadattr to reference
232251875Speter * @return APR_DETACH if threads are to be detached, or APR_NOTDETACH
233251875Speter * if threads are to be joinable.
234251875Speter */
235251875SpeterAPR_DECLARE(apr_status_t) apr_threadattr_detach_get(apr_threadattr_t *attr);
236251875Speter
237251875Speter/**
238251875Speter * Set the stack size of newly created threads.
239251875Speter * @param attr The threadattr to affect
240251875Speter * @param stacksize The stack size in bytes
241251875Speter */
242251875SpeterAPR_DECLARE(apr_status_t) apr_threadattr_stacksize_set(apr_threadattr_t *attr,
243251875Speter                                                       apr_size_t stacksize);
244251875Speter
245251875Speter/**
246251875Speter * Set the stack guard area size of newly created threads.
247251875Speter * @param attr The threadattr to affect
248251875Speter * @param guardsize The stack guard area size in bytes
249251875Speter * @note Thread library implementations commonly use a "guard area"
250251875Speter * after each thread's stack which is not readable or writable such that
251251875Speter * stack overflows cause a segfault; this consumes e.g. 4K of memory
252251875Speter * and increases memory management overhead.  Setting the guard area
253251875Speter * size to zero hence trades off reliable behaviour on stack overflow
254251875Speter * for performance. */
255251875SpeterAPR_DECLARE(apr_status_t) apr_threadattr_guardsize_set(apr_threadattr_t *attr,
256251875Speter                                                       apr_size_t guardsize);
257251875Speter
258251875Speter/**
259251875Speter * Create a new thread of execution
260251875Speter * @param new_thread The newly created thread handle.
261251875Speter * @param attr The threadattr to use to determine how to create the thread
262251875Speter * @param func The function to start the new thread in
263251875Speter * @param data Any data to be passed to the starting function
264251875Speter * @param cont The pool to use
265251875Speter */
266251875SpeterAPR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new_thread,
267251875Speter                                            apr_threadattr_t *attr,
268251875Speter                                            apr_thread_start_t func,
269251875Speter                                            void *data, apr_pool_t *cont);
270251875Speter
271251875Speter/**
272251875Speter * stop the current thread
273251875Speter * @param thd The thread to stop
274251875Speter * @param retval The return value to pass back to any thread that cares
275251875Speter */
276251875SpeterAPR_DECLARE(apr_status_t) apr_thread_exit(apr_thread_t *thd,
277251875Speter                                          apr_status_t retval);
278251875Speter
279251875Speter/**
280251875Speter * block until the desired thread stops executing.
281251875Speter * @param retval The return value from the dead thread.
282251875Speter * @param thd The thread to join
283251875Speter */
284251875SpeterAPR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval,
285251875Speter                                          apr_thread_t *thd);
286251875Speter
287251875Speter/**
288251875Speter * force the current thread to yield the processor
289251875Speter */
290251875SpeterAPR_DECLARE(void) apr_thread_yield(void);
291251875Speter
292251875Speter/**
293251875Speter * Initialize the control variable for apr_thread_once.  If this isn't
294251875Speter * called, apr_initialize won't work.
295251875Speter * @param control The control variable to initialize
296251875Speter * @param p The pool to allocate data from.
297251875Speter */
298251875SpeterAPR_DECLARE(apr_status_t) apr_thread_once_init(apr_thread_once_t **control,
299251875Speter                                               apr_pool_t *p);
300251875Speter
301251875Speter/**
302251875Speter * Run the specified function one time, regardless of how many threads
303251875Speter * call it.
304251875Speter * @param control The control variable.  The same variable should
305251875Speter *                be passed in each time the function is tried to be
306251875Speter *                called.  This is how the underlying functions determine
307251875Speter *                if the function has ever been called before.
308251875Speter * @param func The function to call.
309251875Speter */
310251875SpeterAPR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
311251875Speter                                          void (*func)(void));
312251875Speter
313251875Speter/**
314251875Speter * detach a thread
315251875Speter * @param thd The thread to detach
316251875Speter */
317251875SpeterAPR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd);
318251875Speter
319251875Speter/**
320253734Speter * Return user data associated with the current thread.
321251875Speter * @param data The user data associated with the thread.
322251875Speter * @param key The key to associate with the data
323251875Speter * @param thread The currently open thread.
324251875Speter */
325251875SpeterAPR_DECLARE(apr_status_t) apr_thread_data_get(void **data, const char *key,
326251875Speter                                             apr_thread_t *thread);
327251875Speter
328251875Speter/**
329253734Speter * Set user data associated with the current thread.
330251875Speter * @param data The user data to associate with the thread.
331251875Speter * @param key The key to use for associating the data with the thread
332251875Speter * @param cleanup The cleanup routine to use when the thread is destroyed.
333251875Speter * @param thread The currently open thread.
334251875Speter */
335251875SpeterAPR_DECLARE(apr_status_t) apr_thread_data_set(void *data, const char *key,
336251875Speter                                             apr_status_t (*cleanup) (void *),
337251875Speter                                             apr_thread_t *thread);
338251875Speter
339251875Speter/**
340251875Speter * Create and initialize a new thread private address space
341251875Speter * @param key The thread private handle.
342251875Speter * @param dest The destructor to use when freeing the private memory.
343251875Speter * @param cont The pool to use
344251875Speter */
345251875SpeterAPR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key,
346251875Speter                                                    void (*dest)(void *),
347251875Speter                                                    apr_pool_t *cont);
348251875Speter
349251875Speter/**
350251875Speter * Get a pointer to the thread private memory
351251875Speter * @param new_mem The data stored in private memory
352251875Speter * @param key The handle for the desired thread private memory
353251875Speter */
354251875SpeterAPR_DECLARE(apr_status_t) apr_threadkey_private_get(void **new_mem,
355251875Speter                                                 apr_threadkey_t *key);
356251875Speter
357251875Speter/**
358251875Speter * Set the data to be stored in thread private memory
359251875Speter * @param priv The data to be stored in private memory
360251875Speter * @param key The handle for the desired thread private memory
361251875Speter */
362251875SpeterAPR_DECLARE(apr_status_t) apr_threadkey_private_set(void *priv,
363251875Speter                                                 apr_threadkey_t *key);
364251875Speter
365251875Speter/**
366251875Speter * Free the thread private memory
367251875Speter * @param key The handle for the desired thread private memory
368251875Speter */
369251875SpeterAPR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key);
370251875Speter
371251875Speter/**
372251875Speter * Return the pool associated with the current threadkey.
373251875Speter * @param data The user data associated with the threadkey.
374251875Speter * @param key The key associated with the data
375251875Speter * @param threadkey The currently open threadkey.
376251875Speter */
377251875SpeterAPR_DECLARE(apr_status_t) apr_threadkey_data_get(void **data, const char *key,
378251875Speter                                                apr_threadkey_t *threadkey);
379251875Speter
380251875Speter/**
381251875Speter * Return the pool associated with the current threadkey.
382251875Speter * @param data The data to set.
383251875Speter * @param key The key to associate with the data.
384251875Speter * @param cleanup The cleanup routine to use when the file is destroyed.
385251875Speter * @param threadkey The currently open threadkey.
386251875Speter */
387251875SpeterAPR_DECLARE(apr_status_t) apr_threadkey_data_set(void *data, const char *key,
388251875Speter                                                apr_status_t (*cleanup) (void *),
389251875Speter                                                apr_threadkey_t *threadkey);
390251875Speter
391251875Speter#endif
392251875Speter
393251875Speter/**
394251875Speter * Create and initialize a new procattr variable
395251875Speter * @param new_attr The newly created procattr.
396251875Speter * @param cont The pool to use
397251875Speter */
398251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new_attr,
399251875Speter                                                  apr_pool_t *cont);
400251875Speter
401251875Speter/**
402251875Speter * Determine if any of stdin, stdout, or stderr should be linked to pipes
403251875Speter * when starting a child process.
404251875Speter * @param attr The procattr we care about.
405251875Speter * @param in Should stdin be a pipe back to the parent?
406251875Speter * @param out Should stdout be a pipe back to the parent?
407251875Speter * @param err Should stderr be a pipe back to the parent?
408251875Speter * @note If APR_NO_PIPE, there will be no special channel, the child
409251875Speter * inherits the parent's corresponding stdio stream.  If APR_NO_FILE is
410251875Speter * specified, that corresponding stream is closed in the child (and will
411251875Speter * be INVALID_HANDLE_VALUE when inspected on Win32). This can have ugly
412251875Speter * side effects, as the next file opened in the child on Unix will fall
413251875Speter * into the stdio stream fd slot!
414251875Speter */
415251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr,
416251875Speter                                             apr_int32_t in, apr_int32_t out,
417251875Speter                                             apr_int32_t err);
418251875Speter
419251875Speter/**
420251875Speter * Set the child_in and/or parent_in values to existing apr_file_t values.
421251875Speter * @param attr The procattr we care about.
422251875Speter * @param child_in apr_file_t value to use as child_in. Must be a valid file.
423251875Speter * @param parent_in apr_file_t value to use as parent_in. Must be a valid file.
424251875Speter * @remark  This is NOT a required initializer function. This is
425251875Speter *          useful if you have already opened a pipe (or multiple files)
426251875Speter *          that you wish to use, perhaps persistently across multiple
427251875Speter *          process invocations - such as a log file. You can save some
428251875Speter *          extra function calls by not creating your own pipe since this
429251875Speter *          creates one in the process space for you.
430251875Speter * @bug Note that calling this function with two NULL files on some platforms
431251875Speter * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
432251875Speter * is it supported.  @see apr_procattr_io_set instead for simple pipes.
433251875Speter */
434251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_child_in_set(struct apr_procattr_t *attr,
435251875Speter                                                  apr_file_t *child_in,
436251875Speter                                                  apr_file_t *parent_in);
437251875Speter
438251875Speter/**
439251875Speter * Set the child_out and parent_out values to existing apr_file_t values.
440251875Speter * @param attr The procattr we care about.
441251875Speter * @param child_out apr_file_t value to use as child_out. Must be a valid file.
442251875Speter * @param parent_out apr_file_t value to use as parent_out. Must be a valid file.
443251875Speter * @remark This is NOT a required initializer function. This is
444251875Speter *         useful if you have already opened a pipe (or multiple files)
445251875Speter *         that you wish to use, perhaps persistently across multiple
446251875Speter *         process invocations - such as a log file.
447251875Speter * @bug Note that calling this function with two NULL files on some platforms
448251875Speter * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
449251875Speter * is it supported.  @see apr_procattr_io_set instead for simple pipes.
450251875Speter */
451251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_child_out_set(struct apr_procattr_t *attr,
452251875Speter                                                   apr_file_t *child_out,
453251875Speter                                                   apr_file_t *parent_out);
454251875Speter
455251875Speter/**
456251875Speter * Set the child_err and parent_err values to existing apr_file_t values.
457251875Speter * @param attr The procattr we care about.
458251875Speter * @param child_err apr_file_t value to use as child_err. Must be a valid file.
459251875Speter * @param parent_err apr_file_t value to use as parent_err. Must be a valid file.
460251875Speter * @remark This is NOT a required initializer function. This is
461251875Speter *         useful if you have already opened a pipe (or multiple files)
462251875Speter *         that you wish to use, perhaps persistently across multiple
463251875Speter *         process invocations - such as a log file.
464251875Speter * @bug Note that calling this function with two NULL files on some platforms
465251875Speter * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
466251875Speter * is it supported.  @see apr_procattr_io_set instead for simple pipes.
467251875Speter */
468251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_child_err_set(struct apr_procattr_t *attr,
469251875Speter                                                   apr_file_t *child_err,
470251875Speter                                                   apr_file_t *parent_err);
471251875Speter
472251875Speter/**
473251875Speter * Set which directory the child process should start executing in.
474251875Speter * @param attr The procattr we care about.
475251875Speter * @param dir Which dir to start in.  By default, this is the same dir as
476251875Speter *            the parent currently resides in, when the createprocess call
477251875Speter *            is made.
478251875Speter */
479251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr,
480251875Speter                                              const char *dir);
481251875Speter
482251875Speter/**
483251875Speter * Set what type of command the child process will call.
484251875Speter * @param attr The procattr we care about.
485251875Speter * @param cmd The type of command.  One of:
486251875Speter * <PRE>
487251875Speter *            APR_SHELLCMD     --  Anything that the shell can handle
488251875Speter *            APR_PROGRAM      --  Executable program   (default)
489251875Speter *            APR_PROGRAM_ENV  --  Executable program, copy environment
490251875Speter *            APR_PROGRAM_PATH --  Executable program on PATH, copy env
491251875Speter * </PRE>
492251875Speter */
493251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_cmdtype_set(apr_procattr_t *attr,
494251875Speter                                                  apr_cmdtype_e cmd);
495251875Speter
496251875Speter/**
497251875Speter * Determine if the child should start in detached state.
498251875Speter * @param attr The procattr we care about.
499251875Speter * @param detach Should the child start in detached state?  Default is no.
500251875Speter */
501251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_detach_set(apr_procattr_t *attr,
502251875Speter                                                 apr_int32_t detach);
503251875Speter
504251875Speter#if APR_HAVE_STRUCT_RLIMIT
505251875Speter/**
506251875Speter * Set the Resource Utilization limits when starting a new process.
507251875Speter * @param attr The procattr we care about.
508251875Speter * @param what Which limit to set, one of:
509251875Speter * <PRE>
510251875Speter *                 APR_LIMIT_CPU
511251875Speter *                 APR_LIMIT_MEM
512251875Speter *                 APR_LIMIT_NPROC
513251875Speter *                 APR_LIMIT_NOFILE
514251875Speter * </PRE>
515251875Speter * @param limit Value to set the limit to.
516251875Speter */
517251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr,
518251875Speter                                                apr_int32_t what,
519251875Speter                                                struct rlimit *limit);
520251875Speter#endif
521251875Speter
522251875Speter/**
523251875Speter * Specify an error function to be called in the child process if APR
524251875Speter * encounters an error in the child prior to running the specified program.
525251875Speter * @param attr The procattr describing the child process to be created.
526251875Speter * @param errfn The function to call in the child process.
527251875Speter * @remark At the present time, it will only be called from apr_proc_create()
528251875Speter *         on platforms where fork() is used.  It will never be called on other
529251875Speter *         platforms, on those platforms apr_proc_create() will return the error
530251875Speter *         in the parent process rather than invoke the callback in the now-forked
531251875Speter *         child process.
532251875Speter */
533251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
534251875Speter                                                       apr_child_errfn_t *errfn);
535251875Speter
536251875Speter/**
537251875Speter * Specify that apr_proc_create() should do whatever it can to report
538251875Speter * failures to the caller of apr_proc_create(), rather than find out in
539251875Speter * the child.
540251875Speter * @param attr The procattr describing the child process to be created.
541251875Speter * @param chk Flag to indicate whether or not extra work should be done
542251875Speter *            to try to report failures to the caller.
543251875Speter * @remark This flag only affects apr_proc_create() on platforms where
544251875Speter *         fork() is used.  This leads to extra overhead in the calling
545251875Speter *         process, but that may help the application handle such
546251875Speter *         errors more gracefully.
547251875Speter */
548251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
549251875Speter                                                       apr_int32_t chk);
550251875Speter
551251875Speter/**
552251875Speter * Determine if the child should start in its own address space or using the
553251875Speter * current one from its parent
554251875Speter * @param attr The procattr we care about.
555251875Speter * @param addrspace Should the child start in its own address space?  Default
556251875Speter *                  is no on NetWare and yes on other platforms.
557251875Speter */
558251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_addrspace_set(apr_procattr_t *attr,
559251875Speter                                                       apr_int32_t addrspace);
560251875Speter
561251875Speter/**
562251875Speter * Set the username used for running process
563251875Speter * @param attr The procattr we care about.
564251875Speter * @param username The username used
565251875Speter * @param password User password if needed. Password is needed on WIN32
566251875Speter *                 or any other platform having
567251875Speter *                 APR_PROCATTR_USER_SET_REQUIRES_PASSWORD set.
568251875Speter */
569251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr,
570251875Speter                                                const char *username,
571251875Speter                                                const char *password);
572251875Speter
573251875Speter/**
574251875Speter * Set the group used for running process
575251875Speter * @param attr The procattr we care about.
576251875Speter * @param groupname The group name  used
577251875Speter */
578251875SpeterAPR_DECLARE(apr_status_t) apr_procattr_group_set(apr_procattr_t *attr,
579251875Speter                                                 const char *groupname);
580251875Speter
581251875Speter
582251875Speter#if APR_HAS_FORK
583251875Speter/**
584251875Speter * This is currently the only non-portable call in APR.  This executes
585251875Speter * a standard unix fork.
586251875Speter * @param proc The resulting process handle.
587251875Speter * @param cont The pool to use.
588251875Speter * @remark returns APR_INCHILD for the child, and APR_INPARENT for the parent
589251875Speter * or an error.
590251875Speter */
591251875SpeterAPR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *cont);
592251875Speter#endif
593251875Speter
594251875Speter/**
595251875Speter * Create a new process and execute a new program within that process.
596251875Speter * @param new_proc The resulting process handle.
597251875Speter * @param progname The program to run
598251875Speter * @param args the arguments to pass to the new program.  The first
599251875Speter *             one should be the program name.
600251875Speter * @param env The new environment table for the new process.  This
601251875Speter *            should be a list of NULL-terminated strings. This argument
602251875Speter *            is ignored for APR_PROGRAM_ENV, APR_PROGRAM_PATH, and
603251875Speter *            APR_SHELLCMD_ENV types of commands.
604251875Speter * @param attr the procattr we should use to determine how to create the new
605251875Speter *         process
606251875Speter * @param pool The pool to use.
607251875Speter * @note This function returns without waiting for the new process to terminate;
608251875Speter * use apr_proc_wait for that.
609251875Speter */
610251875SpeterAPR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new_proc,
611251875Speter                                          const char *progname,
612251875Speter                                          const char * const *args,
613251875Speter                                          const char * const *env,
614251875Speter                                          apr_procattr_t *attr,
615251875Speter                                          apr_pool_t *pool);
616251875Speter
617251875Speter/**
618251875Speter * Wait for a child process to die
619251875Speter * @param proc The process handle that corresponds to the desired child process
620251875Speter * @param exitcode The returned exit status of the child, if a child process
621251875Speter *                 dies, or the signal that caused the child to die.
622251875Speter *                 On platforms that don't support obtaining this information,
623251875Speter *                 the status parameter will be returned as APR_ENOTIMPL.
624251875Speter * @param exitwhy Why the child died, the bitwise or of:
625251875Speter * <PRE>
626251875Speter *            APR_PROC_EXIT         -- process terminated normally
627251875Speter *            APR_PROC_SIGNAL       -- process was killed by a signal
628251875Speter *            APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
629251875Speter *                                     generated a core dump.
630251875Speter * </PRE>
631251875Speter * @param waithow How should we wait.  One of:
632251875Speter * <PRE>
633251875Speter *            APR_WAIT   -- block until the child process dies.
634251875Speter *            APR_NOWAIT -- return immediately regardless of if the
635251875Speter *                          child is dead or not.
636251875Speter * </PRE>
637269847Speter * @remark The child's status is in the return code to this process.  It is one of:
638251875Speter * <PRE>
639251875Speter *            APR_CHILD_DONE     -- child is no longer running.
640251875Speter *            APR_CHILD_NOTDONE  -- child is still running.
641251875Speter * </PRE>
642251875Speter */
643251875SpeterAPR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
644251875Speter                                        int *exitcode, apr_exit_why_e *exitwhy,
645251875Speter                                        apr_wait_how_e waithow);
646251875Speter
647251875Speter/**
648251875Speter * Wait for any current child process to die and return information
649251875Speter * about that child.
650251875Speter * @param proc Pointer to NULL on entry, will be filled out with child's
651251875Speter *             information
652251875Speter * @param exitcode The returned exit status of the child, if a child process
653251875Speter *                 dies, or the signal that caused the child to die.
654251875Speter *                 On platforms that don't support obtaining this information,
655251875Speter *                 the status parameter will be returned as APR_ENOTIMPL.
656251875Speter * @param exitwhy Why the child died, the bitwise or of:
657251875Speter * <PRE>
658251875Speter *            APR_PROC_EXIT         -- process terminated normally
659251875Speter *            APR_PROC_SIGNAL       -- process was killed by a signal
660251875Speter *            APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
661251875Speter *                                     generated a core dump.
662251875Speter * </PRE>
663251875Speter * @param waithow How should we wait.  One of:
664251875Speter * <PRE>
665251875Speter *            APR_WAIT   -- block until the child process dies.
666251875Speter *            APR_NOWAIT -- return immediately regardless of if the
667251875Speter *                          child is dead or not.
668251875Speter * </PRE>
669251875Speter * @param p Pool to allocate child information out of.
670251875Speter * @bug Passing proc as a *proc rather than **proc was an odd choice
671251875Speter * for some platforms... this should be revisited in 1.0
672251875Speter */
673251875SpeterAPR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc,
674251875Speter                                                  int *exitcode,
675251875Speter                                                  apr_exit_why_e *exitwhy,
676251875Speter                                                  apr_wait_how_e waithow,
677251875Speter                                                  apr_pool_t *p);
678251875Speter
679251875Speter#define APR_PROC_DETACH_FOREGROUND 0    /**< Do not detach */
680251875Speter#define APR_PROC_DETACH_DAEMONIZE 1     /**< Detach */
681251875Speter
682251875Speter/**
683251875Speter * Detach the process from the controlling terminal.
684251875Speter * @param daemonize set to non-zero if the process should daemonize
685251875Speter *                  and become a background process, else it will
686251875Speter *                  stay in the foreground.
687251875Speter */
688251875SpeterAPR_DECLARE(apr_status_t) apr_proc_detach(int daemonize);
689251875Speter
690251875Speter/**
691251875Speter * Register an other_child -- a child associated to its registered
692251875Speter * maintence callback.  This callback is invoked when the process
693251875Speter * dies, is disconnected or disappears.
694251875Speter * @param proc The child process to register.
695251875Speter * @param maintenance maintenance is a function that is invoked with a
696251875Speter *                    reason and the data pointer passed here.
697251875Speter * @param data Opaque context data passed to the maintenance function.
698251875Speter * @param write_fd An fd that is probed for writing.  If it is ever unwritable
699251875Speter *                 then the maintenance is invoked with reason
700251875Speter *                 OC_REASON_UNWRITABLE.
701251875Speter * @param p The pool to use for allocating memory.
702251875Speter * @bug write_fd duplicates the proc->out stream, it's really redundant
703251875Speter * and should be replaced in the APR 1.0 API with a bitflag of which
704251875Speter * proc->in/out/err handles should be health checked.
705251875Speter * @bug no platform currently tests the pipes health.
706251875Speter */
707251875SpeterAPR_DECLARE(void) apr_proc_other_child_register(apr_proc_t *proc,
708251875Speter                                           void (*maintenance) (int reason,
709251875Speter                                                                void *,
710251875Speter                                                                int status),
711251875Speter                                           void *data, apr_file_t *write_fd,
712251875Speter                                           apr_pool_t *p);
713251875Speter
714251875Speter/**
715251875Speter * Stop watching the specified other child.
716251875Speter * @param data The data to pass to the maintenance function.  This is
717251875Speter *             used to find the process to unregister.
718251875Speter * @warning Since this can be called by a maintenance function while we're
719251875Speter *          scanning the other_children list, all scanners should protect
720251875Speter *          themself by loading ocr->next before calling any maintenance
721251875Speter *          function.
722251875Speter */
723251875SpeterAPR_DECLARE(void) apr_proc_other_child_unregister(void *data);
724251875Speter
725251875Speter/**
726251875Speter * Notify the maintenance callback of a registered other child process
727251875Speter * that application has detected an event, such as death.
728251875Speter * @param proc The process to check
729251875Speter * @param reason The reason code to pass to the maintenance function
730251875Speter * @param status The status to pass to the maintenance function
731251875Speter * @remark An example of code using this behavior;
732251875Speter * <pre>
733251875Speter * rv = apr_proc_wait_all_procs(&proc, &exitcode, &status, APR_WAIT, p);
734251875Speter * if (APR_STATUS_IS_CHILD_DONE(rv)) {
735251875Speter * \#if APR_HAS_OTHER_CHILD
736251875Speter *     if (apr_proc_other_child_alert(&proc, APR_OC_REASON_DEATH, status)
737251875Speter *             == APR_SUCCESS) {
738251875Speter *         ;  (already handled)
739251875Speter *     }
740251875Speter *     else
741251875Speter * \#endif
742251875Speter *         [... handling non-otherchild processes death ...]
743251875Speter * </pre>
744251875Speter */
745251875SpeterAPR_DECLARE(apr_status_t) apr_proc_other_child_alert(apr_proc_t *proc,
746251875Speter                                                     int reason,
747251875Speter                                                     int status);
748251875Speter
749251875Speter/**
750251875Speter * Test one specific other child processes and invoke the maintenance callback
751251875Speter * with the appropriate reason code, if still running, or the appropriate reason
752251875Speter * code if the process is no longer healthy.
753251875Speter * @param ocr The registered other child
754251875Speter * @param reason The reason code (e.g. APR_OC_REASON_RESTART) if still running
755251875Speter */
756251875SpeterAPR_DECLARE(void) apr_proc_other_child_refresh(apr_other_child_rec_t *ocr,
757251875Speter                                               int reason);
758251875Speter
759251875Speter/**
760251875Speter * Test all registered other child processes and invoke the maintenance callback
761251875Speter * with the appropriate reason code, if still running, or the appropriate reason
762251875Speter * code if the process is no longer healthy.
763251875Speter * @param reason The reason code (e.g. APR_OC_REASON_RESTART) to running processes
764251875Speter */
765251875SpeterAPR_DECLARE(void) apr_proc_other_child_refresh_all(int reason);
766251875Speter
767251875Speter/**
768251875Speter * Terminate a process.
769251875Speter * @param proc The process to terminate.
770251875Speter * @param sig How to kill the process.
771251875Speter */
772251875SpeterAPR_DECLARE(apr_status_t) apr_proc_kill(apr_proc_t *proc, int sig);
773251875Speter
774251875Speter/**
775251875Speter * Register a process to be killed when a pool dies.
776251875Speter * @param a The pool to use to define the processes lifetime
777251875Speter * @param proc The process to register
778251875Speter * @param how How to kill the process, one of:
779251875Speter * <PRE>
780251875Speter *         APR_KILL_NEVER         -- process is never sent any signals
781251875Speter *         APR_KILL_ALWAYS        -- process is sent SIGKILL on apr_pool_t cleanup
782251875Speter *         APR_KILL_AFTER_TIMEOUT -- SIGTERM, wait 3 seconds, SIGKILL
783251875Speter *         APR_JUST_WAIT          -- wait forever for the process to complete
784251875Speter *         APR_KILL_ONLY_ONCE     -- send SIGTERM and then wait
785251875Speter * </PRE>
786251875Speter */
787251875SpeterAPR_DECLARE(void) apr_pool_note_subprocess(apr_pool_t *a, apr_proc_t *proc,
788251875Speter                                           apr_kill_conditions_e how);
789251875Speter
790251875Speter#if APR_HAS_THREADS
791251875Speter
792251875Speter#if (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2)
793251875Speter
794251875Speter/**
795251875Speter * Setup the process for a single thread to be used for all signal handling.
796251875Speter * @warning This must be called before any threads are created
797251875Speter */
798251875SpeterAPR_DECLARE(apr_status_t) apr_setup_signal_thread(void);
799251875Speter
800251875Speter/**
801251875Speter * Make the current thread listen for signals.  This thread will loop
802251875Speter * forever, calling a provided function whenever it receives a signal.  That
803251875Speter * functions should return 1 if the signal has been handled, 0 otherwise.
804251875Speter * @param signal_handler The function to call when a signal is received
805251875Speter * apr_status_t apr_signal_thread((int)(*signal_handler)(int signum))
806251875Speter */
807251875SpeterAPR_DECLARE(apr_status_t) apr_signal_thread(int(*signal_handler)(int signum));
808251875Speter
809251875Speter#endif /* (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2) */
810251875Speter
811251875Speter/**
812251875Speter * Get the child-pool used by the thread from the thread info.
813251875Speter * @return apr_pool_t the pool
814251875Speter */
815251875SpeterAPR_POOL_DECLARE_ACCESSOR(thread);
816251875Speter
817251875Speter#endif /* APR_HAS_THREADS */
818251875Speter
819251875Speter/** @} */
820251875Speter
821251875Speter#ifdef __cplusplus
822251875Speter}
823251875Speter#endif
824251875Speter
825251875Speter#endif  /* ! APR_THREAD_PROC_H */
826251875Speter
827