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