"Fossies" - the Fresh Open Source Software Archive

Member "apr-1.7.0/include/apr_thread_proc.h" (8 Mar 2019, 36127 Bytes) of package /linux/www/apr-1.7.0.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "apr_thread_proc.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.6.5_vs_1.7.0.

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