home *** CD-ROM | disk | FTP | other *** search
/ Download Now 8 / Download Now V8.iso / Program / InternetTools / ApacheWebServer1.3.6 / apache_1_3_6_win32.exe / _SETUP.1 / alloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-07  |  66.6 KB  |  2,593 lines

  1. /* ====================================================================
  2.  * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer. 
  10.  *
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in
  13.  *    the documentation and/or other materials provided with the
  14.  *    distribution.
  15.  *
  16.  * 3. All advertising materials mentioning features or use of this
  17.  *    software must display the following acknowledgment:
  18.  *    "This product includes software developed by the Apache Group
  19.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  20.  *
  21.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  22.  *    endorse or promote products derived from this software without
  23.  *    prior written permission. For written permission, please contact
  24.  *    apache@apache.org.
  25.  *
  26.  * 5. Products derived from this software may not be called "Apache"
  27.  *    nor may "Apache" appear in their names without prior written
  28.  *    permission of the Apache Group.
  29.  *
  30.  * 6. Redistributions of any form whatsoever must retain the following
  31.  *    acknowledgment:
  32.  *    "This product includes software developed by the Apache Group
  33.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  36.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Group and was originally based
  51.  * on public domain software written at the National Center for
  52.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  53.  * For more information on the Apache Group and the Apache HTTP server
  54.  * project, please see <http://www.apache.org/>.
  55.  *
  56.  */
  57.  
  58. /*
  59.  * Resource allocation code... the code here is responsible for making
  60.  * sure that nothing leaks.
  61.  *
  62.  * rst --- 4/95 --- 6/95
  63.  */
  64.  
  65. #include "httpd.h"
  66. #include "multithread.h"
  67. #include "http_log.h"
  68.  
  69. #include <stdarg.h>
  70.  
  71. /* debugging support, define this to enable code which helps detect re-use
  72.  * of freed memory and other such nonsense.
  73.  *
  74.  * The theory is simple.  The FILL_BYTE (0xa5) is written over all malloc'd
  75.  * memory as we receive it, and is written over everything that we free up
  76.  * during a clear_pool.  We check that blocks on the free list always
  77.  * have the FILL_BYTE in them, and we check during palloc() that the bytes
  78.  * still have FILL_BYTE in them.  If you ever see garbage URLs or whatnot
  79.  * containing lots of 0xa5s then you know something used data that's been
  80.  * freed or uninitialized.
  81.  */
  82. /* #define ALLOC_DEBUG */
  83.  
  84. /* debugging support, if defined all allocations will be done with
  85.  * malloc and free()d appropriately at the end.  This is intended to be
  86.  * used with something like Electric Fence or Purify to help detect
  87.  * memory problems.  Note that if you're using efence then you should also
  88.  * add in ALLOC_DEBUG.  But don't add in ALLOC_DEBUG if you're using Purify
  89.  * because ALLOC_DEBUG would hide all the uninitialized read errors that
  90.  * Purify can diagnose.
  91.  */
  92. /* #define ALLOC_USE_MALLOC */
  93.  
  94. /* Pool debugging support.  This is intended to detect cases where the
  95.  * wrong pool is used when assigning data to an object in another pool.
  96.  * In particular, it causes the table_{set,add,merge}n routines to check
  97.  * that their arguments are safe for the table they're being placed in.
  98.  * It currently only works with the unix multiprocess model, but could
  99.  * be extended to others.
  100.  */
  101. /* #define POOL_DEBUG */
  102.  
  103. /* Provide diagnostic information about make_table() calls which are
  104.  * possibly too small.  This requires a recent gcc which supports
  105.  * __builtin_return_address().  The error_log output will be a
  106.  * message such as:
  107.  *    table_push: table created by 0x804d874 hit limit of 10
  108.  * Use "l *0x804d874" to find the source that corresponds to.  It
  109.  * indicates that a table allocated by a call at that address has
  110.  * possibly too small an initial table size guess.
  111.  */
  112. /* #define MAKE_TABLE_PROFILE */
  113.  
  114. #ifdef POOL_DEBUG
  115. #ifdef ALLOC_USE_MALLOC
  116. # error "sorry, no support for ALLOC_USE_MALLOC and POOL_DEBUG at the same time"
  117. #endif
  118. #ifdef MULTITHREAD
  119. # error "sorry, no support for MULTITHREAD and POOL_DEBUG at the same time"
  120. #endif
  121. #endif
  122.  
  123. #ifdef ALLOC_USE_MALLOC
  124. #undef BLOCK_MINFREE
  125. #undef BLOCK_MINALLOC
  126. #define BLOCK_MINFREE    0
  127. #define BLOCK_MINALLOC    0
  128. #endif
  129.  
  130. /*****************************************************************
  131.  *
  132.  * Managing free storage blocks...
  133.  */
  134.  
  135. union align {
  136.     /* Types which are likely to have the longest RELEVANT alignment
  137.      * restrictions...
  138.      */
  139.  
  140.     char *cp;
  141.     void (*f) (void);
  142.     long l;
  143.     FILE *fp;
  144.     double d;
  145. };
  146.  
  147. #define CLICK_SZ (sizeof(union align))
  148.  
  149. union block_hdr {
  150.     union align a;
  151.  
  152.     /* Actual header... */
  153.  
  154.     struct {
  155.     char *endp;
  156.     union block_hdr *next;
  157.     char *first_avail;
  158. #ifdef POOL_DEBUG
  159.     union block_hdr *global_next;
  160.     struct pool *owning_pool;
  161. #endif
  162.     } h;
  163. };
  164.  
  165. static union block_hdr *block_freelist = NULL;
  166. static mutex *alloc_mutex = NULL;
  167. static mutex *spawn_mutex = NULL;
  168. #ifdef POOL_DEBUG
  169. static char *known_stack_point;
  170. static int stack_direction;
  171. static union block_hdr *global_block_list;
  172. #define FREE_POOL    ((struct pool *)(-1))
  173. #endif
  174.  
  175. #ifdef ALLOC_DEBUG
  176. #define FILL_BYTE    ((char)(0xa5))
  177.  
  178. #define debug_fill(ptr,size)    ((void)memset((ptr), FILL_BYTE, (size)))
  179.  
  180. static ap_inline void debug_verify_filled(const char *ptr,
  181.     const char *endp, const char *error_msg)
  182. {
  183.     for (; ptr < endp; ++ptr) {
  184.     if (*ptr != FILL_BYTE) {
  185.         fputs(error_msg, stderr);
  186.         abort();
  187.         exit(1);
  188.     }
  189.     }
  190. }
  191.  
  192. #else
  193. #define debug_fill(a,b)
  194. #define debug_verify_filled(a,b,c)
  195. #endif
  196.  
  197.  
  198. /* Get a completely new block from the system pool. Note that we rely on
  199.    malloc() to provide aligned memory. */
  200.  
  201. static union block_hdr *malloc_block(int size)
  202. {
  203.     union block_hdr *blok;
  204.  
  205. #ifdef ALLOC_DEBUG
  206.     /* make some room at the end which we'll fill and expect to be
  207.      * always filled
  208.      */
  209.     size += CLICK_SZ;
  210. #endif
  211.     blok = (union block_hdr *) malloc(size + sizeof(union block_hdr));
  212.     if (blok == NULL) {
  213.     fprintf(stderr, "Ouch!  malloc failed in malloc_block()\n");
  214.     exit(1);
  215.     }
  216.     debug_fill(blok, size + sizeof(union block_hdr));
  217.     blok->h.next = NULL;
  218.     blok->h.first_avail = (char *) (blok + 1);
  219.     blok->h.endp = size + blok->h.first_avail;
  220. #ifdef ALLOC_DEBUG
  221.     blok->h.endp -= CLICK_SZ;
  222. #endif
  223. #ifdef POOL_DEBUG
  224.     blok->h.global_next = global_block_list;
  225.     global_block_list = blok;
  226.     blok->h.owning_pool = NULL;
  227. #endif
  228.  
  229.     return blok;
  230. }
  231.  
  232.  
  233.  
  234. #if defined(ALLOC_DEBUG) && !defined(ALLOC_USE_MALLOC)
  235. static void chk_on_blk_list(union block_hdr *blok, union block_hdr *free_blk)
  236. {
  237.     debug_verify_filled(blok->h.endp, blok->h.endp + CLICK_SZ,
  238.     "Ouch!  Someone trounced the padding at the end of a block!\n");
  239.     while (free_blk) {
  240.     if (free_blk == blok) {
  241.         fprintf(stderr, "Ouch!  Freeing free block\n");
  242.         abort();
  243.         exit(1);
  244.     }
  245.     free_blk = free_blk->h.next;
  246.     }
  247. }
  248. #else
  249. #define chk_on_blk_list(_x, _y)
  250. #endif
  251.  
  252. /* Free a chain of blocks --- must be called with alarms blocked. */
  253.  
  254. static void free_blocks(union block_hdr *blok)
  255. {
  256. #ifdef ALLOC_USE_MALLOC
  257.     union block_hdr *next;
  258.  
  259.     for (; blok; blok = next) {
  260.     next = blok->h.next;
  261.     free(blok);
  262.     }
  263. #else
  264.     /* First, put new blocks at the head of the free list ---
  265.      * we'll eventually bash the 'next' pointer of the last block
  266.      * in the chain to point to the free blocks we already had.
  267.      */
  268.  
  269.     union block_hdr *old_free_list;
  270.  
  271.     if (blok == NULL)
  272.     return;            /* Sanity check --- freeing empty pool? */
  273.  
  274.     (void) ap_acquire_mutex(alloc_mutex);
  275.     old_free_list = block_freelist;
  276.     block_freelist = blok;
  277.  
  278.     /*
  279.      * Next, adjust first_avail pointers of each block --- have to do it
  280.      * sooner or later, and it simplifies the search in new_block to do it
  281.      * now.
  282.      */
  283.  
  284.     while (blok->h.next != NULL) {
  285.     chk_on_blk_list(blok, old_free_list);
  286.     blok->h.first_avail = (char *) (blok + 1);
  287.     debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail);
  288. #ifdef POOL_DEBUG
  289.     blok->h.owning_pool = FREE_POOL;
  290. #endif
  291.     blok = blok->h.next;
  292.     }
  293.  
  294.     chk_on_blk_list(blok, old_free_list);
  295.     blok->h.first_avail = (char *) (blok + 1);
  296.     debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail);
  297. #ifdef POOL_DEBUG
  298.     blok->h.owning_pool = FREE_POOL;
  299. #endif
  300.  
  301.     /* Finally, reset next pointer to get the old free blocks back */
  302.  
  303.     blok->h.next = old_free_list;
  304.     (void) ap_release_mutex(alloc_mutex);
  305. #endif
  306. }
  307.  
  308.  
  309. /* Get a new block, from our own free list if possible, from the system
  310.  * if necessary.  Must be called with alarms blocked.
  311.  */
  312.  
  313. static union block_hdr *new_block(int min_size)
  314. {
  315.     union block_hdr **lastptr = &block_freelist;
  316.     union block_hdr *blok = block_freelist;
  317.  
  318.     /* First, see if we have anything of the required size
  319.      * on the free list...
  320.      */
  321.  
  322.     while (blok != NULL) {
  323.     if (min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {
  324.         *lastptr = blok->h.next;
  325.         blok->h.next = NULL;
  326.         debug_verify_filled(blok->h.first_avail, blok->h.endp,
  327.         "Ouch!  Someone trounced a block on the free list!\n");
  328.         return blok;
  329.     }
  330.     else {
  331.         lastptr = &blok->h.next;
  332.         blok = blok->h.next;
  333.     }
  334.     }
  335.  
  336.     /* Nope. */
  337.  
  338.     min_size += BLOCK_MINFREE;
  339.     blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC);
  340.     return blok;
  341. }
  342.  
  343.  
  344. /* Accounting */
  345.  
  346. static long bytes_in_block_list(union block_hdr *blok)
  347. {
  348.     long size = 0;
  349.  
  350.     while (blok) {
  351.     size += blok->h.endp - (char *) (blok + 1);
  352.     blok = blok->h.next;
  353.     }
  354.  
  355.     return size;
  356. }
  357.  
  358.  
  359. /*****************************************************************
  360.  *
  361.  * Pool internals and management...
  362.  * NB that subprocesses are not handled by the generic cleanup code,
  363.  * basically because we don't want cleanups for multiple subprocesses
  364.  * to result in multiple three-second pauses.
  365.  */
  366.  
  367. struct process_chain;
  368. struct cleanup;
  369.  
  370. static void run_cleanups(struct cleanup *);
  371. static void free_proc_chain(struct process_chain *);
  372.  
  373. struct pool {
  374.     union block_hdr *first;
  375.     union block_hdr *last;
  376.     struct cleanup *cleanups;
  377.     struct process_chain *subprocesses;
  378.     struct pool *sub_pools;
  379.     struct pool *sub_next;
  380.     struct pool *sub_prev;
  381.     struct pool *parent;
  382.     char *free_first_avail;
  383. #ifdef ALLOC_USE_MALLOC
  384.     void *allocation_list;
  385. #endif
  386. #ifdef POOL_DEBUG
  387.     struct pool *joined;
  388. #endif
  389. };
  390.  
  391. static pool *permanent_pool;
  392.  
  393. /* Each pool structure is allocated in the start of its own first block,
  394.  * so we need to know how many bytes that is (once properly aligned...).
  395.  * This also means that when a pool's sub-pool is destroyed, the storage
  396.  * associated with it is *completely* gone, so we have to make sure it
  397.  * gets taken off the parent's sub-pool list...
  398.  */
  399.  
  400. #define POOL_HDR_CLICKS (1 + ((sizeof(struct pool) - 1) / CLICK_SZ))
  401. #define POOL_HDR_BYTES (POOL_HDR_CLICKS * CLICK_SZ)
  402.  
  403. API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p)
  404. {
  405.     union block_hdr *blok;
  406.     pool *new_pool;
  407.  
  408.     ap_block_alarms();
  409.  
  410.     (void) ap_acquire_mutex(alloc_mutex);
  411.  
  412.     blok = new_block(POOL_HDR_BYTES);
  413.     new_pool = (pool *) blok->h.first_avail;
  414.     blok->h.first_avail += POOL_HDR_BYTES;
  415. #ifdef POOL_DEBUG
  416.     blok->h.owning_pool = new_pool;
  417. #endif
  418.  
  419.     memset((char *) new_pool, '\0', sizeof(struct pool));
  420.     new_pool->free_first_avail = blok->h.first_avail;
  421.     new_pool->first = new_pool->last = blok;
  422.  
  423.     if (p) {
  424.     new_pool->parent = p;
  425.     new_pool->sub_next = p->sub_pools;
  426.     if (new_pool->sub_next)
  427.         new_pool->sub_next->sub_prev = new_pool;
  428.     p->sub_pools = new_pool;
  429.     }
  430.  
  431.     (void) ap_release_mutex(alloc_mutex);
  432.     ap_unblock_alarms();
  433.  
  434.     return new_pool;
  435. }
  436.  
  437. #ifdef POOL_DEBUG
  438. static void stack_var_init(char *s)
  439. {
  440.     char t;
  441.  
  442.     if (s < &t) {
  443.     stack_direction = 1; /* stack grows up */
  444.     }
  445.     else {
  446.     stack_direction = -1; /* stack grows down */
  447.     }
  448. }
  449. #endif
  450.  
  451. pool *ap_init_alloc(void)
  452. {
  453. #ifdef POOL_DEBUG
  454.     char s;
  455.  
  456.     known_stack_point = &s;
  457.     stack_var_init(&s);
  458. #endif
  459.     alloc_mutex = ap_create_mutex(NULL);
  460.     spawn_mutex = ap_create_mutex(NULL);
  461.     permanent_pool = ap_make_sub_pool(NULL);
  462.  
  463.     return permanent_pool;
  464. }
  465.  
  466. API_EXPORT(void) ap_clear_pool(struct pool *a)
  467. {
  468.     ap_block_alarms();
  469.  
  470.     (void) ap_acquire_mutex(alloc_mutex);
  471.     while (a->sub_pools)
  472.     ap_destroy_pool(a->sub_pools);
  473.     (void) ap_release_mutex(alloc_mutex);
  474.     /* Don't hold the mutex during cleanups. */
  475.     run_cleanups(a->cleanups);
  476.     a->cleanups = NULL;
  477.     free_proc_chain(a->subprocesses);
  478.     a->subprocesses = NULL;
  479.     free_blocks(a->first->h.next);
  480.     a->first->h.next = NULL;
  481.  
  482.     a->last = a->first;
  483.     a->first->h.first_avail = a->free_first_avail;
  484.     debug_fill(a->first->h.first_avail,
  485.     a->first->h.endp - a->first->h.first_avail);
  486.  
  487. #ifdef ALLOC_USE_MALLOC
  488.     {
  489.     void *c, *n;
  490.  
  491.     for (c = a->allocation_list; c; c = n) {
  492.         n = *(void **)c;
  493.         free(c);
  494.     }
  495.     a->allocation_list = NULL;
  496.     }
  497. #endif
  498.  
  499.     ap_unblock_alarms();
  500. }
  501.  
  502. API_EXPORT(void) ap_destroy_pool(pool *a)
  503. {
  504.     ap_block_alarms();
  505.     ap_clear_pool(a);
  506.  
  507.     (void) ap_acquire_mutex(alloc_mutex);
  508.     if (a->parent) {
  509.     if (a->parent->sub_pools == a)
  510.         a->parent->sub_pools = a->sub_next;
  511.     if (a->sub_prev)
  512.         a->sub_prev->sub_next = a->sub_next;
  513.     if (a->sub_next)
  514.         a->sub_next->sub_prev = a->sub_prev;
  515.     }
  516.     (void) ap_release_mutex(alloc_mutex);
  517.  
  518.     free_blocks(a->first);
  519.     ap_unblock_alarms();
  520. }
  521.  
  522. API_EXPORT(long) ap_bytes_in_pool(pool *p)
  523. {
  524.     return bytes_in_block_list(p->first);
  525. }
  526. API_EXPORT(long) ap_bytes_in_free_blocks(void)
  527. {
  528.     return bytes_in_block_list(block_freelist);
  529. }
  530.  
  531. /*****************************************************************
  532.  * POOL_DEBUG support
  533.  */
  534. #ifdef POOL_DEBUG
  535.  
  536. /* the unix linker defines this symbol as the last byte + 1 of
  537.  * the executable... so it includes TEXT, BSS, and DATA
  538.  */
  539. extern char _end;
  540.  
  541. /* is ptr in the range [lo,hi) */
  542. #define is_ptr_in_range(ptr, lo, hi)    \
  543.     (((unsigned long)(ptr) - (unsigned long)(lo)) \
  544.     < \
  545.     (unsigned long)(hi) - (unsigned long)(lo))
  546.  
  547. /* Find the pool that ts belongs to, return NULL if it doesn't
  548.  * belong to any pool.
  549.  */
  550. API_EXPORT(pool *) ap_find_pool(const void *ts)
  551. {
  552.     const char *s = ts;
  553.     union block_hdr **pb;
  554.     union block_hdr *b;
  555.  
  556.     /* short-circuit stuff which is in TEXT, BSS, or DATA */
  557.     if (is_ptr_in_range(s, 0, &_end)) {
  558.     return NULL;
  559.     }
  560.     /* consider stuff on the stack to also be in the NULL pool...
  561.      * XXX: there's cases where we don't want to assume this
  562.      */
  563.     if ((stack_direction == -1 && is_ptr_in_range(s, &ts, known_stack_point))
  564.     || (stack_direction == 1 && is_ptr_in_range(s, known_stack_point, &ts))) {
  565.     abort();
  566.     return NULL;
  567.     }
  568.     ap_block_alarms();
  569.     /* search the global_block_list */
  570.     for (pb = &global_block_list; *pb; pb = &b->h.global_next) {
  571.     b = *pb;
  572.     if (is_ptr_in_range(s, b, b->h.endp)) {
  573.         if (b->h.owning_pool == FREE_POOL) {
  574.         fprintf(stderr,
  575.             "Ouch!  find_pool() called on pointer in a free block\n");
  576.         abort();
  577.         exit(1);
  578.         }
  579.         if (b != global_block_list) {
  580.         /* promote b to front of list, this is a hack to speed
  581.          * up the lookup */
  582.         *pb = b->h.global_next;
  583.         b->h.global_next = global_block_list;
  584.         global_block_list = b;
  585.         }
  586.         ap_unblock_alarms();
  587.         return b->h.owning_pool;
  588.     }
  589.     }
  590.     ap_unblock_alarms();
  591.     return NULL;
  592. }
  593.  
  594. /* return TRUE iff a is an ancestor of b
  595.  * NULL is considered an ancestor of all pools
  596.  */
  597. API_EXPORT(int) ap_pool_is_ancestor(pool *a, pool *b)
  598. {
  599.     if (a == NULL) {
  600.     return 1;
  601.     }
  602.     while (a->joined) {
  603.     a = a->joined;
  604.     }
  605.     while (b) {
  606.     if (a == b) {
  607.         return 1;
  608.     }
  609.     b = b->parent;
  610.     }
  611.     return 0;
  612. }
  613.  
  614. /* All blocks belonging to sub will be changed to point to p
  615.  * instead.  This is a guarantee by the caller that sub will not
  616.  * be destroyed before p is.
  617.  */
  618. API_EXPORT(void) ap_pool_join(pool *p, pool *sub)
  619. {
  620.     union block_hdr *b;
  621.  
  622.     /* We could handle more general cases... but this is it for now. */
  623.     if (sub->parent != p) {
  624.     fprintf(stderr, "pool_join: p is not parent of sub\n");
  625.     abort();
  626.     }
  627.     ap_block_alarms();
  628.     while (p->joined) {
  629.     p = p->joined;
  630.     }
  631.     sub->joined = p;
  632.     for (b = global_block_list; b; b = b->h.global_next) {
  633.     if (b->h.owning_pool == sub) {
  634.         b->h.owning_pool = p;
  635.     }
  636.     }
  637.     ap_unblock_alarms();
  638. }
  639. #endif
  640.  
  641. /*****************************************************************
  642.  *
  643.  * Allocating stuff...
  644.  */
  645.  
  646.  
  647. API_EXPORT(void *) ap_palloc(struct pool *a, int reqsize)
  648. {
  649. #ifdef ALLOC_USE_MALLOC
  650.     int size = reqsize + CLICK_SZ;
  651.     void *ptr;
  652.  
  653.     ap_block_alarms();
  654.     ptr = malloc(size);
  655.     if (ptr == NULL) {
  656.     fputs("Ouch!  Out of memory!\n", stderr);
  657.     exit(1);
  658.     }
  659.     debug_fill(ptr, size); /* might as well get uninitialized protection */
  660.     *(void **)ptr = a->allocation_list;
  661.     a->allocation_list = ptr;
  662.     ap_unblock_alarms();
  663.     return (char *)ptr + CLICK_SZ;
  664. #else
  665.  
  666.     /* Round up requested size to an even number of alignment units (core clicks)
  667.      */
  668.  
  669.     int nclicks = 1 + ((reqsize - 1) / CLICK_SZ);
  670.     int size = nclicks * CLICK_SZ;
  671.  
  672.     /* First, see if we have space in the block most recently
  673.      * allocated to this pool
  674.      */
  675.  
  676.     union block_hdr *blok = a->last;
  677.     char *first_avail = blok->h.first_avail;
  678.     char *new_first_avail;
  679.  
  680.     if (reqsize <= 0)
  681.     return NULL;
  682.  
  683.     new_first_avail = first_avail + size;
  684.  
  685.     if (new_first_avail <= blok->h.endp) {
  686.     debug_verify_filled(first_avail, blok->h.endp,
  687.         "Ouch!  Someone trounced past the end of their allocation!\n");
  688.     blok->h.first_avail = new_first_avail;
  689.     return (void *) first_avail;
  690.     }
  691.  
  692.     /* Nope --- get a new one that's guaranteed to be big enough */
  693.  
  694.     ap_block_alarms();
  695.  
  696.     (void) ap_acquire_mutex(alloc_mutex);
  697.  
  698.     blok = new_block(size);
  699.     a->last->h.next = blok;
  700.     a->last = blok;
  701. #ifdef POOL_DEBUG
  702.     blok->h.owning_pool = a;
  703. #endif
  704.  
  705.     (void) ap_release_mutex(alloc_mutex);
  706.  
  707.     ap_unblock_alarms();
  708.  
  709.     first_avail = blok->h.first_avail;
  710.     blok->h.first_avail += size;
  711.  
  712.     return (void *) first_avail;
  713. #endif
  714. }
  715.  
  716. API_EXPORT(void *) ap_pcalloc(struct pool *a, int size)
  717. {
  718.     void *res = ap_palloc(a, size);
  719.     memset(res, '\0', size);
  720.     return res;
  721. }
  722.  
  723. API_EXPORT(char *) ap_pstrdup(struct pool *a, const char *s)
  724. {
  725.     char *res;
  726.     size_t len;
  727.  
  728.     if (s == NULL)
  729.     return NULL;
  730.     len = strlen(s) + 1;
  731.     res = ap_palloc(a, len);
  732.     memcpy(res, s, len);
  733.     return res;
  734. }
  735.  
  736. API_EXPORT(char *) ap_pstrndup(struct pool *a, const char *s, int n)
  737. {
  738.     char *res;
  739.  
  740.     if (s == NULL)
  741.     return NULL;
  742.     res = ap_palloc(a, n + 1);
  743.     memcpy(res, s, n);
  744.     res[n] = '\0';
  745.     return res;
  746. }
  747.  
  748. API_EXPORT_NONSTD(char *) ap_pstrcat(pool *a,...)
  749. {
  750.     char *cp, *argp, *res;
  751.  
  752.     /* Pass one --- find length of required string */
  753.  
  754.     int len = 0;
  755.     va_list adummy;
  756.  
  757.     va_start(adummy, a);
  758.  
  759.     while ((cp = va_arg(adummy, char *)) != NULL)
  760.          len += strlen(cp);
  761.  
  762.     va_end(adummy);
  763.  
  764.     /* Allocate the required string */
  765.  
  766.     res = (char *) ap_palloc(a, len + 1);
  767.     cp = res;
  768.     *cp = '\0';
  769.  
  770.     /* Pass two --- copy the argument strings into the result space */
  771.  
  772.     va_start(adummy, a);
  773.  
  774.     while ((argp = va_arg(adummy, char *)) != NULL) {
  775.     strcpy(cp, argp);
  776.     cp += strlen(argp);
  777.     }
  778.  
  779.     va_end(adummy);
  780.  
  781.     /* Return the result string */
  782.  
  783.     return res;
  784. }
  785.  
  786. /* ap_psprintf is implemented by writing directly into the current
  787.  * block of the pool, starting right at first_avail.  If there's
  788.  * insufficient room, then a new block is allocated and the earlier
  789.  * output is copied over.  The new block isn't linked into the pool
  790.  * until all the output is done.
  791.  *
  792.  * Note that this is completely safe because nothing else can
  793.  * allocate in this pool while ap_psprintf is running.  alarms are
  794.  * blocked, and the only thing outside of alloc.c that's invoked
  795.  * is ap_vformatter -- which was purposefully written to be
  796.  * self-contained with no callouts.
  797.  */
  798.  
  799. struct psprintf_data {
  800.     ap_vformatter_buff vbuff;
  801. #ifdef ALLOC_USE_MALLOC
  802.     char *base;
  803. #else
  804.     union block_hdr *blok;
  805.     int got_a_new_block;
  806. #endif
  807. };
  808.  
  809. static int psprintf_flush(ap_vformatter_buff *vbuff)
  810. {
  811.     struct psprintf_data *ps = (struct psprintf_data *)vbuff;
  812. #ifdef ALLOC_USE_MALLOC
  813.     int size;
  814.     char *ptr;
  815.  
  816.     size = (char *)ps->vbuff.curpos - ps->base;
  817.     ptr = realloc(ps->base, 2*size);
  818.     if (ptr == NULL) {
  819.     fputs("Ouch!  Out of memory!\n", stderr);
  820.     exit(1);
  821.     }
  822.     ps->base = ptr;
  823.     ps->vbuff.curpos = ptr + size;
  824.     ps->vbuff.endpos = ptr + 2*size - 1;
  825.     return 0;
  826. #else
  827.     union block_hdr *blok;
  828.     union block_hdr *nblok;
  829.     size_t cur_len;
  830.     char *strp;
  831.  
  832.     blok = ps->blok;
  833.     strp = ps->vbuff.curpos;
  834.     cur_len = strp - blok->h.first_avail;
  835.  
  836.     /* must try another blok */
  837.     (void) ap_acquire_mutex(alloc_mutex);
  838.     nblok = new_block(2 * cur_len);
  839.     (void) ap_release_mutex(alloc_mutex);
  840.     memcpy(nblok->h.first_avail, blok->h.first_avail, cur_len);
  841.     ps->vbuff.curpos = nblok->h.first_avail + cur_len;
  842.     /* save a byte for the NUL terminator */
  843.     ps->vbuff.endpos = nblok->h.endp - 1;
  844.  
  845.     /* did we allocate the current blok? if so free it up */
  846.     if (ps->got_a_new_block) {
  847.     debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail);
  848.     (void) ap_acquire_mutex(alloc_mutex);
  849.     blok->h.next = block_freelist;
  850.     block_freelist = blok;
  851.     (void) ap_release_mutex(alloc_mutex);
  852.     }
  853.     ps->blok = nblok;
  854.     ps->got_a_new_block = 1;
  855.     /* note that we've deliberately not linked the new block onto
  856.      * the pool yet... because we may need to flush again later, and
  857.      * we'd have to spend more effort trying to unlink the block.
  858.      */
  859.     return 0;
  860. #endif
  861. }
  862.  
  863. API_EXPORT(char *) ap_pvsprintf(pool *p, const char *fmt, va_list ap)
  864. {
  865. #ifdef ALLOC_USE_MALLOC
  866.     struct psprintf_data ps;
  867.     void *ptr;
  868.  
  869.     ap_block_alarms();
  870.     ps.base = malloc(512);
  871.     if (ps.base == NULL) {
  872.     fputs("Ouch!  Out of memory!\n", stderr);
  873.     exit(1);
  874.     }
  875.     /* need room at beginning for allocation_list */
  876.     ps.vbuff.curpos = ps.base + CLICK_SZ;
  877.     ps.vbuff.endpos = ps.base + 511;
  878.     ap_vformatter(psprintf_flush, &ps.vbuff, fmt, ap);
  879.     *ps.vbuff.curpos++ = '\0';
  880.     ptr = ps.base;
  881.     /* shrink */
  882.     ptr = realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr);
  883.     if (ptr == NULL) {
  884.     fputs("Ouch!  Out of memory!\n", stderr);
  885.     exit(1);
  886.     }
  887.     *(void **)ptr = p->allocation_list;
  888.     p->allocation_list = ptr;
  889.     ap_unblock_alarms();
  890.     return (char *)ptr + CLICK_SZ;
  891. #else
  892.     struct psprintf_data ps;
  893.     char *strp;
  894.     int size;
  895.  
  896.     ap_block_alarms();
  897.     ps.blok = p->last;
  898.     ps.vbuff.curpos = ps.blok->h.first_avail;
  899.     ps.vbuff.endpos = ps.blok->h.endp - 1;    /* save one for NUL */
  900.     ps.got_a_new_block = 0;
  901.  
  902.     ap_vformatter(psprintf_flush, &ps.vbuff, fmt, ap);
  903.  
  904.     strp = ps.vbuff.curpos;
  905.     *strp++ = '\0';
  906.  
  907.     size = strp - ps.blok->h.first_avail;
  908.     size = (1 + ((size - 1) / CLICK_SZ)) * CLICK_SZ;
  909.     strp = ps.blok->h.first_avail;    /* save away result pointer */
  910.     ps.blok->h.first_avail += size;
  911.  
  912.     /* have to link the block in if it's a new one */
  913.     if (ps.got_a_new_block) {
  914.     p->last->h.next = ps.blok;
  915.     p->last = ps.blok;
  916. #ifdef POOL_DEBUG
  917.     ps.blok->h.owning_pool = p;
  918. #endif
  919.     }
  920.     ap_unblock_alarms();
  921.  
  922.     return strp;
  923. #endif
  924. }
  925.  
  926. API_EXPORT_NONSTD(char *) ap_psprintf(pool *p, const char *fmt, ...)
  927. {
  928.     va_list ap;
  929.     char *res;
  930.  
  931.     va_start(ap, fmt);
  932.     res = ap_pvsprintf(p, fmt, ap);
  933.     va_end(ap);
  934.     return res;
  935. }
  936.  
  937. /*****************************************************************
  938.  *
  939.  * The 'array' functions...
  940.  */
  941.  
  942. static void make_array_core(array_header *res, pool *p, int nelts, int elt_size)
  943. {
  944.     if (nelts < 1)
  945.     nelts = 1;        /* Assure sanity if someone asks for
  946.                  * array of zero elts.
  947.                  */
  948.  
  949.     res->elts = ap_pcalloc(p, nelts * elt_size);
  950.  
  951.     res->pool = p;
  952.     res->elt_size = elt_size;
  953.     res->nelts = 0;        /* No active elements yet... */
  954.     res->nalloc = nelts;    /* ...but this many allocated */
  955. }
  956.  
  957. API_EXPORT(array_header *) ap_make_array(pool *p, int nelts, int elt_size)
  958. {
  959.     array_header *res = (array_header *) ap_palloc(p, sizeof(array_header));
  960.  
  961.     make_array_core(res, p, nelts, elt_size);
  962.     return res;
  963. }
  964.  
  965. API_EXPORT(void *) ap_push_array(array_header *arr)
  966. {
  967.     if (arr->nelts == arr->nalloc) {
  968.     int new_size = (arr->nalloc <= 0) ? 1 : arr->nalloc * 2;
  969.     char *new_data;
  970.  
  971.     new_data = ap_pcalloc(arr->pool, arr->elt_size * new_size);
  972.  
  973.     memcpy(new_data, arr->elts, arr->nalloc * arr->elt_size);
  974.     arr->elts = new_data;
  975.     arr->nalloc = new_size;
  976.     }
  977.  
  978.     ++arr->nelts;
  979.     return arr->elts + (arr->elt_size * (arr->nelts - 1));
  980. }
  981.  
  982. API_EXPORT(void) ap_array_cat(array_header *dst, const array_header *src)
  983. {
  984.     int elt_size = dst->elt_size;
  985.  
  986.     if (dst->nelts + src->nelts > dst->nalloc) {
  987.     int new_size = (dst->nalloc <= 0) ? 1 : dst->nalloc * 2;
  988.     char *new_data;
  989.  
  990.     while (dst->nelts + src->nelts > new_size)
  991.         new_size *= 2;
  992.  
  993.     new_data = ap_pcalloc(dst->pool, elt_size * new_size);
  994.     memcpy(new_data, dst->elts, dst->nalloc * elt_size);
  995.  
  996.     dst->elts = new_data;
  997.     dst->nalloc = new_size;
  998.     }
  999.  
  1000.     memcpy(dst->elts + dst->nelts * elt_size, src->elts, elt_size * src->nelts);
  1001.     dst->nelts += src->nelts;
  1002. }
  1003.  
  1004. API_EXPORT(array_header *) ap_copy_array(pool *p, const array_header *arr)
  1005. {
  1006.     array_header *res = ap_make_array(p, arr->nalloc, arr->elt_size);
  1007.  
  1008.     memcpy(res->elts, arr->elts, arr->elt_size * arr->nelts);
  1009.     res->nelts = arr->nelts;
  1010.     return res;
  1011. }
  1012.  
  1013. /* This cute function copies the array header *only*, but arranges
  1014.  * for the data section to be copied on the first push or arraycat.
  1015.  * It's useful when the elements of the array being copied are
  1016.  * read only, but new stuff *might* get added on the end; we have the
  1017.  * overhead of the full copy only where it is really needed.
  1018.  */
  1019.  
  1020. static ap_inline void copy_array_hdr_core(array_header *res,
  1021.     const array_header *arr)
  1022. {
  1023.     res->elts = arr->elts;
  1024.     res->elt_size = arr->elt_size;
  1025.     res->nelts = arr->nelts;
  1026.     res->nalloc = arr->nelts;    /* Force overflow on push */
  1027. }
  1028.  
  1029. API_EXPORT(array_header *) ap_copy_array_hdr(pool *p, const array_header *arr)
  1030. {
  1031.     array_header *res = (array_header *) ap_palloc(p, sizeof(array_header));
  1032.  
  1033.     res->pool = p;
  1034.     copy_array_hdr_core(res, arr);
  1035.     return res;
  1036. }
  1037.  
  1038. /* The above is used here to avoid consing multiple new array bodies... */
  1039.  
  1040. API_EXPORT(array_header *) ap_append_arrays(pool *p,
  1041.                      const array_header *first,
  1042.                      const array_header *second)
  1043. {
  1044.     array_header *res = ap_copy_array_hdr(p, first);
  1045.  
  1046.     ap_array_cat(res, second);
  1047.     return res;
  1048. }
  1049.  
  1050. /* ap_array_pstrcat generates a new string from the pool containing
  1051.  * the concatenated sequence of substrings referenced as elements within
  1052.  * the array.  The string will be empty if all substrings are empty or null,
  1053.  * or if there are no elements in the array.
  1054.  * If sep is non-NUL, it will be inserted between elements as a separator.
  1055.  */
  1056. API_EXPORT(char *) ap_array_pstrcat(pool *p, const array_header *arr,
  1057.                                     const char sep)
  1058. {
  1059.     char *cp, *res, **strpp;
  1060.     int i, len;
  1061.  
  1062.     if (arr->nelts <= 0 || arr->elts == NULL)      /* Empty table? */
  1063.         return (char *) ap_pcalloc(p, 1);
  1064.  
  1065.     /* Pass one --- find length of required string */
  1066.  
  1067.     len = 0;
  1068.     for (i = 0, strpp = (char **) arr->elts; ; ++strpp) {
  1069.         if (strpp && *strpp != NULL) {
  1070.             len += strlen(*strpp);
  1071.         }
  1072.         if (++i >= arr->nelts)
  1073.             break;
  1074.         if (sep)
  1075.             ++len;
  1076.     }
  1077.  
  1078.     /* Allocate the required string */
  1079.  
  1080.     res = (char *) ap_palloc(p, len + 1);
  1081.     cp = res;
  1082.  
  1083.     /* Pass two --- copy the argument strings into the result space */
  1084.  
  1085.     for (i = 0, strpp = (char **) arr->elts; ; ++strpp) {
  1086.         if (strpp && *strpp != NULL) {
  1087.             len = strlen(*strpp);
  1088.             memcpy(cp, *strpp, len);
  1089.             cp += len;
  1090.         }
  1091.         if (++i >= arr->nelts)
  1092.             break;
  1093.         if (sep)
  1094.             *cp++ = sep;
  1095.     }
  1096.  
  1097.     *cp = '\0';
  1098.  
  1099.     /* Return the result string */
  1100.  
  1101.     return res;
  1102. }
  1103.  
  1104.  
  1105. /*****************************************************************
  1106.  *
  1107.  * The "table" functions.
  1108.  */
  1109.  
  1110. /* XXX: if you tweak this you should look at is_empty_table() and table_elts()
  1111.  * in alloc.h */
  1112. struct table {
  1113.     /* This has to be first to promote backwards compatibility with
  1114.      * older modules which cast a table * to an array_header *...
  1115.      * they should use the table_elts() function for most of the
  1116.      * cases they do this for.
  1117.      */
  1118.     array_header a;
  1119. #ifdef MAKE_TABLE_PROFILE
  1120.     void *creator;
  1121. #endif
  1122. };
  1123.  
  1124. #ifdef MAKE_TABLE_PROFILE
  1125. static table_entry *table_push(table *t)
  1126. {
  1127.     if (t->a.nelts == t->a.nalloc) {
  1128.     fprintf(stderr,
  1129.         "table_push: table created by %p hit limit of %u\n",
  1130.         t->creator, t->a.nalloc);
  1131.     }
  1132.     return (table_entry *) ap_push_array(&t->a);
  1133. }
  1134. #else
  1135. #define table_push(t)    ((table_entry *) ap_push_array(&(t)->a))
  1136. #endif
  1137.  
  1138.  
  1139. API_EXPORT(table *) ap_make_table(pool *p, int nelts)
  1140. {
  1141.     table *t = ap_palloc(p, sizeof(table));
  1142.  
  1143.     make_array_core(&t->a, p, nelts, sizeof(table_entry));
  1144. #ifdef MAKE_TABLE_PROFILE
  1145.     t->creator = __builtin_return_address(0);
  1146. #endif
  1147.     return t;
  1148. }
  1149.  
  1150. API_EXPORT(table *) ap_copy_table(pool *p, const table *t)
  1151. {
  1152.     table *new = ap_palloc(p, sizeof(table));
  1153.  
  1154. #ifdef POOL_DEBUG
  1155.     /* we don't copy keys and values, so it's necessary that t->a.pool
  1156.      * have a life span at least as long as p
  1157.      */
  1158.     if (!ap_pool_is_ancestor(t->a.pool, p)) {
  1159.     fprintf(stderr, "copy_table: t's pool is not an ancestor of p\n");
  1160.     abort();
  1161.     }
  1162. #endif
  1163.     make_array_core(&new->a, p, t->a.nalloc, sizeof(table_entry));
  1164.     memcpy(new->a.elts, t->a.elts, t->a.nelts * sizeof(table_entry));
  1165.     new->a.nelts = t->a.nelts;
  1166.     return new;
  1167. }
  1168.  
  1169. API_EXPORT(void) ap_clear_table(table *t)
  1170. {
  1171.     t->a.nelts = 0;
  1172. }
  1173.  
  1174. API_EXPORT(const char *) ap_table_get(const table *t, const char *key)
  1175. {
  1176.     table_entry *elts = (table_entry *) t->a.elts;
  1177.     int i;
  1178.  
  1179.     if (key == NULL)
  1180.     return NULL;
  1181.  
  1182.     for (i = 0; i < t->a.nelts; ++i)
  1183.     if (!strcasecmp(elts[i].key, key))
  1184.         return elts[i].val;
  1185.  
  1186.     return NULL;
  1187. }
  1188.  
  1189. API_EXPORT(void) ap_table_set(table *t, const char *key, const char *val)
  1190. {
  1191.     register int i, j, k;
  1192.     table_entry *elts = (table_entry *) t->a.elts;
  1193.     int done = 0;
  1194.  
  1195.     for (i = 0; i < t->a.nelts; ) {
  1196.     if (!strcasecmp(elts[i].key, key)) {
  1197.         if (!done) {
  1198.         elts[i].val = ap_pstrdup(t->a.pool, val);
  1199.         done = 1;
  1200.         ++i;
  1201.         }
  1202.         else {        /* delete an extraneous element */
  1203.         for (j = i, k = i + 1; k < t->a.nelts; ++j, ++k) {
  1204.             elts[j].key = elts[k].key;
  1205.             elts[j].val = elts[k].val;
  1206.         }
  1207.         --t->a.nelts;
  1208.         }
  1209.     }
  1210.     else {
  1211.         ++i;
  1212.     }
  1213.     }
  1214.  
  1215.     if (!done) {
  1216.     elts = (table_entry *) table_push(t);
  1217.     elts->key = ap_pstrdup(t->a.pool, key);
  1218.     elts->val = ap_pstrdup(t->a.pool, val);
  1219.     }
  1220. }
  1221.  
  1222. API_EXPORT(void) ap_table_setn(table *t, const char *key, const char *val)
  1223. {
  1224.     register int i, j, k;
  1225.     table_entry *elts = (table_entry *) t->a.elts;
  1226.     int done = 0;
  1227.  
  1228. #ifdef POOL_DEBUG
  1229.     {
  1230.     if (!ap_pool_is_ancestor(ap_find_pool(key), t->a.pool)) {
  1231.         fprintf(stderr, "table_set: key not in ancestor pool of t\n");
  1232.         abort();
  1233.     }
  1234.     if (!ap_pool_is_ancestor(ap_find_pool(val), t->a.pool)) {
  1235.         fprintf(stderr, "table_set: val not in ancestor pool of t\n");
  1236.         abort();
  1237.     }
  1238.     }
  1239. #endif
  1240.  
  1241.     for (i = 0; i < t->a.nelts; ) {
  1242.     if (!strcasecmp(elts[i].key, key)) {
  1243.         if (!done) {
  1244.         elts[i].val = (char *)val;
  1245.         done = 1;
  1246.         ++i;
  1247.         }
  1248.         else {        /* delete an extraneous element */
  1249.         for (j = i, k = i + 1; k < t->a.nelts; ++j, ++k) {
  1250.             elts[j].key = elts[k].key;
  1251.             elts[j].val = elts[k].val;
  1252.         }
  1253.         --t->a.nelts;
  1254.         }
  1255.     }
  1256.     else {
  1257.         ++i;
  1258.     }
  1259.     }
  1260.  
  1261.     if (!done) {
  1262.     elts = (table_entry *) table_push(t);
  1263.     elts->key = (char *)key;
  1264.     elts->val = (char *)val;
  1265.     }
  1266. }
  1267.  
  1268. API_EXPORT(void) ap_table_unset(table *t, const char *key)
  1269. {
  1270.     register int i, j, k;
  1271.     table_entry *elts = (table_entry *) t->a.elts;
  1272.  
  1273.     for (i = 0; i < t->a.nelts;) {
  1274.     if (!strcasecmp(elts[i].key, key)) {
  1275.  
  1276.         /* found an element to skip over
  1277.          * there are any number of ways to remove an element from
  1278.          * a contiguous block of memory.  I've chosen one that
  1279.          * doesn't do a memcpy/bcopy/array_delete, *shrug*...
  1280.          */
  1281.         for (j = i, k = i + 1; k < t->a.nelts; ++j, ++k) {
  1282.         elts[j].key = elts[k].key;
  1283.         elts[j].val = elts[k].val;
  1284.         }
  1285.         --t->a.nelts;
  1286.     }
  1287.     else {
  1288.         ++i;
  1289.     }
  1290.     }
  1291. }
  1292.  
  1293. API_EXPORT(void) ap_table_merge(table *t, const char *key, const char *val)
  1294. {
  1295.     table_entry *elts = (table_entry *) t->a.elts;
  1296.     int i;
  1297.  
  1298.     for (i = 0; i < t->a.nelts; ++i)
  1299.     if (!strcasecmp(elts[i].key, key)) {
  1300.         elts[i].val = ap_pstrcat(t->a.pool, elts[i].val, ", ", val, NULL);
  1301.         return;
  1302.     }
  1303.  
  1304.     elts = (table_entry *) table_push(t);
  1305.     elts->key = ap_pstrdup(t->a.pool, key);
  1306.     elts->val = ap_pstrdup(t->a.pool, val);
  1307. }
  1308.  
  1309. API_EXPORT(void) ap_table_mergen(table *t, const char *key, const char *val)
  1310. {
  1311.     table_entry *elts = (table_entry *) t->a.elts;
  1312.     int i;
  1313.  
  1314. #ifdef POOL_DEBUG
  1315.     {
  1316.     if (!ap_pool_is_ancestor(ap_find_pool(key), t->a.pool)) {
  1317.         fprintf(stderr, "table_set: key not in ancestor pool of t\n");
  1318.         abort();
  1319.     }
  1320.     if (!ap_pool_is_ancestor(ap_find_pool(val), t->a.pool)) {
  1321.         fprintf(stderr, "table_set: key not in ancestor pool of t\n");
  1322.         abort();
  1323.     }
  1324.     }
  1325. #endif
  1326.  
  1327.     for (i = 0; i < t->a.nelts; ++i) {
  1328.     if (!strcasecmp(elts[i].key, key)) {
  1329.         elts[i].val = ap_pstrcat(t->a.pool, elts[i].val, ", ", val, NULL);
  1330.         return;
  1331.     }
  1332.     }
  1333.  
  1334.     elts = (table_entry *) table_push(t);
  1335.     elts->key = (char *)key;
  1336.     elts->val = (char *)val;
  1337. }
  1338.  
  1339. API_EXPORT(void) ap_table_add(table *t, const char *key, const char *val)
  1340. {
  1341.     table_entry *elts = (table_entry *) t->a.elts;
  1342.  
  1343.     elts = (table_entry *) table_push(t);
  1344.     elts->key = ap_pstrdup(t->a.pool, key);
  1345.     elts->val = ap_pstrdup(t->a.pool, val);
  1346. }
  1347.  
  1348. API_EXPORT(void) ap_table_addn(table *t, const char *key, const char *val)
  1349. {
  1350.     table_entry *elts = (table_entry *) t->a.elts;
  1351.  
  1352. #ifdef POOL_DEBUG
  1353.     {
  1354.     if (!ap_pool_is_ancestor(ap_find_pool(key), t->a.pool)) {
  1355.         fprintf(stderr, "table_set: key not in ancestor pool of t\n");
  1356.         abort();
  1357.     }
  1358.     if (!ap_pool_is_ancestor(ap_find_pool(val), t->a.pool)) {
  1359.         fprintf(stderr, "table_set: key not in ancestor pool of t\n");
  1360.         abort();
  1361.     }
  1362.     }
  1363. #endif
  1364.  
  1365.     elts = (table_entry *) table_push(t);
  1366.     elts->key = (char *)key;
  1367.     elts->val = (char *)val;
  1368. }
  1369.  
  1370. API_EXPORT(table *) ap_overlay_tables(pool *p, const table *overlay, const table *base)
  1371. {
  1372.     table *res;
  1373.  
  1374. #ifdef POOL_DEBUG
  1375.     /* we don't copy keys and values, so it's necessary that
  1376.      * overlay->a.pool and base->a.pool have a life span at least
  1377.      * as long as p
  1378.      */
  1379.     if (!ap_pool_is_ancestor(overlay->a.pool, p)) {
  1380.     fprintf(stderr, "overlay_tables: overlay's pool is not an ancestor of p\n");
  1381.     abort();
  1382.     }
  1383.     if (!ap_pool_is_ancestor(base->a.pool, p)) {
  1384.     fprintf(stderr, "overlay_tables: base's pool is not an ancestor of p\n");
  1385.     abort();
  1386.     }
  1387. #endif
  1388.  
  1389.     res = ap_palloc(p, sizeof(table));
  1390.     /* behave like append_arrays */
  1391.     res->a.pool = p;
  1392.     copy_array_hdr_core(&res->a, &overlay->a);
  1393.     ap_array_cat(&res->a, &base->a);
  1394.  
  1395.     return res;
  1396. }
  1397.  
  1398. /* And now for something completely abstract ...
  1399.  
  1400.  * For each key value given as a vararg:
  1401.  *   run the function pointed to as
  1402.  *     int comp(void *r, char *key, char *value);
  1403.  *   on each valid key-value pair in the table t that matches the vararg key,
  1404.  *   or once for every valid key-value pair if the vararg list is empty,
  1405.  *   until the function returns false (0) or we finish the table.
  1406.  *
  1407.  * Note that we restart the traversal for each vararg, which means that
  1408.  * duplicate varargs will result in multiple executions of the function
  1409.  * for each matching key.  Note also that if the vararg list is empty,
  1410.  * only one traversal will be made and will cut short if comp returns 0.
  1411.  *
  1412.  * Note that the table_get and table_merge functions assume that each key in
  1413.  * the table is unique (i.e., no multiple entries with the same key).  This
  1414.  * function does not make that assumption, since it (unfortunately) isn't
  1415.  * true for some of Apache's tables.
  1416.  *
  1417.  * Note that rec is simply passed-on to the comp function, so that the
  1418.  * caller can pass additional info for the task.
  1419.  */
  1420. API_EXPORT(void) ap_table_do(int (*comp) (void *, const char *, const char *), void *rec,
  1421.           const table *t,...)
  1422. {
  1423.     va_list vp;
  1424.     char *argp;
  1425.     table_entry *elts = (table_entry *) t->a.elts;
  1426.     int rv, i;
  1427.  
  1428.     va_start(vp, t);
  1429.  
  1430.     argp = va_arg(vp, char *);
  1431.  
  1432.     do {
  1433.     for (rv = 1, i = 0; rv && (i < t->a.nelts); ++i) {
  1434.         if (elts[i].key && (!argp || !strcasecmp(elts[i].key, argp))) {
  1435.         rv = (*comp) (rec, elts[i].key, elts[i].val);
  1436.         }
  1437.     }
  1438.     } while (argp && ((argp = va_arg(vp, char *)) != NULL));
  1439.  
  1440.     va_end(vp);
  1441. }
  1442.  
  1443. /* Curse libc and the fact that it doesn't guarantee a stable sort.  We
  1444.  * have to enforce stability ourselves by using the order field.  If it
  1445.  * provided a stable sort then we wouldn't even need temporary storage to
  1446.  * do the work below. -djg
  1447.  *
  1448.  * ("stable sort" means that equal keys retain their original relative
  1449.  * ordering in the output.)
  1450.  */
  1451. typedef struct {
  1452.     char *key;
  1453.     char *val;
  1454.     int order;
  1455. } overlap_key;
  1456.  
  1457. static int sort_overlap(const void *va, const void *vb)
  1458. {
  1459.     const overlap_key *a = va;
  1460.     const overlap_key *b = vb;
  1461.     int r;
  1462.  
  1463.     r = strcasecmp(a->key, b->key);
  1464.     if (r) {
  1465.     return r;
  1466.     }
  1467.     return a->order - b->order;
  1468. }
  1469.  
  1470. /* prefer to use the stack for temp storage for overlaps smaller than this */
  1471. #ifndef AP_OVERLAP_TABLES_ON_STACK
  1472. #define AP_OVERLAP_TABLES_ON_STACK    (512)
  1473. #endif
  1474.  
  1475. API_EXPORT(void) ap_overlap_tables(table *a, const table *b, unsigned flags)
  1476. {
  1477.     overlap_key cat_keys_buf[AP_OVERLAP_TABLES_ON_STACK];
  1478.     overlap_key *cat_keys;
  1479.     int nkeys;
  1480.     table_entry *e;
  1481.     table_entry *last_e;
  1482.     overlap_key *left;
  1483.     overlap_key *right;
  1484.     overlap_key *last;
  1485.  
  1486.     nkeys = a->a.nelts + b->a.nelts;
  1487.     if (nkeys < AP_OVERLAP_TABLES_ON_STACK) {
  1488.     cat_keys = cat_keys_buf;
  1489.     }
  1490.     else {
  1491.     /* XXX: could use scratch free space in a or b's pool instead...
  1492.      * which could save an allocation in b's pool.
  1493.      */
  1494.     cat_keys = ap_palloc(b->a.pool, sizeof(overlap_key) * nkeys);
  1495.     }
  1496.  
  1497.     nkeys = 0;
  1498.  
  1499.     /* Create a list of the entries from a concatenated with the entries
  1500.      * from b.
  1501.      */
  1502.     e = (table_entry *)a->a.elts;
  1503.     last_e = e + a->a.nelts;
  1504.     while (e < last_e) {
  1505.     cat_keys[nkeys].key = e->key;
  1506.     cat_keys[nkeys].val = e->val;
  1507.     cat_keys[nkeys].order = nkeys;
  1508.     ++nkeys;
  1509.     ++e;
  1510.     }
  1511.  
  1512.     e = (table_entry *)b->a.elts;
  1513.     last_e = e + b->a.nelts;
  1514.     while (e < last_e) {
  1515.     cat_keys[nkeys].key = e->key;
  1516.     cat_keys[nkeys].val = e->val;
  1517.     cat_keys[nkeys].order = nkeys;
  1518.     ++nkeys;
  1519.     ++e;
  1520.     }
  1521.  
  1522.     qsort(cat_keys, nkeys, sizeof(overlap_key), sort_overlap);
  1523.  
  1524.     /* Now iterate over the sorted list and rebuild a.
  1525.      * Start by making sure it has enough space.
  1526.      */
  1527.     a->a.nelts = 0;
  1528.     if (a->a.nalloc < nkeys) {
  1529.     a->a.elts = ap_palloc(a->a.pool, a->a.elt_size * nkeys * 2);
  1530.     a->a.nalloc = nkeys * 2;
  1531.     }
  1532.  
  1533.     /*
  1534.      * In both the merge and set cases we retain the invariant:
  1535.      *
  1536.      * left->key, (left+1)->key, (left+2)->key, ..., (right-1)->key
  1537.      * are all equal keys.  (i.e. strcasecmp returns 0)
  1538.      *
  1539.      * We essentially need to find the maximal
  1540.      * right for each key, then we can do a quick merge or set as
  1541.      * appropriate.
  1542.      */
  1543.  
  1544.     if (flags & AP_OVERLAP_TABLES_MERGE) {
  1545.     left = cat_keys;
  1546.     last = left + nkeys;
  1547.     while (left < last) {
  1548.         right = left + 1;
  1549.         if (right == last
  1550.         || strcasecmp(left->key, right->key)) {
  1551.         ap_table_addn(a, left->key, left->val);
  1552.         left = right;
  1553.         }
  1554.         else {
  1555.         char *strp;
  1556.         char *value;
  1557.         size_t len;
  1558.  
  1559.         /* Have to merge some headers.  Let's re-use the order field,
  1560.          * since it's handy... we'll store the length of val there.
  1561.          */
  1562.         left->order = strlen(left->val);
  1563.         len = left->order;
  1564.         do {
  1565.             right->order = strlen(right->val);
  1566.             len += 2 + right->order;
  1567.             ++right;
  1568.         } while (right < last
  1569.             && !strcasecmp(left->key, right->key));
  1570.         /* right points one past the last header to merge */
  1571.         value = ap_palloc(a->a.pool, len + 1);
  1572.         strp = value;
  1573.         for (;;) {
  1574.             memcpy(strp, left->val, left->order);
  1575.             strp += left->order;
  1576.             ++left;
  1577.             if (left == right) break;
  1578.             *strp++ = ',';
  1579.             *strp++ = ' ';
  1580.         }
  1581.         *strp = 0;
  1582.         ap_table_addn(a, (left-1)->key, value);
  1583.         }
  1584.     }
  1585.     }
  1586.     else {
  1587.     left = cat_keys;
  1588.     last = left + nkeys;
  1589.     while (left < last) {
  1590.         right = left + 1;
  1591.         while (right < last && !strcasecmp(left->key, right->key)) {
  1592.         ++right;
  1593.         }
  1594.         ap_table_addn(a, (right-1)->key, (right-1)->val);
  1595.         left = right;
  1596.     }
  1597.     }
  1598. }
  1599.  
  1600. /*****************************************************************
  1601.  *
  1602.  * Managing generic cleanups.  
  1603.  */
  1604.  
  1605. struct cleanup {
  1606.     void *data;
  1607.     void (*plain_cleanup) (void *);
  1608.     void (*child_cleanup) (void *);
  1609.     struct cleanup *next;
  1610. };
  1611.  
  1612. API_EXPORT(void) ap_register_cleanup(pool *p, void *data, void (*plain_cleanup) (void *),
  1613.                   void (*child_cleanup) (void *))
  1614. {
  1615.     struct cleanup *c = (struct cleanup *) ap_palloc(p, sizeof(struct cleanup));
  1616.     c->data = data;
  1617.     c->plain_cleanup = plain_cleanup;
  1618.     c->child_cleanup = child_cleanup;
  1619.     c->next = p->cleanups;
  1620.     p->cleanups = c;
  1621. }
  1622.  
  1623. API_EXPORT(void) ap_kill_cleanup(pool *p, void *data, void (*cleanup) (void *))
  1624. {
  1625.     struct cleanup *c = p->cleanups;
  1626.     struct cleanup **lastp = &p->cleanups;
  1627.  
  1628.     while (c) {
  1629.     if (c->data == data && c->plain_cleanup == cleanup) {
  1630.         *lastp = c->next;
  1631.         break;
  1632.     }
  1633.  
  1634.     lastp = &c->next;
  1635.     c = c->next;
  1636.     }
  1637. }
  1638.  
  1639. API_EXPORT(void) ap_run_cleanup(pool *p, void *data, void (*cleanup) (void *))
  1640. {
  1641.     ap_block_alarms();        /* Run cleanup only once! */
  1642.     (*cleanup) (data);
  1643.     ap_kill_cleanup(p, data, cleanup);
  1644.     ap_unblock_alarms();
  1645. }
  1646.  
  1647. static void run_cleanups(struct cleanup *c)
  1648. {
  1649.     while (c) {
  1650.     (*c->plain_cleanup) (c->data);
  1651.     c = c->next;
  1652.     }
  1653. }
  1654.  
  1655. static void run_child_cleanups(struct cleanup *c)
  1656. {
  1657.     while (c) {
  1658.     (*c->child_cleanup) (c->data);
  1659.     c = c->next;
  1660.     }
  1661. }
  1662.  
  1663. static void cleanup_pool_for_exec(pool *p)
  1664. {
  1665.     run_child_cleanups(p->cleanups);
  1666.     p->cleanups = NULL;
  1667.  
  1668.     for (p = p->sub_pools; p; p = p->sub_next)
  1669.     cleanup_pool_for_exec(p);
  1670. }
  1671.  
  1672. API_EXPORT(void) ap_cleanup_for_exec(void)
  1673. {
  1674. #ifndef WIN32
  1675.     /*
  1676.      * Don't need to do anything on NT, because I
  1677.      * am actually going to spawn the new process - not
  1678.      * exec it. All handles that are not inheritable, will
  1679.      * be automajically closed. The only problem is with
  1680.      * file handles that are open, but there isn't much
  1681.      * I can do about that (except if the child decides
  1682.      * to go out and close them
  1683.      */
  1684.     ap_block_alarms();
  1685.     cleanup_pool_for_exec(permanent_pool);
  1686.     ap_unblock_alarms();
  1687. #endif /* ndef WIN32 */
  1688. }
  1689.  
  1690. API_EXPORT_NONSTD(void) ap_null_cleanup(void *data)
  1691. {
  1692.     /* do nothing cleanup routine */
  1693. }
  1694.  
  1695. /*****************************************************************
  1696.  *
  1697.  * Files and file descriptors; these are just an application of the
  1698.  * generic cleanup interface.
  1699.  */
  1700.  
  1701. static void fd_cleanup(void *fdv)
  1702. {
  1703.     close((int) (long) fdv);
  1704. }
  1705.  
  1706. API_EXPORT(void) ap_note_cleanups_for_fd(pool *p, int fd)
  1707. {
  1708.     ap_register_cleanup(p, (void *) (long) fd, fd_cleanup, fd_cleanup);
  1709. }
  1710.  
  1711. API_EXPORT(void) ap_kill_cleanups_for_fd(pool *p, int fd)
  1712. {
  1713.     ap_kill_cleanup(p, (void *) (long) fd, fd_cleanup);
  1714. }
  1715.  
  1716. API_EXPORT(int) ap_popenf(pool *a, const char *name, int flg, int mode)
  1717. {
  1718.     int fd;
  1719.     int save_errno;
  1720.  
  1721.     ap_block_alarms();
  1722.     fd = open(name, flg, mode);
  1723.     save_errno = errno;
  1724.     if (fd >= 0) {
  1725.     fd = ap_slack(fd, AP_SLACK_HIGH);
  1726.     ap_note_cleanups_for_fd(a, fd);
  1727.     }
  1728.     ap_unblock_alarms();
  1729.     errno = save_errno;
  1730.     return fd;
  1731. }
  1732.  
  1733. API_EXPORT(int) ap_pclosef(pool *a, int fd)
  1734. {
  1735.     int res;
  1736.     int save_errno;
  1737.  
  1738.     ap_block_alarms();
  1739.     res = close(fd);
  1740.     save_errno = errno;
  1741.     ap_kill_cleanup(a, (void *) (long) fd, fd_cleanup);
  1742.     ap_unblock_alarms();
  1743.     errno = save_errno;
  1744.     return res;
  1745. }
  1746.  
  1747. #ifdef WIN32
  1748. static void h_cleanup(void *fdv)
  1749. {
  1750.     CloseHandle((HANDLE) fdv);
  1751. }
  1752.  
  1753. API_EXPORT(void) ap_note_cleanups_for_h(pool *p, HANDLE hDevice)
  1754. {
  1755.     ap_register_cleanup(p, (void *) hDevice, h_cleanup, h_cleanup);
  1756. }
  1757.  
  1758. API_EXPORT(int) ap_pcloseh(pool *a, HANDLE hDevice)
  1759. {
  1760.     int res=0;
  1761.     int save_errno;
  1762.  
  1763.     ap_block_alarms();
  1764.     
  1765.     if (!CloseHandle(hDevice)) {
  1766.         res = GetLastError();
  1767.     }
  1768.     
  1769.     save_errno = errno;
  1770.     ap_kill_cleanup(a, (void *) hDevice, h_cleanup);
  1771.     ap_unblock_alarms();
  1772.     errno = save_errno;
  1773.     return res;
  1774. }
  1775. #endif
  1776.  
  1777. /* Note that we have separate plain_ and child_ cleanups for FILE *s,
  1778.  * since fclose() would flush I/O buffers, which is extremely undesirable;
  1779.  * we just close the descriptor.
  1780.  */
  1781.  
  1782. static void file_cleanup(void *fpv)
  1783. {
  1784.     fclose((FILE *) fpv);
  1785. }
  1786. static void file_child_cleanup(void *fpv)
  1787. {
  1788.     close(fileno((FILE *) fpv));
  1789. }
  1790.  
  1791. API_EXPORT(void) ap_note_cleanups_for_file(pool *p, FILE *fp)
  1792. {
  1793.     ap_register_cleanup(p, (void *) fp, file_cleanup, file_child_cleanup);
  1794. }
  1795.  
  1796. API_EXPORT(FILE *) ap_pfopen(pool *a, const char *name, const char *mode)
  1797. {
  1798.     FILE *fd = NULL;
  1799.     int baseFlag, desc;
  1800.     int modeFlags = 0;
  1801.     int saved_errno;
  1802.  
  1803. #ifdef WIN32
  1804.     modeFlags = _S_IREAD | _S_IWRITE;
  1805. #else
  1806.     modeFlags = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
  1807. #endif
  1808.  
  1809.     ap_block_alarms();
  1810.  
  1811.     if (*mode == 'a') {
  1812.     /* Work around faulty implementations of fopen */
  1813.     baseFlag = (*(mode + 1) == '+') ? O_RDWR : O_WRONLY;
  1814.     desc = open(name, baseFlag | O_APPEND | O_CREAT,
  1815.             modeFlags);
  1816.     if (desc >= 0) {
  1817.         desc = ap_slack(desc, AP_SLACK_LOW);
  1818.         fd = ap_fdopen(desc, mode);
  1819.     }
  1820.     }
  1821.     else {
  1822.     fd = fopen(name, mode);
  1823.     }
  1824.     saved_errno = errno;
  1825.     if (fd != NULL)
  1826.     ap_note_cleanups_for_file(a, fd);
  1827.     ap_unblock_alarms();
  1828.     errno = saved_errno;
  1829.     return fd;
  1830. }
  1831.  
  1832. API_EXPORT(FILE *) ap_pfdopen(pool *a, int fd, const char *mode)
  1833. {
  1834.     FILE *f;
  1835.     int saved_errno;
  1836.  
  1837.     ap_block_alarms();
  1838.     f = ap_fdopen(fd, mode);
  1839.     saved_errno = errno;
  1840.     if (f != NULL)
  1841.     ap_note_cleanups_for_file(a, f);
  1842.     ap_unblock_alarms();
  1843.     errno = saved_errno;
  1844.     return f;
  1845. }
  1846.  
  1847.  
  1848. API_EXPORT(int) ap_pfclose(pool *a, FILE *fd)
  1849. {
  1850.     int res;
  1851.  
  1852.     ap_block_alarms();
  1853.     res = fclose(fd);
  1854.     ap_kill_cleanup(a, (void *) fd, file_cleanup);
  1855.     ap_unblock_alarms();
  1856.     return res;
  1857. }
  1858.  
  1859. /*
  1860.  * DIR * with cleanup
  1861.  */
  1862.  
  1863. static void dir_cleanup(void *dv)
  1864. {
  1865.     closedir((DIR *) dv);
  1866. }
  1867.  
  1868. API_EXPORT(DIR *) ap_popendir(pool *p, const char *name)
  1869. {
  1870.     DIR *d;
  1871.     int save_errno;
  1872.  
  1873.     ap_block_alarms();
  1874.     d = opendir(name);
  1875.     if (d == NULL) {
  1876.     save_errno = errno;
  1877.     ap_unblock_alarms();
  1878.     errno = save_errno;
  1879.     return NULL;
  1880.     }
  1881.     ap_register_cleanup(p, (void *) d, dir_cleanup, dir_cleanup);
  1882.     ap_unblock_alarms();
  1883.     return d;
  1884. }
  1885.  
  1886. API_EXPORT(void) ap_pclosedir(pool *p, DIR * d)
  1887. {
  1888.     ap_block_alarms();
  1889.     ap_kill_cleanup(p, (void *) d, dir_cleanup);
  1890.     closedir(d);
  1891.     ap_unblock_alarms();
  1892. }
  1893.  
  1894. /*****************************************************************
  1895.  *
  1896.  * Files and file descriptors; these are just an application of the
  1897.  * generic cleanup interface.
  1898.  */
  1899.  
  1900. static void socket_cleanup(void *fdv)
  1901. {
  1902.     closesocket((int) (long) fdv);
  1903. }
  1904.  
  1905. API_EXPORT(void) ap_note_cleanups_for_socket(pool *p, int fd)
  1906. {
  1907.     ap_register_cleanup(p, (void *) (long) fd, socket_cleanup, socket_cleanup);
  1908. }
  1909.  
  1910. API_EXPORT(void) ap_kill_cleanups_for_socket(pool *p, int sock)
  1911. {
  1912.     ap_kill_cleanup(p, (void *) (long) sock, socket_cleanup);
  1913. }
  1914.  
  1915. API_EXPORT(int) ap_psocket(pool *p, int domain, int type, int protocol)
  1916. {
  1917.     int fd;
  1918.  
  1919.     ap_block_alarms();
  1920.     fd = socket(domain, type, protocol);
  1921.     if (fd == -1) {
  1922.     int save_errno = errno;
  1923.     ap_unblock_alarms();
  1924.     errno = save_errno;
  1925.     return -1;
  1926.     }
  1927.     ap_note_cleanups_for_socket(p, fd);
  1928.     ap_unblock_alarms();
  1929.     return fd;
  1930. }
  1931.  
  1932. API_EXPORT(int) ap_pclosesocket(pool *a, int sock)
  1933. {
  1934.     int res;
  1935.     int save_errno;
  1936.  
  1937.     ap_block_alarms();
  1938.     res = closesocket(sock);
  1939. #ifdef WIN32
  1940.     errno = WSAGetLastError();
  1941. #endif /* WIN32 */
  1942.     save_errno = errno;
  1943.     ap_kill_cleanup(a, (void *) (long) sock, socket_cleanup);
  1944.     ap_unblock_alarms();
  1945.     errno = save_errno;
  1946.     return res;
  1947. }
  1948.  
  1949.  
  1950. /*
  1951.  * Here's a pool-based interface to POSIX regex's regcomp().
  1952.  * Note that we return regex_t instead of being passed one.
  1953.  * The reason is that if you use an already-used regex_t structure,
  1954.  * the memory that you've already allocated gets forgotten, and
  1955.  * regfree() doesn't clear it. So we don't allow it.
  1956.  */
  1957.  
  1958. static void regex_cleanup(void *preg)
  1959. {
  1960.     regfree((regex_t *) preg);
  1961. }
  1962.  
  1963. API_EXPORT(regex_t *) ap_pregcomp(pool *p, const char *pattern, int cflags)
  1964. {
  1965.     regex_t *preg = ap_palloc(p, sizeof(regex_t));
  1966.  
  1967.     if (regcomp(preg, pattern, cflags))
  1968.     return NULL;
  1969.  
  1970.     ap_register_cleanup(p, (void *) preg, regex_cleanup, regex_cleanup);
  1971.  
  1972.     return preg;
  1973. }
  1974.  
  1975.  
  1976. API_EXPORT(void) ap_pregfree(pool *p, regex_t * reg)
  1977. {
  1978.     ap_block_alarms();
  1979.     regfree(reg);
  1980.     ap_kill_cleanup(p, (void *) reg, regex_cleanup);
  1981.     ap_unblock_alarms();
  1982. }
  1983.  
  1984. /*****************************************************************
  1985.  *
  1986.  * More grotty system stuff... subprocesses.  Frump.  These don't use
  1987.  * the generic cleanup interface because I don't want multiple
  1988.  * subprocesses to result in multiple three-second pauses; the
  1989.  * subprocesses have to be "freed" all at once.  If someone comes
  1990.  * along with another resource they want to allocate which has the
  1991.  * same property, we might want to fold support for that into the
  1992.  * generic interface, but for now, it's a special case
  1993.  */
  1994.  
  1995. struct process_chain {
  1996.     pid_t pid;
  1997.     enum kill_conditions kill_how;
  1998.     struct process_chain *next;
  1999. };
  2000.  
  2001. API_EXPORT(void) ap_note_subprocess(pool *a, pid_t pid, enum kill_conditions 
  2002. how) {
  2003.     struct process_chain *new =
  2004.     (struct process_chain *) ap_palloc(a, sizeof(struct process_chain));
  2005.  
  2006.     new->pid = pid;
  2007.     new->kill_how = how;
  2008.     new->next = a->subprocesses;
  2009.     a->subprocesses = new;
  2010. }
  2011.  
  2012. #ifdef WIN32
  2013. #define os_pipe(fds) _pipe(fds, 512, O_BINARY | O_NOINHERIT)
  2014. #else
  2015. #define os_pipe(fds) pipe(fds)
  2016. #endif /* WIN32 */
  2017.  
  2018. /* for ap_fdopen, to get binary mode */
  2019. #if defined (OS2) || defined (WIN32)
  2020. #define BINMODE    "b"
  2021. #else
  2022. #define BINMODE
  2023. #endif
  2024.  
  2025. static pid_t spawn_child_core(pool *p, int (*func) (void *, child_info *),
  2026.                 void *data,enum kill_conditions kill_how,
  2027.                 int *pipe_in, int *pipe_out, int *pipe_err)
  2028. {
  2029.     pid_t pid;
  2030.     int in_fds[2];
  2031.     int out_fds[2];
  2032.     int err_fds[2];
  2033.     int save_errno;
  2034.  
  2035.     if (pipe_in && os_pipe(in_fds) < 0) {
  2036.     return 0;
  2037.     }
  2038.  
  2039.     if (pipe_out && os_pipe(out_fds) < 0) {
  2040.     save_errno = errno;
  2041.     if (pipe_in) {
  2042.         close(in_fds[0]);
  2043.         close(in_fds[1]);
  2044.     }
  2045.     errno = save_errno;
  2046.     return 0;
  2047.     }
  2048.  
  2049.     if (pipe_err && os_pipe(err_fds) < 0) {
  2050.     save_errno = errno;
  2051.     if (pipe_in) {
  2052.         close(in_fds[0]);
  2053.         close(in_fds[1]);
  2054.     }
  2055.     if (pipe_out) {
  2056.         close(out_fds[0]);
  2057.         close(out_fds[1]);
  2058.     }
  2059.     errno = save_errno;
  2060.     return 0;
  2061.     }
  2062.  
  2063. #ifdef WIN32
  2064.  
  2065.     {
  2066.     HANDLE thread_handle;
  2067.     int hStdIn, hStdOut, hStdErr;
  2068.     int old_priority;
  2069.     child_info info;
  2070.  
  2071.     (void) ap_acquire_mutex(spawn_mutex);
  2072.     thread_handle = GetCurrentThread();    /* doesn't need to be closed */
  2073.     old_priority = GetThreadPriority(thread_handle);
  2074.     SetThreadPriority(thread_handle, THREAD_PRIORITY_HIGHEST);
  2075.     /* Now do the right thing with your pipes */
  2076.     if (pipe_in) {
  2077.         hStdIn = dup(fileno(stdin));
  2078.         if(dup2(in_fds[0], fileno(stdin)))
  2079.         ap_log_error(APLOG_MARK, APLOG_ERR, NULL, "dup2(stdin) failed");
  2080.         close(in_fds[0]);
  2081.     }
  2082.     if (pipe_out) {
  2083.         hStdOut = dup(fileno(stdout));
  2084.         close(fileno(stdout));
  2085.         if(dup2(out_fds[1], fileno(stdout)))
  2086.         ap_log_error(APLOG_MARK, APLOG_ERR, NULL, "dup2(stdout) failed");
  2087.         close(out_fds[1]);
  2088.     }
  2089.     if (pipe_err) {
  2090.         hStdErr = dup(fileno(stderr));
  2091.         if(dup2(err_fds[1], fileno(stderr)))
  2092.         ap_log_error(APLOG_MARK, APLOG_ERR, NULL, "dup2(stdin) failed");
  2093.         close(err_fds[1]);
  2094.     }
  2095.  
  2096.     info.hPipeInputRead   = GetStdHandle(STD_INPUT_HANDLE);
  2097.     info.hPipeOutputWrite = GetStdHandle(STD_OUTPUT_HANDLE);
  2098.     info.hPipeErrorWrite  = GetStdHandle(STD_ERROR_HANDLE);
  2099.  
  2100.     pid = (*func) (data, &info);
  2101.         if (pid == -1) pid = 0;   /* map Win32 error code onto Unix default */
  2102.  
  2103.         if (!pid) {
  2104.         save_errno = errno;
  2105.         close(in_fds[1]);
  2106.         close(out_fds[0]);
  2107.         close(err_fds[0]);
  2108.     }
  2109.  
  2110.     /* restore the original stdin, stdout and stderr */
  2111.     if (pipe_in) {
  2112.         dup2(hStdIn, fileno(stdin));
  2113.         close(hStdIn);
  2114.         }
  2115.     if (pipe_out) {
  2116.         dup2(hStdOut, fileno(stdout));
  2117.         close(hStdOut);
  2118.     }
  2119.     if (pipe_err) {
  2120.         dup2(hStdErr, fileno(stderr));
  2121.         close(hStdErr);
  2122.     }
  2123.  
  2124.         if (pid) {
  2125.         ap_note_subprocess(p, pid, kill_how);
  2126.         if (pipe_in) {
  2127.         *pipe_in = in_fds[1];
  2128.         }
  2129.         if (pipe_out) {
  2130.         *pipe_out = out_fds[0];
  2131.         }
  2132.         if (pipe_err) {
  2133.         *pipe_err = err_fds[0];
  2134.         }
  2135.     }
  2136.     SetThreadPriority(thread_handle, old_priority);
  2137.     (void) ap_release_mutex(spawn_mutex);
  2138.     /*
  2139.      * go on to the end of the function, where you can
  2140.      * unblock alarms and return the pid
  2141.      */
  2142.  
  2143.     }
  2144. #else
  2145.  
  2146.     if ((pid = fork()) < 0) {
  2147.     save_errno = errno;
  2148.     if (pipe_in) {
  2149.         close(in_fds[0]);
  2150.         close(in_fds[1]);
  2151.     }
  2152.     if (pipe_out) {
  2153.         close(out_fds[0]);
  2154.         close(out_fds[1]);
  2155.     }
  2156.     if (pipe_err) {
  2157.         close(err_fds[0]);
  2158.         close(err_fds[1]);
  2159.     }
  2160.     errno = save_errno;
  2161.     return 0;
  2162.     }
  2163.  
  2164.     if (!pid) {
  2165.     /* Child process */
  2166.     RAISE_SIGSTOP(SPAWN_CHILD);
  2167.  
  2168.     if (pipe_out) {
  2169.         close(out_fds[0]);
  2170.         dup2(out_fds[1], STDOUT_FILENO);
  2171.         close(out_fds[1]);
  2172.     }
  2173.  
  2174.     if (pipe_in) {
  2175.         close(in_fds[1]);
  2176.         dup2(in_fds[0], STDIN_FILENO);
  2177.         close(in_fds[0]);
  2178.     }
  2179.  
  2180.     if (pipe_err) {
  2181.         close(err_fds[0]);
  2182.         dup2(err_fds[1], STDERR_FILENO);
  2183.         close(err_fds[1]);
  2184.     }
  2185.  
  2186.     /* HP-UX SIGCHLD fix goes here, if someone will remind me what it is... */
  2187.     signal(SIGCHLD, SIG_DFL);    /* Was that it? */
  2188.  
  2189.     func(data, NULL);
  2190.     exit(1);        /* Should only get here if the exec in func() failed */
  2191.     }
  2192.  
  2193.     /* Parent process */
  2194.  
  2195.     ap_note_subprocess(p, pid, kill_how);
  2196.  
  2197.     if (pipe_out) {
  2198.     close(out_fds[1]);
  2199.     *pipe_out = out_fds[0];
  2200.     }
  2201.  
  2202.     if (pipe_in) {
  2203.     close(in_fds[0]);
  2204.     *pipe_in = in_fds[1];
  2205.     }
  2206.  
  2207.     if (pipe_err) {
  2208.     close(err_fds[1]);
  2209.     *pipe_err = err_fds[0];
  2210.     }
  2211. #endif /* WIN32 */
  2212.  
  2213.     return pid;
  2214. }
  2215.  
  2216.  
  2217. API_EXPORT(int) ap_spawn_child(pool *p, int (*func) (void *, child_info *),
  2218.                    void *data, enum kill_conditions kill_how,
  2219.                    FILE **pipe_in, FILE **pipe_out,
  2220.                    FILE **pipe_err)
  2221. {
  2222.     int fd_in, fd_out, fd_err;
  2223.     pid_t pid;
  2224.     int save_errno;
  2225.  
  2226.     ap_block_alarms();
  2227.  
  2228.     pid = spawn_child_core(p, func, data, kill_how,
  2229.                pipe_in ? &fd_in : NULL,
  2230.                pipe_out ? &fd_out : NULL,
  2231.                pipe_err ? &fd_err : NULL);
  2232.  
  2233.     if (pid == 0) {
  2234.     save_errno = errno;
  2235.     ap_unblock_alarms();
  2236.     errno = save_errno;
  2237.     return 0;
  2238.     }
  2239.  
  2240.     if (pipe_out) {
  2241.     *pipe_out = ap_fdopen(fd_out, "r" BINMODE);
  2242.     if (*pipe_out)
  2243.         ap_note_cleanups_for_file(p, *pipe_out);
  2244.     else
  2245.         close(fd_out);
  2246.     }
  2247.  
  2248.     if (pipe_in) {
  2249.     *pipe_in = ap_fdopen(fd_in, "w" BINMODE);
  2250.     if (*pipe_in)
  2251.         ap_note_cleanups_for_file(p, *pipe_in);
  2252.     else
  2253.         close(fd_in);
  2254.     }
  2255.  
  2256.     if (pipe_err) {
  2257.     *pipe_err = ap_fdopen(fd_err, "r" BINMODE);
  2258.     if (*pipe_err)
  2259.         ap_note_cleanups_for_file(p, *pipe_err);
  2260.     else
  2261.         close(fd_err);
  2262.     }
  2263.  
  2264.     ap_unblock_alarms();
  2265.     return pid;
  2266. }
  2267.  
  2268. API_EXPORT(int) ap_bspawn_child(pool *p, int (*func) (void *, child_info *), void *data,
  2269.                 enum kill_conditions kill_how,
  2270.                 BUFF **pipe_in, BUFF **pipe_out, BUFF **pipe_err)
  2271. {
  2272. #ifdef WIN32
  2273.     SECURITY_ATTRIBUTES sa = {0};  
  2274.     HANDLE hPipeOutputRead  = NULL;
  2275.     HANDLE hPipeOutputWrite = NULL;
  2276.     HANDLE hPipeInputRead   = NULL;
  2277.     HANDLE hPipeInputWrite  = NULL;
  2278.     HANDLE hPipeErrorRead   = NULL;
  2279.     HANDLE hPipeErrorWrite  = NULL;
  2280.     HANDLE hPipeInputWriteDup = NULL;
  2281.     HANDLE hPipeOutputReadDup = NULL;
  2282.     HANDLE hPipeErrorReadDup  = NULL;
  2283.     HANDLE hCurrentProcess;
  2284.     pid_t pid = 0;
  2285.     child_info info;
  2286.  
  2287.  
  2288.     ap_block_alarms();
  2289.  
  2290.     /*
  2291.      *  First thing to do is to create the pipes that we will use for stdin, stdout, and
  2292.      *  stderr in the child process.
  2293.      */      
  2294.     sa.nLength = sizeof(sa);
  2295.     sa.bInheritHandle = TRUE;
  2296.     sa.lpSecurityDescriptor = NULL;
  2297.  
  2298.  
  2299.     /* Create pipes for standard input/output/error redirection. */
  2300.     if (pipe_in && !CreatePipe(&hPipeInputRead, &hPipeInputWrite, &sa, 0))
  2301.     return 0;
  2302.  
  2303.     if (pipe_out && !CreatePipe(&hPipeOutputRead, &hPipeOutputWrite, &sa, 0)) {
  2304.     if(pipe_in) {
  2305.         CloseHandle(hPipeInputRead);
  2306.         CloseHandle(hPipeInputWrite);
  2307.     }
  2308.     return 0;
  2309.     }
  2310.  
  2311.     if (pipe_err && !CreatePipe(&hPipeErrorRead, &hPipeErrorWrite, &sa, 0)) {
  2312.     if(pipe_in) {
  2313.         CloseHandle(hPipeInputRead);
  2314.         CloseHandle(hPipeInputWrite);
  2315.     }
  2316.     if(pipe_out) {
  2317.         CloseHandle(hPipeOutputRead);
  2318.         CloseHandle(hPipeOutputWrite);
  2319.     }
  2320.     return 0;
  2321.     }
  2322.     /*
  2323.      * When the pipe handles are created, the security descriptor
  2324.      * indicates that the handle can be inherited.  However, we do not
  2325.      * want the server side handles to the pipe to be inherited by the
  2326.      * child CGI process. If the child CGI does inherit the server
  2327.      * side handles, then the child may be left around if the server
  2328.      * closes its handles (e.g. if the http connection is aborted),
  2329.      * because the child will have a valid copy of handles to both
  2330.      * sides of the pipes, and no I/O error will occur.  Microsoft
  2331.      * recommends using DuplicateHandle to turn off the inherit bit
  2332.      * under NT and Win95.
  2333.      */
  2334.     hCurrentProcess = GetCurrentProcess();
  2335.     if ((pipe_in && !DuplicateHandle(hCurrentProcess, hPipeInputWrite,
  2336.                      hCurrentProcess,
  2337.                      &hPipeInputWriteDup, 0, FALSE,
  2338.                      DUPLICATE_SAME_ACCESS))
  2339.     || (pipe_out && !DuplicateHandle(hCurrentProcess, hPipeOutputRead,
  2340.                      hCurrentProcess, &hPipeOutputReadDup,
  2341.                      0, FALSE, DUPLICATE_SAME_ACCESS))
  2342.     || (pipe_err && !DuplicateHandle(hCurrentProcess, hPipeErrorRead,
  2343.                      hCurrentProcess, &hPipeErrorReadDup,
  2344.                      0, FALSE, DUPLICATE_SAME_ACCESS))) {
  2345.     if (pipe_in) {
  2346.         CloseHandle(hPipeInputRead);
  2347.         CloseHandle(hPipeInputWrite);
  2348.     }
  2349.     if (pipe_out) {
  2350.         CloseHandle(hPipeOutputRead);
  2351.         CloseHandle(hPipeOutputWrite);
  2352.     }
  2353.     if (pipe_err) {
  2354.         CloseHandle(hPipeErrorRead);
  2355.         CloseHandle(hPipeErrorWrite);
  2356.     }
  2357.     return 0;
  2358.     }
  2359.     else {
  2360.     if (pipe_in) {
  2361.         CloseHandle(hPipeInputWrite);
  2362.         hPipeInputWrite = hPipeInputWriteDup;
  2363.     }
  2364.     if (pipe_out) {
  2365.         CloseHandle(hPipeOutputRead);
  2366.         hPipeOutputRead = hPipeOutputReadDup;
  2367.     }
  2368.     if (pipe_err) {
  2369.         CloseHandle(hPipeErrorRead);
  2370.         hPipeErrorRead = hPipeErrorReadDup;
  2371.     }
  2372.     }
  2373.  
  2374.     /* The script writes stdout to this pipe handle */
  2375.     info.hPipeOutputWrite = hPipeOutputWrite;  
  2376.  
  2377.     /* The script reads stdin from this pipe handle */
  2378.     info.hPipeInputRead = hPipeInputRead;
  2379.  
  2380.     /* The script writes stderr to this pipe handle */
  2381.     info.hPipeErrorWrite = hPipeErrorWrite;    
  2382.      
  2383.     /*
  2384.      *  Try to launch the CGI.  Under the covers, this call 
  2385.      *  will try to pick up the appropriate interpreter if 
  2386.      *  one is needed.
  2387.      */
  2388.     pid = func(data, &info);
  2389.     if (pid == -1) {
  2390.         /* Things didn't work, so cleanup */
  2391.         pid = 0;   /* map Win32 error code onto Unix default */
  2392.         CloseHandle(hPipeOutputRead);
  2393.         CloseHandle(hPipeInputWrite);
  2394.         CloseHandle(hPipeErrorRead);
  2395.     }
  2396.     else {
  2397.         if (pipe_out) {
  2398.             /*
  2399.              *  This pipe represents stdout for the script, 
  2400.              *  so we read from this pipe.
  2401.              */
  2402.         /* Create a read buffer */
  2403.             *pipe_out = ap_bcreate(p, B_RD);
  2404.  
  2405.         /* Setup the cleanup routine for the handle */
  2406.             ap_note_cleanups_for_h(p, hPipeOutputRead);   
  2407.  
  2408.         /* Associate the handle with the new buffer */
  2409.             ap_bpushh(*pipe_out, hPipeOutputRead);
  2410.         }
  2411.         
  2412.         if (pipe_in) {
  2413.             /*
  2414.              *  This pipe represents stdin for the script, so we 
  2415.              *  write to this pipe.
  2416.              */
  2417.         /* Create a write buffer */
  2418.             *pipe_in = ap_bcreate(p, B_WR);             
  2419.  
  2420.         /* Setup the cleanup routine for the handle */
  2421.             ap_note_cleanups_for_h(p, hPipeInputWrite);
  2422.  
  2423.         /* Associate the handle with the new buffer */
  2424.             ap_bpushh(*pipe_in, hPipeInputWrite);
  2425.  
  2426.         }
  2427.       
  2428.         if (pipe_err) {
  2429.             /*
  2430.              *  This pipe represents stderr for the script, so 
  2431.              *  we read from this pipe.
  2432.              */
  2433.         /* Create a read buffer */
  2434.             *pipe_err = ap_bcreate(p, B_RD);
  2435.  
  2436.         /* Setup the cleanup routine for the handle */
  2437.             ap_note_cleanups_for_h(p, hPipeErrorRead);
  2438.  
  2439.         /* Associate the handle with the new buffer */
  2440.             ap_bpushh(*pipe_err, hPipeErrorRead);
  2441.         }
  2442.     }  
  2443.  
  2444.  
  2445.     /*
  2446.      * Now that handles have been inherited, close them to be safe.
  2447.      * You don't want to read or write to them accidentally, and we
  2448.      * sure don't want to have a handle leak.
  2449.      */
  2450.     CloseHandle(hPipeOutputWrite);
  2451.     CloseHandle(hPipeInputRead);
  2452.     CloseHandle(hPipeErrorWrite);
  2453.  
  2454. #else
  2455.     int fd_in, fd_out, fd_err;
  2456.     pid_t pid;
  2457.     int save_errno;
  2458.  
  2459.     ap_block_alarms();
  2460.  
  2461.     pid = spawn_child_core(p, func, data, kill_how,
  2462.                pipe_in ? &fd_in : NULL,
  2463.                pipe_out ? &fd_out : NULL,
  2464.                pipe_err ? &fd_err : NULL);
  2465.  
  2466.     if (pid == 0) {
  2467.     save_errno = errno;
  2468.     ap_unblock_alarms();
  2469.     errno = save_errno;
  2470.     return 0;
  2471.     }
  2472.  
  2473.     if (pipe_out) {
  2474.     *pipe_out = ap_bcreate(p, B_RD);
  2475.     ap_note_cleanups_for_fd(p, fd_out);
  2476.     ap_bpushfd(*pipe_out, fd_out, fd_out);
  2477.     }
  2478.  
  2479.     if (pipe_in) {
  2480.     *pipe_in = ap_bcreate(p, B_WR);
  2481.     ap_note_cleanups_for_fd(p, fd_in);
  2482.     ap_bpushfd(*pipe_in, fd_in, fd_in);
  2483.     }
  2484.  
  2485.     if (pipe_err) {
  2486.     *pipe_err = ap_bcreate(p, B_RD);
  2487.     ap_note_cleanups_for_fd(p, fd_err);
  2488.     ap_bpushfd(*pipe_err, fd_err, fd_err);
  2489.     }
  2490. #endif
  2491.  
  2492.     ap_unblock_alarms();
  2493.     return pid;
  2494. }
  2495.  
  2496. static void free_proc_chain(struct process_chain *procs)
  2497. {
  2498.     /* Dispose of the subprocesses we've spawned off in the course of
  2499.      * whatever it was we're cleaning up now.  This may involve killing
  2500.      * some of them off...
  2501.      */
  2502.  
  2503.     struct process_chain *p;
  2504.     int need_timeout = 0;
  2505.     int status;
  2506.  
  2507.     if (procs == NULL)
  2508.     return;            /* No work.  Whew! */
  2509.  
  2510.     /* First, check to see if we need to do the SIGTERM, sleep, SIGKILL
  2511.      * dance with any of the processes we're cleaning up.  If we've got
  2512.      * any kill-on-sight subprocesses, ditch them now as well, so they
  2513.      * don't waste any more cycles doing whatever it is that they shouldn't
  2514.      * be doing anymore.
  2515.      */
  2516. #ifdef WIN32
  2517.     /* Pick up all defunct processes */
  2518.     for (p = procs; p; p = p->next) {
  2519.     if (GetExitCodeProcess((HANDLE) p->pid, &status)) {
  2520.         p->kill_how = kill_never;
  2521.     }
  2522.     }
  2523.  
  2524.  
  2525.     for (p = procs; p; p = p->next) {
  2526.     if (p->kill_how == kill_after_timeout) {
  2527.         need_timeout = 1;
  2528.     }
  2529.     else if (p->kill_how == kill_always) {
  2530.         TerminateProcess((HANDLE) p->pid, 1);
  2531.     }
  2532.     }
  2533.     /* Sleep only if we have to... */
  2534.  
  2535.     if (need_timeout)
  2536.     sleep(3);
  2537.  
  2538.     /* OK, the scripts we just timed out for have had a chance to clean up
  2539.      * --- now, just get rid of them, and also clean up the system accounting
  2540.      * goop...
  2541.      */
  2542.  
  2543.     for (p = procs; p; p = p->next) {
  2544.     if (p->kill_how == kill_after_timeout)
  2545.         TerminateProcess((HANDLE) p->pid, 1);
  2546.     }
  2547.  
  2548.     for (p = procs; p; p = p->next) {
  2549.     CloseHandle((HANDLE) p->pid);
  2550.     }
  2551. #else
  2552. #ifndef NEED_WAITPID
  2553.     /* Pick up all defunct processes */
  2554.     for (p = procs; p; p = p->next) {
  2555.     if (waitpid(p->pid, (int *) 0, WNOHANG) > 0) {
  2556.         p->kill_how = kill_never;
  2557.     }
  2558.     }
  2559. #endif
  2560.  
  2561.     for (p = procs; p; p = p->next) {
  2562.     if ((p->kill_how == kill_after_timeout)
  2563.         || (p->kill_how == kill_only_once)) {
  2564.         /* Subprocess may be dead already.  Only need the timeout if not. */
  2565.         if (kill(p->pid, SIGTERM) != -1)
  2566.         need_timeout = 1;
  2567.     }
  2568.     else if (p->kill_how == kill_always) {
  2569.         kill(p->pid, SIGKILL);
  2570.     }
  2571.     }
  2572.  
  2573.     /* Sleep only if we have to... */
  2574.  
  2575.     if (need_timeout)
  2576.     sleep(3);
  2577.  
  2578.     /* OK, the scripts we just timed out for have had a chance to clean up
  2579.      * --- now, just get rid of them, and also clean up the system accounting
  2580.      * goop...
  2581.      */
  2582.  
  2583.     for (p = procs; p; p = p->next) {
  2584.  
  2585.     if (p->kill_how == kill_after_timeout)
  2586.         kill(p->pid, SIGKILL);
  2587.  
  2588.     if (p->kill_how != kill_never)
  2589.         waitpid(p->pid, &status, 0);
  2590.     }
  2591. #endif /* WIN32 */
  2592. }
  2593.