View Issue Details

IDProjectCategoryView StatusLast Update
0000638Apache 2.x Bugpublic2020-08-24 03:01
ReporterSteven Levine Assigned ToSteven Levine  
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
PlatformeCS/OS2OSeComstation or OS/2OS Version1.x 2.x or 4.5
Fixed in Version2.4.x 
Summary0000638: httpd mpm does not support MaxRequestsPerChild properly
DescriptionWhile thinking about http://mantis.smedley.id.au/view.php?id=637, it occurred to me that I had no clue why MaxRequestsPerChild was configured to 0. This is never the recommended value on any platform.

Now I know why. The result is

[Mon Dec 22 14:45:44 2014] [notice] Apache/2.2.29 (OS/2) PHP/5.4.36 configured -- resuming normal operations
[Mon Dec 22 14:45:44 2014] [info] Server built: Dec 17 2014 14:44:31
[Mon Dec 22 14:46:07 2014] [error] (OS 10038)Socket operation on non-socket: apr_socket_accept
[Mon Dec 22 14:46:07 2014] [error] (OS 10038)Socket operation on non-socket: apr_socket_accept
[Mon Dec 22 14:46:07 2014] [info] removed PID file D:/Internet/apache22/logs/httpd.pid (pid=13722)
[Mon Dec 22 14:46:07 2014] [info] pidSemaphoreOwner = 242352128, tidSemaphoreOwner = 13730, ulRequestCount = 0l
[Mon Dec 22 14:46:07 2014] [notice] caught SIGTERM, shutting down

FWIW, http://mantis.smedley.id.au/view.php?id=190 reported a MaxRequestsPerChild issues, but this defect seems to have been resolved even though the ticket is still open.

It appears to me that getting MaxRequestsPerChild to work properly will resolve a number of stability issues, so I plan to focus on this for a bit.






TagsNo tags attached.
Attached Files
apr_portable.h.diff (1,291 bytes)   
diff --git a/include/apr_portable.h b/include/apr_portable.h
index 45d53eb..4c3723f 100644
--- a/include/apr_portable.h
+++ b/include/apr_portable.h
@@ -383,7 +383,7 @@ APR_DECLARE(apr_status_t) apr_os_dir_put(apr_dir_t **dir,
  * Convert a socket from the os specific type to the apr type
  * @param sock The pool to use.
  * @param thesock The socket to convert to.
- * @param cont The socket we are converting to an apr type.
+ * @param cont The pool to use.
  * @remark If it is a true socket, it is best to call apr_os_sock_make()
  *         and provide APR with more information about the socket.
  */
@@ -391,6 +391,16 @@ APR_DECLARE(apr_status_t) apr_os_sock_put(apr_socket_t **sock,
                                           apr_os_sock_t *thesock, 
                                           apr_pool_t *cont);
 
+#if 1 // 2014-12-27 SHL
+/**
+ * Deregister socket cleanup function for socket.
+ * Ensures sockets not owned by process are not closed during pool cleanup.
+ * Supports use case where httpd mpm passes listen sockets to child process.
+ * @param sock The socket to have cleanup deregistered.
+ */
+APR_DECLARE(void) apr_sock_cleanup_kill(apr_socket_t *sock);
+#endif
+
 /**
  * Create a socket from an existing descriptor and local and remote
  * socket addresses.
apr_portable.h.diff (1,291 bytes)   
sockets.c.diff (561 bytes)   
diff --git a/network_io/os2/sockets.c b/network_io/os2/sockets.c
index 2142d1e..e2408e6 100644
--- a/network_io/os2/sockets.c
+++ b/network_io/os2/sockets.c
@@ -416,6 +416,14 @@ APR_DECLARE(apr_status_t) apr_os_sock_put(apr_socket_t **sock, apr_os_sock_t *th
     return APR_SUCCESS;
 }
 
+#if 1 // 2014-12-26 SHL
+APR_DECLARE(void) apr_sock_cleanup_kill(apr_socket_t *apr_sock)
+{
+    apr_pool_cleanup_kill(apr_sock->pool, (void *)(apr_sock),
+                          socket_cleanup);
+}
+#endif
+
 APR_POOL_IMPLEMENT_ACCESSOR(socket);
 
 #ifndef __KLIBC__
sockets.c.diff (561 bytes)   
apr-1.5.1.git-20150110-1002-shl.diff (4,811 bytes)   
Generated on slamain at 01-10-15 10:02:52
git diff -w 
diff --git a/file_io/os2/open.c b/file_io/os2/open.c
index fabc4ef..03be904 100644
--- a/file_io/os2/open.c
+++ b/file_io/os2/open.c
@@ -194,6 +194,11 @@ APR_DECLARE(apr_status_t) apr_file_close(apr_file_t *file)
     if (file && file->isopen) {
         /* XXX: flush here is not mutex protected */
         status = apr_file_flush(file);
+	/* 2014-11-18 SHL ensure client sees ERROR_BROKEN_PIPE */
+	if (file->pipe == 1) {
+	  DosCloseEventSem(file->pipeSem);
+	  DosDisconnectNPipe(file->filedes);
+	}
         rc = DosClose(file->filedes);
     
         if (rc == 0) {
diff --git a/file_io/os2/pipe.c b/file_io/os2/pipe.c
index 4cbc66c..6c24619 100644
--- a/file_io/os2/pipe.c
+++ b/file_io/os2/pipe.c
@@ -109,7 +109,7 @@ APR_DECLARE(apr_status_t) apr_file_pipe_create(apr_file_t **in, apr_file_t **out
     (*out)->isopen = TRUE;
     (*out)->buffered = FALSE;
     (*out)->flags = 0;
-    (*out)->pipe = 1;
+    (*out)->pipe = 2;			// 2014-11-17 SHL mark as client pipe
     (*out)->ungetchar = -1;
     (*out)->timeout = -1;
     (*out)->blocking = BLK_ON;
diff --git a/file_io/os2/readwrite.c b/file_io/os2/readwrite.c
index 5e77d5f..646f48a 100644
--- a/file_io/os2/readwrite.c
+++ b/file_io/os2/readwrite.c
@@ -33,7 +33,6 @@ APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size
         *len = 0;
         return APR_SUCCESS;
     }
-
 #if 1
     /* Handle the ungetchar if there is one */
     /* copied from win32/readwrite.c */
@@ -105,22 +104,29 @@ APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size
         /* Unbuffered i/o */
         apr_size_t nbytes;
 
+        // 2014-11-11 SHL reworked to support ERROR_MORE_DATA etc.
+	for (;;) {
+	    int post_count;
         if (thefile->pipe)
-            DosResetEventSem(thefile->pipeSem, &rc);
-
-        rc = DosRead(thefile->filedes, buf, *len, &nbytes);
-
-        if (rc == ERROR_NO_DATA && thefile->timeout != 0) {
-            int rcwait = DosWaitEventSem(thefile->pipeSem, thefile->timeout >= 0 ? thefile->timeout / 1000 : SEM_INDEFINITE_WAIT);
-
-            if (rcwait == 0) {
+		DosResetEventSem(thefile->pipeSem, &post_count);
                 rc = DosRead(thefile->filedes, buf, *len, &nbytes);
+	    if (!thefile->pipe)
+		break;			// Blocking i/o - we are done
+	    if (rc == ERROR_MORE_DATA) {
+		// Buffer is full - caller will read more eventually
+		rc = NO_ERROR;
+		break;
             }
-            else if (rcwait == ERROR_TIMEOUT) {
+	    if (thefile->timeout == 0)
+		break;
+	    if (rc != ERROR_NO_DATA)
+		break;
+	    rc = DosWaitEventSem(thefile->pipeSem, thefile->timeout >= 0 ? thefile->timeout / 1000 : SEM_INDEFINITE_WAIT);
+	    if (rc == ERROR_TIMEOUT) {
                 *len = 0;
                 return APR_TIMEUP;
             }
-        }
+	} // for
 
         if (rc) {
             *len = 0;
diff --git a/include/apr_portable.h b/include/apr_portable.h
index 45d53eb..cb3e01b 100644
--- a/include/apr_portable.h
+++ b/include/apr_portable.h
@@ -383,7 +383,7 @@ APR_DECLARE(apr_status_t) apr_os_dir_put(apr_dir_t **dir,
  * Convert a socket from the os specific type to the apr type
  * @param sock The pool to use.
  * @param thesock The socket to convert to.
- * @param cont The socket we are converting to an apr type.
+ * @param cont The pool to use.
  * @remark If it is a true socket, it is best to call apr_os_sock_make()
  *         and provide APR with more information about the socket.
  */
@@ -392,6 +392,15 @@ APR_DECLARE(apr_status_t) apr_os_sock_put(apr_socket_t **sock,
                                           apr_pool_t *cont);
 
 /**
+ * Deregister socket cleanup function for socket.
+ * Ensures sockets not owned by process are not closed during pool cleanup.
+ * Supports use case where httpd mpm passes listen sockets to child process.
+ * @param sock The socket to have cleanup deregistered.
+ * @added 2014-12-27 SHL
+ */
+APR_DECLARE(void) apr_sock_cleanup_kill(apr_socket_t *sock);
+
+/**
  * Create a socket from an existing descriptor and local and remote
  * socket addresses.
  * @param apr_sock The new socket that has been set up
diff --git a/network_io/os2/sockets.c b/network_io/os2/sockets.c
index 2142d1e..fefa42b 100644
--- a/network_io/os2/sockets.c
+++ b/network_io/os2/sockets.c
@@ -416,6 +416,17 @@ APR_DECLARE(apr_status_t) apr_os_sock_put(apr_socket_t **sock, apr_os_sock_t *th
     return APR_SUCCESS;
 }
 
+/**
+ * Kill cleanup function registered by apr_socket_create
+ * @added 2014-12-27 SHL
+ */
+
+APR_DECLARE(void) apr_sock_cleanup_kill(apr_socket_t *apr_sock)
+{
+    apr_pool_cleanup_kill(apr_sock->pool, (void *)(apr_sock),
+                          socket_cleanup);
+}
+
 APR_POOL_IMPLEMENT_ACCESSOR(socket);
 
 #ifndef __KLIBC__
httpd-2.2.29.git-20150110-1012-shl.diff (6,158 bytes)   
Generated on slamain at 01-10-15 10:12:35
git diff -w 
diff --git a/server/mpm/mpmt_os2/mpmt_os2.c b/server/mpm/mpmt_os2/mpmt_os2.c
index d9c4b95..731d145 100644
--- a/server/mpm/mpmt_os2/mpmt_os2.c
+++ b/server/mpm/mpmt_os2/mpmt_os2.c
@@ -128,8 +128,8 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
     restart_pending = 0;
     ULONG    CurMaxFH      = 0;          /* Current count of handles         */
     LONG     ReqCount      = 0;          /* Number to adjust file handles    */
-    PID   pidSemaphoreOwner;   /* will get PID of sem owner */
-    TID   tidSemaphoreOwner;   /* will get TID of sem owner */
+    PID   pidSemaphoreOwner = 0;         /* will get PID of sem owner */
+    TID   tidSemaphoreOwner = 0;         /* will get TID of sem owner */
     ULONG ulRequestCount;      /* will get the request count for the sem */
 
     // DosSetMaxFH(ap_thread_limit * 2);
@@ -153,6 +153,7 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
 
         ap_mpm_accept_mutex = parent_info->accept_mutex;
 
+#if 0 // 2014-12-25 SHL looks like dead code - parent ensures listeners exist - FIXME to be gone
         /* Set up a default listener if necessary */
         if (ap_listeners == NULL) {
             ap_listen_rec *lr = apr_pcalloc(s->process->pool, sizeof(ap_listen_rec));
@@ -162,11 +163,20 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
             apr_socket_create(&lr->sd, lr->bind_addr->family,
                               SOCK_STREAM, 0, s->process->pool);
         }
+#endif
+        // 2014-12-25 SHL Sync with parent sanity checks
+        if (ap_listeners == NULL) {
+            ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s,
+                         "no listening sockets available, shutting down");
+            return 1;
+        }
 
         for (lr = ap_listeners; lr; lr = lr->next) {
             apr_sockaddr_t *sa;
             apr_os_sock_put(&lr->sd, &parent_info->listeners[num_listeners].listen_fd, pconf);
             apr_socket_addr_get(&sa, APR_LOCAL, lr->sd);
+            // 2014-12-26 SHL Ensure socket_cleanup does not close listen socket owned by parent
+            apr_sock_cleanup_kill(lr->sd);
             num_listeners++;
         }
 
@@ -352,7 +362,8 @@ static char master_main()
 
         if (rc == 0) {
             /* A child has terminated, remove its scoreboard entry & terminate if necessary */
-            for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++);
+            for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++)
+                ;                       // Keep looking
 
             if (slot < HARD_SERVER_LIMIT) {
                 ap_scoreboard_image->parent[slot].pid = 0;
@@ -370,11 +381,10 @@ static char master_main()
             /* No child exited, lets sleep for a while.... */
             apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL);
         }
-    }
+    } // while
 
     /* Signal children to shut down, either gracefully or immediately */
     for (slot=0; slot<HARD_SERVER_LIMIT; slot++) {
-
     if (ap_scoreboard_image->parent[slot].pid!=0){
       kill(ap_scoreboard_image->parent[slot].pid, is_graceful ? SIGHUP : SIGTERM);
     }
diff --git a/server/mpm/mpmt_os2/mpmt_os2_child.c b/server/mpm/mpmt_os2/mpmt_os2_child.c
index f03f442..0b35e0b 100644
--- a/server/mpm/mpmt_os2/mpmt_os2_child.c
+++ b/server/mpm/mpmt_os2/mpmt_os2_child.c
@@ -190,13 +190,6 @@ void ap_mpm_child_main(apr_pool_t *pconf)
         clean_child_exit(APEXIT_CHILDFATAL);
     }
 
-#if 0 // 2013-03-24 SHL Moved to add_worker by Paul way back when
-    /* Create initial pool of worker threads */
-    for (c = 0; c < ap_min_spare_threads; c++) {
-        ap_scoreboard_image->servers[child_slot][c].tid = _beginthread(worker_main, NULL, 128*1024, (void *)c);
-    }
-#endif
-
     /* Start maintenance thread */
     server_maint_tid = _beginthread(server_maintenance, NULL, 32768, NULL);
 
@@ -222,7 +215,6 @@ void ap_mpm_child_main(apr_pool_t *pconf)
         apr_pool_t *pconn;
         worker_args_t *worker_args;
         int last_poll_idx = 0;
-
         apr_pool_create(&pconn, pchild);
         worker_args = apr_palloc(pconn, sizeof(worker_args_t));
         worker_args->pconn = pconn;
@@ -258,13 +250,12 @@ void ap_mpm_child_main(apr_pool_t *pconf)
 
                 lr = poll_results[last_poll_idx++].client_data;
                 rv = apr_socket_accept(&worker_args->conn_sd, lr->sd, pconn);
-
                 // 2014-11-30 SHL FIXME to be gone - spurious - see worker.c
                 // last_poll_idx++;
             }
         }
 
-#if 0
+#if 0 // Old way
         if (rv != APR_SUCCESS) {
             if (!APR_STATUS_IS_EINTR(rv)) {
                 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
@@ -272,7 +263,7 @@ void ap_mpm_child_main(apr_pool_t *pconf)
                 clean_child_exit(APEXIT_CHILDFATAL);
             }
         // } else {
-#else
+#else // New way
        if (rv != APR_SUCCESS) {
             if (APR_STATUS_IS_EAGAIN(rv)) {
                 // 2013-03-26 SHL
@@ -437,7 +428,7 @@ ULONG APIENTRY thread_exception_handler(EXCEPTIONREPORTRECORD *pReportRec,
 #endif
     } // if fatal
 
-#if 1 // FIXME to be gone - this handler only invoked if USE_EXCEPTQ not defined
+#if 1 // FIXME to be gone - this handler only invoked if USE_EXCEPTQ not defined which should not occur
     apiret = DosLoadModule (0, 0, "exceptq" ,&hmod);
     if (apiret) {
         // Silently ignore if not in LIBPATH
@@ -700,4 +691,3 @@ int IsExceptionHandlerChainOK(void)
   } // for
 }
 #endif
-
diff --git a/support/ab.c b/support/ab.c
index 25fc0e0..95b7cd5 100644
--- a/support/ab.c
+++ b/support/ab.c
@@ -2027,6 +2027,11 @@ int main(int argc, const char * const argv[])
     AB_SSL_METHOD_CONST SSL_METHOD *meth = SSLv23_client_method();
 #endif
 
+#   if OS2                              /* 2014-12-29 SHL want text output for OS2 */
+    _fsetmode(stdout, "t");
+    _fsetmode(stderr, "t");
+#   endif
+
     /* table defaults  */
     tablestring = "";
     trstring = "";
SplitPatch.pl (1,583 bytes)
mpmt_os2.c (21,026 bytes)   
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Multi-process, multi-threaded MPM for OS/2
 *
 * Server consists of
 * - a main, parent process
 * - a small, static number of child processes
 *
 * The parent process's job is to manage the child processes. This involves
 * spawning children as required to ensure there are always ap_daemons_to_start
 * processes accepting connections.
 *
 * Each child process consists of a a pool of worker threads and a
 * main thread that accepts connections & passes them to the workers via
 * a work queue. The worker thread pool is dynamic, managed by a maintanence
 * thread so that the number of idle threads is kept between
 * min_spare_threads & max_spare_threads.
 *
 */

/*
 Todo list
 - Enforce MaxClients somehow
*/
#define CORE_PRIVATE
#define INCL_NOPMAPI
#define INCL_DOS
#define INCL_DOSERRORS
#include "ap_config.h"
#include "httpd.h"
#include "mpm_default.h"
#include "http_main.h"
#include "http_log.h"
#include "http_config.h"
#include "http_core.h"  /* for get_remote_host */
#include "http_connection.h"
#include "mpm.h"
#include "ap_mpm.h"
#include "ap_listen.h"
#include "apr_portable.h"
#include "mpm_common.h"
#include "apr_strings.h"
#ifdef __KLIBC__
#include <os2safe.h>
#endif
#include <os2.h>
#include <process.h>

/* We don't need many processes,
 * they're only for redundancy in the event of a crash
 */
#define HARD_SERVER_LIMIT 10

/* Limit on the total number of threads per process
 */
#ifndef HARD_THREAD_LIMIT
#define HARD_THREAD_LIMIT 256
#endif

server_rec *ap_server_conf;
static apr_pool_t *pconf = NULL;  /* Pool for config stuff */
/* const char *ap_pid_fname=NULL;*/ /* defined in mpm_common.h */

/* Config globals */
static int one_process = 0;
static int ap_daemons_to_start = 0;
static int ap_thread_limit = 0;
/*static int ap_max_requests_per_child = 0;*/ /* defined in mpm_common.h */
int ap_min_spare_threads = 0;
int ap_max_spare_threads = 0;
int ap_thread_stack_size = 128 * 1024;

/* Keep track of a few interesting statistics */
int ap_max_daemons_limit = -1;

/* volatile just in case */
static int volatile shutdown_pending;
static int volatile restart_pending;
static int volatile is_graceful = 0;
ap_generation_t volatile ap_my_generation=0; /* Used by the scoreboard */
static int is_parent_process=TRUE;
HMTX ap_mpm_accept_mutex = 0;

/* An array of these is stored in a shared memory area for passing
 * sockets from the parent to child processes
 */
typedef struct {
    struct sockaddr_in name;
    apr_os_sock_t listen_fd;
} listen_socket_t;

typedef struct {
    HMTX accept_mutex;
    listen_socket_t listeners[1];
} parent_info_t;

static char master_main();
static void spawn_child(int slot);
void ap_mpm_child_main(apr_pool_t *pconf);
static void set_signals();


/**
 * Drive os/2 mpm worker loops
 * @called by main
 */
int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
{
    char *listener_shm_name;
    parent_info_t *parent_info;
    ULONG rc;
    pconf = _pconf;
    ap_server_conf = s;
    restart_pending = 0;
    ULONG    CurMaxFH      = 0;          /* Current count of handles         */
    LONG     ReqCount      = 0;          /* Number to adjust file handles    */
    PID   pidSemaphoreOwner = 0;         /* will get PID of sem owner */
    TID   tidSemaphoreOwner = 0;         /* will get TID of sem owner */
    ULONG ulRequestCount;      /* will get the request count for the sem */

    // DosSetMaxFH(ap_thread_limit * 2);

    rc = DosSetRelMaxFH(&ReqCount,     /* Using 0 here will return the       */
                        &CurMaxFH);    /* current number of file handles     */

    ReqCount = ap_thread_limit * 2;

    rc = DosSetRelMaxFH(&ReqCount,&CurMaxFH);     /* Change handle maximum */

    listener_shm_name = apr_psprintf(pconf, "/sharemem/httpd/parent_info.%d", getppid());
    rc = DosGetNamedSharedMem((PPVOID)&parent_info, listener_shm_name, PAG_READ);
    is_parent_process = rc != 0;
    ap_scoreboard_fname = apr_psprintf(pconf, "/sharemem/httpd/scoreboard.%d", is_parent_process ? getpid() : getppid());

    if (rc == 0) {
        /* Child process */
        ap_listen_rec *lr;
        int num_listeners = 0;

        ap_mpm_accept_mutex = parent_info->accept_mutex;

#if 0 // 2014-12-25 SHL looks like dead code - parent ensures listeners exist - FIXME to be gone
        /* Set up a default listener if necessary */
        if (ap_listeners == NULL) {
            ap_listen_rec *lr = apr_pcalloc(s->process->pool, sizeof(ap_listen_rec));
            ap_listeners = lr;
            apr_sockaddr_info_get(&lr->bind_addr, "0.0.0.0", APR_UNSPEC,
                                  DEFAULT_HTTP_PORT, 0, s->process->pool);
            apr_socket_create(&lr->sd, lr->bind_addr->family,
                              SOCK_STREAM, 0, s->process->pool);
        }
#endif
        // 2014-12-25 SHL Sync with parent sanity checks
        if (ap_listeners == NULL) {
            ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s,
                         "no listening sockets available, shutting down");
            return 1;
        }

        for (lr = ap_listeners; lr; lr = lr->next) {
            apr_sockaddr_t *sa;
            apr_os_sock_put(&lr->sd, &parent_info->listeners[num_listeners].listen_fd, pconf);
            apr_socket_addr_get(&sa, APR_LOCAL, lr->sd);
            // 2014-12-26 SHL Ensure socket_cleanup does not close listen socket owned by parent
            apr_sock_cleanup_kill(lr->sd);
            num_listeners++;
        }

        DosFreeMem(parent_info);

        /* Do the work */
        ap_mpm_child_main(pconf);

        /* Outta here */
        return 1;
    }
    else {
        /* Parent process or DosGetNamedSharedMem problem */
        char restart;
        is_parent_process = TRUE;

        // 2013-03-24 SHL
        if (rc != ERROR_FILE_NOT_FOUND)
            ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), s,
                         "DosGetNamedSharedMem returned %d", rc);

        if (ap_setup_listeners(ap_server_conf) < 1) {
            ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s,
                         "no listening sockets available, shutting down");
            return 1;
        }

        ap_log_pid(pconf, ap_pid_fname);

        restart = master_main();
        ++ap_my_generation;
        ap_scoreboard_image->global->running_generation = ap_my_generation;

        if (!restart) {
            const char *pidfile = ap_server_root_relative(pconf, ap_pid_fname);

            if (pidfile != NULL && remove(pidfile) == 0) {
                ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS,
                             ap_server_conf, "removed PID file %s (pid=%d)",
                             pidfile, getpid());
            }

            rc = DosQueryMutexSem(ap_mpm_accept_mutex,
                                  &pidSemaphoreOwner,
                                  &tidSemaphoreOwner,
                                  &ulRequestCount);
            // 2013-03-24 SHL was APLOG_INFO
            if (rc == 0)
                ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS,
                             ap_server_conf, "pidSemaphoreOwner = %d, tidSemaphoreOwner = %d, ulRequestCount = %ul",
                             pidSemaphoreOwner, tidSemaphoreOwner, ulRequestCount);

            // 2013-03-24 SHL
            else if (rc == ERROR_SEM_OWNER_DIED)
                ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc),
                             ap_server_conf, "Sem owner died pidSemaphoreOwner = %d, tidSemaphoreOwner = %d, ulRequestCount = %ul",
                             pidSemaphoreOwner, tidSemaphoreOwner, ulRequestCount);
            else
                ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), s,
                             "DosQueryMutexSem returned %d", rc);

            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
                         "caught SIGTERM, shutting down");
            return 1;                   /* fail */
        }
    }  /* Parent process */

    return 0; /* Restart */
}



/* Main processing of the parent process
 * returns TRUE if restarting
 */
static char master_main()
{
    server_rec *s = ap_server_conf;
    ap_listen_rec *lr;
    parent_info_t *parent_info;
    char *listener_shm_name;
    int listener_num, num_listeners, slot;
    ULONG rc;

    printf("%s \n", ap_get_server_description());
    set_signals();

    if (ap_setup_listeners(ap_server_conf) < 1) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s,
                     "no listening sockets available, shutting down");
        return FALSE;
    }

    /* Allocate a shared memory block for the array of listeners */
    for (num_listeners = 0, lr = ap_listeners; lr; lr = lr->next) {
        num_listeners++;
    }

    listener_shm_name = apr_psprintf(pconf, "/sharemem/httpd/parent_info.%d", getpid());
    rc = DosAllocSharedMem((PPVOID)&parent_info, listener_shm_name,
                           sizeof(parent_info_t) + num_listeners * sizeof(listen_socket_t),
                           PAG_READ|PAG_WRITE|PAG_COMMIT);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s,
                     "failure allocating shared memory, shutting down");
        return FALSE;
    }

    /* Store the listener sockets in the shared memory area for our children to see */
    for (listener_num = 0, lr = ap_listeners; lr; lr = lr->next, listener_num++) {
        apr_os_sock_get(&parent_info->listeners[listener_num].listen_fd, lr->sd);
    }

    /* Create mutex to prevent multiple child processes from detecting
     * a connection with apr_poll()
     */

    rc = DosCreateMutexSem(NULL, &ap_mpm_accept_mutex, DC_SEM_SHARED, FALSE);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s,
                     "failure creating accept mutex, shutting down");
        return FALSE;
    }

    parent_info->accept_mutex = ap_mpm_accept_mutex;

    /* Allocate shared memory for scoreboard */
    if (ap_scoreboard_image == NULL) {
        void *sb_mem;
        rc = DosAllocSharedMem(&sb_mem, ap_scoreboard_fname,
                               ap_calc_scoreboard_size(),
                               PAG_COMMIT|PAG_READ|PAG_WRITE);

        if (rc) {
            ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf,
                         "unable to allocate shared memory for scoreboard , exiting");
            return FALSE;
        }

        ap_init_scoreboard(sb_mem);
    }

    ap_scoreboard_image->global->restart_time = apr_time_now();
    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
                "%s configured -- resuming normal operations",
                ap_get_server_description());
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
                "Server built: %s", ap_get_server_built());
#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
                "AcceptMutex: %s (default: %s)",
                apr_proc_mutex_name(accept_mutex),
                apr_proc_mutex_defname());
#endif
    if (one_process) {
        ap_scoreboard_image->parent[0].pid = getpid();
        ap_mpm_child_main(pconf);
        return FALSE;
    }

    while (!restart_pending && !shutdown_pending) {
        RESULTCODES proc_rc;
        PID child_pid;
        int active_children = 0;

        /* Count number of active children */
        for (slot=0; slot < HARD_SERVER_LIMIT; slot++) {
            active_children += ap_scoreboard_image->parent[slot].pid != 0 &&
                !ap_scoreboard_image->parent[slot].quiescing;
        }

        /* Spawn children if needed */
        for (slot=0; slot < HARD_SERVER_LIMIT && active_children < ap_daemons_to_start; slot++) {
            if (ap_scoreboard_image->parent[slot].pid == 0) {
                spawn_child(slot);
                active_children++;
            }
        }

        rc = DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &proc_rc, &child_pid, 0);

        if (rc == 0) {
            /* A child has terminated, remove its scoreboard entry & terminate if necessary */
            for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++)
                ;                       // Keep looking

            if (slot < HARD_SERVER_LIMIT) {
                ap_scoreboard_image->parent[slot].pid = 0;
                ap_scoreboard_image->parent[slot].quiescing = 0;

                if (proc_rc.codeTerminate == TC_EXIT) {
                    /* Child terminated normally, check its exit code and
                     * terminate server if child indicates a fatal error
                     */
                    if (proc_rc.codeResult == APEXIT_CHILDFATAL)
                        break;
                }
            }
        } else if (rc == ERROR_CHILD_NOT_COMPLETE) {
            /* No child exited, lets sleep for a while.... */
            apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL);
        }
    } // while

    /* Signal children to shut down, either gracefully or immediately */
    for (slot=0; slot<HARD_SERVER_LIMIT; slot++) {
        if (ap_scoreboard_image->parent[slot].pid!=0){
          kill(ap_scoreboard_image->parent[slot].pid, is_graceful ? SIGHUP : SIGTERM);
        }
    }

    DosFreeMem(parent_info);
    return restart_pending;
}



static void spawn_child(int slot)
{
    PPIB ppib;
    PTIB ptib;
    char fail_module[100];
    char progname[CCHMAXPATH];
    RESULTCODES proc_rc;
    ULONG rc;

    ap_scoreboard_image->parent[slot].generation = ap_my_generation;
    DosGetInfoBlocks(&ptib, &ppib);
    DosQueryModuleName(ppib->pib_hmte, sizeof(progname), progname);
    rc = DosExecPgm(fail_module, sizeof(fail_module), EXEC_ASYNCRESULT,
                    ppib->pib_pchcmd, NULL, &proc_rc, progname);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf,
                     "error spawning child, slot %d", slot);
    }

    if (ap_max_daemons_limit < slot) {
        ap_max_daemons_limit = slot;
    }

    ap_scoreboard_image->parent[slot].pid = proc_rc.codeTerminate;
}



/* Signal handling routines */

static void sig_term(int sig)
{
    shutdown_pending = 1;
    signal(SIGTERM, SIG_DFL);
}



static void sig_restart(int sig)
{
    if (sig == SIGUSR1) {
        is_graceful = 1;
    }

    restart_pending = 1;
}



static void set_signals()
{
    struct sigaction sa;

    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sa.sa_handler = sig_term;

    if (sigaction(SIGTERM, &sa, NULL) < 0)
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)");

    if (sigaction(SIGINT, &sa, NULL) < 0)
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)");

    sa.sa_handler = sig_restart;

    if (sigaction(SIGHUP, &sa, NULL) < 0)
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)");
    if (sigaction(SIGUSR1, &sa, NULL) < 0)
        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGUSR1)");
}



/* Enquiry functions used get MPM status info */

AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
{
    switch (query_code) {
        case AP_MPMQ_MAX_DAEMON_USED:
            *result = ap_max_daemons_limit;
            return APR_SUCCESS;
        case AP_MPMQ_IS_THREADED:
            *result = AP_MPMQ_DYNAMIC;
            return APR_SUCCESS;
        case AP_MPMQ_IS_FORKED:
            *result = AP_MPMQ_NOT_SUPPORTED;
            return APR_SUCCESS;
        case AP_MPMQ_HARD_LIMIT_DAEMONS:
            *result = HARD_SERVER_LIMIT;
            return APR_SUCCESS;
        case AP_MPMQ_HARD_LIMIT_THREADS:
            *result = HARD_THREAD_LIMIT;
            return APR_SUCCESS;
        case AP_MPMQ_MIN_SPARE_DAEMONS:
            *result = 0;
            return APR_SUCCESS;
        case AP_MPMQ_MAX_SPARE_DAEMONS:
            *result = 0;
            return APR_SUCCESS;
        case AP_MPMQ_MAX_REQUESTS_DAEMON:
            *result = ap_max_requests_per_child;
            return APR_SUCCESS;
    }
    return APR_ENOTIMPL;
}



int ap_graceful_stop_signalled(void)
{
    return is_graceful;
}



/* Configuration handling stuff */

static int mpmt_os2_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
{
    one_process = ap_exists_config_define("ONE_PROCESS") ||
                  ap_exists_config_define("DEBUG");
    is_graceful = 0;
    ap_listen_pre_config();
    ap_daemons_to_start = DEFAULT_START_DAEMON;
    ap_thread_limit = HARD_THREAD_LIMIT;
    ap_pid_fname = DEFAULT_PIDLOG;
    ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
    ap_extended_status = 0;
    ap_min_spare_threads = DEFAULT_MIN_SPARE_THREAD;
    ap_max_spare_threads = DEFAULT_MAX_SPARE_THREAD;
#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE
        ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED;
#endif

    return OK;
}



static void mpmt_os2_hooks(apr_pool_t *p)
{
    ap_hook_pre_config(mpmt_os2_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
}



static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg)
{
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);

    if (err != NULL) {
        return err;
    }

    ap_daemons_to_start = atoi(arg);
    return NULL;
}



static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy,
                                         const char *arg)
{
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);

    if (err != NULL) {
        return err;
    }

    ap_min_spare_threads = atoi(arg);

    if (ap_min_spare_threads <= 0) {
       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                    "WARNING: detected MinSpareThreads set to non-positive.");
       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                    "Resetting to 1 to avoid almost certain Apache failure.");
       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                    "Please read the documentation.");
       ap_min_spare_threads = 1;
    }

    return NULL;
}



static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy,
                                         const char *arg)
{
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);

    if (err != NULL) {
        return err;
    }

    ap_max_spare_threads = atoi(arg);
    return NULL;
}



static const char *ignore_cmd(cmd_parms *cmd, void *dummy, const char *arg)
{
    return NULL;
}

static const char *set_thread_stacksize(cmd_parms *cmd, void *dummy,
                                        const char *arg)
{
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    if (err != NULL) {
        return err;
    }

    ap_thread_stack_size = atoi(arg);
    return NULL;
}



static const command_rec mpmt_os2_cmds[] = {
LISTEN_COMMANDS,
AP_INIT_TAKE1("ThreadStackSize", set_thread_stacksize, NULL, RSRC_CONF,
              "Stack size each created thread will use."),
AP_INIT_TAKE1( "StartServers", set_daemons_to_start, NULL, RSRC_CONF,
  "Number of child processes launched at server startup" ),
AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
  "Minimum number of idle children, to handle request spikes"),
AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
  "Maximum number of idle children"),
AP_INIT_TAKE1("User", ignore_cmd, NULL, RSRC_CONF,
  "Not applicable on this platform"),
AP_INIT_TAKE1("Group", ignore_cmd, NULL, RSRC_CONF,
  "Not applicable on this platform"),
AP_INIT_TAKE1("ScoreBoardFile", ignore_cmd, NULL, RSRC_CONF, \
  "Not applicable on this platform"),
{ NULL }
};

module AP_MODULE_DECLARE_DATA mpm_mpmt_os2_module = {
    MPM20_MODULE_STUFF,
    ap_mpm_rewrite_args,            /* hook to run before apache parses args */
    NULL,            /* create per-directory config structure */
    NULL,            /* merge per-directory config structures */
    NULL,            /* create per-server config structure */
    NULL,            /* merge per-server config structures */
    mpmt_os2_cmds,   /* command apr_table_t */
    mpmt_os2_hooks,  /* register_hooks */
};
mpmt_os2.c (21,026 bytes)   
mpmt_os2.c-20150203-1701.diff (3,259 bytes)   
diff --git a/server/mpm/mpmt_os2/mpmt_os2.c b/server/mpm/mpmt_os2/mpmt_os2.c
index d9c4b95..731d145 100644
--- a/server/mpm/mpmt_os2/mpmt_os2.c
+++ b/server/mpm/mpmt_os2/mpmt_os2.c
@@ -128,8 +128,8 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
     restart_pending = 0;
     ULONG    CurMaxFH      = 0;          /* Current count of handles         */
     LONG     ReqCount      = 0;          /* Number to adjust file handles    */
-    PID   pidSemaphoreOwner;   /* will get PID of sem owner */
-    TID   tidSemaphoreOwner;   /* will get TID of sem owner */
+    PID   pidSemaphoreOwner = 0;         /* will get PID of sem owner */
+    TID   tidSemaphoreOwner = 0;         /* will get TID of sem owner */
     ULONG ulRequestCount;      /* will get the request count for the sem */
 
     // DosSetMaxFH(ap_thread_limit * 2);
@@ -153,6 +153,7 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
 
         ap_mpm_accept_mutex = parent_info->accept_mutex;
 
+#if 0 // 2014-12-25 SHL looks like dead code - parent ensures listeners exist - FIXME to be gone
         /* Set up a default listener if necessary */
         if (ap_listeners == NULL) {
             ap_listen_rec *lr = apr_pcalloc(s->process->pool, sizeof(ap_listen_rec));
@@ -162,11 +163,20 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s )
             apr_socket_create(&lr->sd, lr->bind_addr->family,
                               SOCK_STREAM, 0, s->process->pool);
         }
+#endif
+        // 2014-12-25 SHL Sync with parent sanity checks
+        if (ap_listeners == NULL) {
+            ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s,
+                         "no listening sockets available, shutting down");
+            return 1;
+        }
 
         for (lr = ap_listeners; lr; lr = lr->next) {
             apr_sockaddr_t *sa;
             apr_os_sock_put(&lr->sd, &parent_info->listeners[num_listeners].listen_fd, pconf);
             apr_socket_addr_get(&sa, APR_LOCAL, lr->sd);
+            // 2014-12-26 SHL Ensure socket_cleanup does not close listen socket owned by parent
+            apr_sock_cleanup_kill(lr->sd);
             num_listeners++;
         }
 
@@ -352,7 +362,8 @@ static char master_main()
 
         if (rc == 0) {
             /* A child has terminated, remove its scoreboard entry & terminate if necessary */
-            for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++);
+            for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++)
+                ;                       // Keep looking
 
             if (slot < HARD_SERVER_LIMIT) {
                 ap_scoreboard_image->parent[slot].pid = 0;
@@ -370,11 +381,10 @@ static char master_main()
             /* No child exited, lets sleep for a while.... */
             apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL);
         }
-    }
+    } // while
 
     /* Signal children to shut down, either gracefully or immediately */
     for (slot=0; slot<HARD_SERVER_LIMIT; slot++) {
-
         if (ap_scoreboard_image->parent[slot].pid!=0){
           kill(ap_scoreboard_image->parent[slot].pid, is_graceful ? SIGHUP : SIGTERM);
         }
mpmt_os2.c-20150203-1701.diff (3,259 bytes)   
sendrecv.c (4,793 bytes)
apr_errno.h (54,259 bytes)
mpmt_os2_child.c-20150206-1839.diff (704 bytes)   
diff --git a/server/mpm/mpmt_os2/mpmt_os2_child.c b/server/mpm/mpmt_os2/mpmt_os2_child.c
index c7ab247..02dbad2 100644
--- a/server/mpm/mpmt_os2/mpmt_os2_child.c
+++ b/server/mpm/mpmt_os2/mpmt_os2_child.c
@@ -258,8 +258,9 @@ void ap_mpm_child_main(apr_pool_t *pconf)
         }
 
         if (rv != APR_SUCCESS) {
+            // 2013-03-26 SHL Warn and retry if EAGAIN
+            // 2015-02-04 SHL APR_STATUS_IS_EAGAIN updated to include SOCENOBUFS
             if (APR_STATUS_IS_EAGAIN(rv)) {
-                // 2013-03-26 SHL Warn
                 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, ap_server_conf,
                              "apr_socket_accept");
                 apr_sleep(5 * 1000L);
apr_errno.h-20150206-1838.diff (970 bytes)   
diff --git a/include/apr_errno.h b/include/apr_errno.h
index fb53806..80e6d9c 100644
--- a/include/apr_errno.h
+++ b/include/apr_errno.h
@@ -940,9 +940,12 @@ APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
                 || (s) == APR_OS_START_SYSERR + ERROR_INVALID_FUNCTION)
 #define APR_STATUS_IS_ESPIPE(s)         ((s) == APR_ESPIPE \
                 || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK)
+/* 2015-02-06 SHL SHL Add more */
 #define APR_STATUS_IS_EAGAIN(s)         ((s) == APR_EAGAIN \
                 || (s) == APR_OS_START_SYSERR + ERROR_NO_DATA \
                 || (s) == APR_OS_START_SYSERR + SOCEWOULDBLOCK \
+                || (s) == APR_OS_START_SYSERR + ENOBUFS \
+                || (s) == APR_OS_START_SYSERR + SOCENOBUFS \
                 || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION)
 #define APR_STATUS_IS_EINTR(s)          ((s) == APR_EINTR \
                 || (s) == APR_OS_START_SYSERR + SOCEINTR)
sendrecv.c-20150206-1849.diff (709 bytes)   
diff --git a/network_io/os2/sendrecv.c b/network_io/os2/sendrecv.c
index b561462..3fbb1a5 100644
--- a/network_io/os2/sendrecv.c
+++ b/network_io/os2/sendrecv.c
@@ -152,7 +152,10 @@ APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock,
 
         rv = writev(sock->socketdes, tmpvec, nv_tosend);
         err = rv < 0 ? sock_errno() : 0;
-    } while (err == SOCEINTR || err == SOCEWOULDBLOCK);
+        /* 2015-02-06 SHL Allow SOCENOBUFS and delay if out of resources */
+        if (err == SOCEWOULDBLOCK || err == SOCENOBUFS)
+          apr_sleep(100 * 1000);        /* 100 mSec */
+    } while (err == SOCEINTR || err == SOCEWOULDBLOCK || err == SOCENOBUFS);
 
     if (err) {
         *len = 0;
mpmt_os2_child.c (25,151 bytes)

Relationships

related to 0000190 closedpsmedley MaxRequestsPerChild problem 
related to 0000637 closedLewisR Apache 2.2.29 / PHP 5.4.34 issues - server: eCSVirtual 

Activities

LewisR

2014-12-23 03:06

developer   ~0002953

I might take exception to the statement "this is never the recommended value on any platform," as it actually is the recommended value for NetWare (and Win32, IIRC) - (0, that is).

Some reference:

http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxrequestsperchild

and

http://httpd.apache.org/docs/2.2/misc/perf-tuning.html

which states:

Related to process creation is process death induced by the MaxRequestsPerChild setting. By default this is 0, which means that there is no limit to the number of requests handled per child. If your configuration currently has this set to some very low number, such as 30, you may want to bump this up significantly. If you are running SunOS or an old version of Solaris, limit this to 10000 or so because of memory leaks.

So, while it may not be the recommended value on OS/2, it is still valid for other platforms. We just need to figure out what's best for us, I 'spose. ;-)

Steven Levine

2014-12-24 18:28

manager   ~0002954

You are correct - these are the compile time default values. I was talking about the recommended values. Perhaps never is too strong a word, because one can always find exceptions to a general rule.

The consensus of what I found in my searching was that 0 is not a recommended value. This makes sense because memory fragmentation, even if there are no leaks, is pretty much a sure thing for any long lived process.

LewisR

2014-12-24 19:13

developer   ~0002955

Again, this depends upon the platform. Obviously, our main concern here is with OS/2, where this may make a considerable difference. For comparison, the following is the default text from a NetWare installation of Apache 2.2.27, from httpd-mpm.conf:

# MaxRequestsPerChild: Maximum  number of requests a thread serves. It is     
#                      recommended that the default value of 0 be set for this
#                      directive on NetWare.  This will allow the thread to   
#                      continue to service requests indefinitely.             


Apparently, this should not cause significant fragmentation on NetWare (and again, I understand that the memory models are different between the two OSes). I'll be interested to see whether this really does make a big difference on OS/2.

LewisR

2014-12-25 00:32

developer   ~0002956

Last edited: 2014-12-25 00:33

Siege testing with benchmarks (siege -b -t60S http://<hosted-url>) against eCSVirtual (configured for two child server processes), with various settings:

MaxRequestsPerChild 0
Transactions:                  13423 hits
Availability:                 100.00 %
Elapsed time:                  59.15 secs
Data transferred:              15.28 MB
Response time:                  0.07 secs
Transaction rate:             226.93 trans/sec
Throughput:                     0.26 MB/sec
Concurrency:                   14.97
Successful transactions:       13423
Failed transactions:               0
Longest transaction:            0.38
Shortest transaction:           0.01

MaxRequestsPerChild 100
Transactions:                    200 hits
Availability:                  16.16 %
Elapsed time:                   1.90 secs
Data transferred:               0.23 MB
Response time:                  0.03 secs
Transaction rate:             105.26 trans/sec
Throughput:                     0.12 MB/sec
Concurrency:                    3.49
Successful transactions:         200
Failed transactions:            1038
Longest transaction:            0.06
Shortest transaction:           0.02

MaxRequestsPerChild 1000
Transactions:                   2000 hits
Availability:                  65.83 %
Elapsed time:                   5.82 secs
Data transferred:               2.28 MB
Response time:                  0.03 secs
Transaction rate:             343.64 trans/sec
Throughput:                     0.39 MB/sec
Concurrency:                   10.49
Successful transactions:        2000
Failed transactions:            1038
Longest transaction:            0.09
Shortest transaction:           0.02


In the non-0 MaxRequestsPerChild tests, the daemon exited cleanly (by itself) with:

[Wed Dec 24 19:23:34 2014] [error] (OS 10038)Socket operation on non-socket: apr_socket_accept
[Wed Dec 24 19:23:34 2014] [notice] caught SIGTERM, shutting down


No POPUPLOG entry, no .TRP file.

Looks like a recurring theme.

Steven Levine

2014-12-26 05:27

manager   ~0002957

Last edited: 2014-12-26 17:37

It's not a good idea to close in-use sockets that one does not own.

The parent httpd process creates the listen sockets and passes them to the child httpd processes via a named shared memory buffer.

In ap_mpm_run, we have the following code run by the child httpd processes:

mpmt_os2.c:166
        for (lr = ap_listeners; lr; lr = lr->next) {
            apr_sockaddr_t *sa;
            apr_os_sock_put(&lr->sd, &parent_info->listeners[num_listeners].listen_fd, pconf);
            apr_socket_addr_get(&sa, APR_LOCAL, lr->sd);
            num_listeners++;
        }

This has the side-effect of making the listen sockets known to one of the pools that will be destroyed by destroy_and_exit_process() when the child exits because socket_cleanup() is registered as a cleanup function for the poll.

This is wrong because the cleanup fuction will close the listen sockets and the child is not responsible for closing listen sockets it does not create. It has no way of knowing whether or not the socket is still in use by other processes. This is why we see the e10038 errors in the log.

There is code near mpmt_os2.c:156 that claims to set up a default listener if necessary. However, since the mpmt_os2.c:257 will shutdown the process if there are no listeners, my current belief that this code can never execute.

The fix is to avoid putting the listen sockets in the cleanup schedule, but I don't know how to do this yet.

Steven Levine

2014-12-26 17:38

manager   ~0002958

I have a potential fix for this. Update coming soon.

Steven Levine

2014-12-27 06:56

manager   ~0002961

The following patches

  apr_portable.h.diff
  sockets.c.diff
  mpmt_os2.c.diff

allow child httpd processes to avoid closing listener sockets they do not own. The APR patches implement apr_socket_pool_cleanup_kill() which allows the socket cleanup function responsible for closing the sockets to be removed from the pool. The mpmt_os2.c patch modifies ap_mpm_run to use this function.

The patch also intializes some variables to avoid spurous output in some log messages.

The patches compile clean, but are otherwise untested.

Steven Levine

2014-12-27 07:11

manager   ~0002962

To test that the patched build handles MaxRequestsPerChild per child properly, edit httpd.conf and set

  MaxRequestsPerChild=1

and run

  ab -c 2 -n 2 http://localhost/ 2>&1 | less

If all goes well, the http child processes should terminate without errors and the parent httpd process should spawn new child processes to replace them.

In a production setting, I expect that a

  MaxRequestsPerChild=2000

setting should be sufficient to avoid memory fragmentation issues on most systems.

psmedley

2014-12-27 08:13

administrator   ~0002963

Last edited: 2014-12-27 08:26

Slight error in patched with GCC 4.9.2:
network_io/os2/sockets.c:420:19: error: conflicting types for 'apr_sock_cleanup_
kill'
 APR_DECLARE(void) apr_sock_cleanup_kill(apr_socket_t *apr_sock)
                   ^
In file included from network_io/os2/sockets.c:21:0:
./include/apr_portable.h:401:27: note: previous declaration of 'apr_sock_cleanup
_kill' was here
 APR_DECLARE(apr_status_t) apr_sock_cleanup_kill(apr_socket_t *sock);

I changed the definition in sockets.c to apr_status_t to match apr_portable.h

I also assume that apr_socket_pool_cleanup_kill in mpmt_os2.c should be apr_sock_cleanup_kill - nope that one only takes one parameter

Steven Levine

2014-12-27 19:22

manager   ~0002964

Grumble. I sure messed that up. I've replaced the patches with a set that should work the way I intended.

If you look carefully at the original sockets.c patch you will notice that it applies to the copy of sockets.c in the hpptd srclib, which was not what I meant to do and it was not the file I was compiling. In addition, I neglected to add -Wimplicit to CFLAGS which would have caught the typos immediately.

apr_sock_cleanup_kill is the correct function to call. This was a copy/paste error that got though testing because I was not yet using -Wimplicit. The call is correct in the updated patch.

-Wall shows a couple of things that could be cleaned up, but these are not functional problems.

psmedley

2014-12-27 20:08

administrator   ~0002965

http://smedley.id.au/tmp/httpd-dll-20141228.zip contains these patches

psmedley

2014-12-27 20:31

administrator   ~0002966

results from ab:
[e:\internet\apache2\bin]ab -c 2 -n 2 http://localhost/ 2>&1 | more

This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss,
 Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)...apr_poll:
The timeout specified has expired (70007)
Send request failed!
Send request failed
!
 Total of 2 requests completed

LewisR

2014-12-27 20:37

developer   ~0002967

Wow!

MaxRequestsPerChild 1

Transactions:                   1624 hits
Availability:                 100.00 %
Elapsed time:                  59.51 secs
Data transferred:               1.85 MB
Response time:                  0.55 secs
Transaction rate:              27.29 trans/sec
Throughput:                     0.03 MB/sec
Concurrency:                   14.94
Successful transactions:        1624
Failed transactions:               0
Longest transaction:           29.83
Shortest transaction:           0.00

MaxRequestsPerChild 200

Transactions:                   5600 hits
Availability:                 100.00 %
Elapsed time:                  59.23 secs
Data transferred:               6.38 MB
Response time:                  0.15 secs
Transaction rate:              94.55 trans/sec
Throughput:                     0.11 MB/sec
Concurrency:                   14.63
Successful transactions:        5600
Failed transactions:               0
Longest transaction:            3.63
Shortest transaction:           0.00

MaxRequestsPerChild 2000

Transactions:                  20000 hits
Availability:                 100.00 %
Elapsed time:                  59.95 secs
Data transferred:              22.77 MB
Response time:                  0.04 secs
Transaction rate:             333.61 trans/sec
Throughput:                     0.38 MB/sec
Concurrency:                   14.48
Successful transactions:       20000
Failed transactions:               0
Longest transaction:            3.77
Shortest transaction:           0.00


CPU went up in the VM, but memory increased and decreased throughout the siege benchmark, settling back down to where it started when the siege finished (as did the CPU).

No errors in the log, and no failed transactions (of course, we weren't getting failed transactions with this siege configuration for the benchmark before).

Good job, guys! I'll do some more stress testing and then move this to production. FTR, the complete mpm settings in the VM are currently:

    ThreadStackSize    262144
    StartServers            2
    MinSpareThreads        50
    MaxSpareThreads        60
    MaxRequestsPerChild  2000

LewisR

2014-12-27 20:50

developer   ~0002968

Paul: My ab results were similar:

Send request failed!
Send request failed
!
 Total of 2 requests completed 

LewisR

2014-12-27 20:54

developer   ~0002969

Also, stress testing is not good.

5 second delay, 200 simultaneous clients, 2000 MaxRequestsPerChild yields me about 60 hits and hundreds of failures. Memory use goes up and stays up, even after the siege has ended.

I have some more tests to run before getting some process dumps. I'm quite stunned at the difference between the benchmarking and the actual stressing, though the major difference between the two is the heavier involvement of PHP, where we may be introducing some longer delays.

LewisR

2014-12-27 21:06

developer   ~0002970

For good measure, here are a few more siege benchmarks:

MaxRequestsPerChild 4000

Transactions:                  25173 hits
Availability:                 100.00 %
Elapsed time:                  59.26 secs
Data transferred:              28.66 MB
Response time:                  0.04 secs
Transaction rate:             424.79 trans/sec
Throughput:                     0.48 MB/sec
Concurrency:                   14.98
Successful transactions:       25173
Failed transactions:               0
Longest transaction:            3.07
Shortest transaction:           0.00

MaxRequestsPerChild 6000

Transactions:                  25524 hits
Availability:                 100.00 %
Elapsed time:                  59.03 secs
Data transferred:              29.06 MB
Response time:                  0.03 secs
Transaction rate:             432.39 trans/sec
Throughput:                     0.49 MB/sec
Concurrency:                   14.98
Successful transactions:       25524
Failed transactions:               0
Longest transaction:            4.06
Shortest transaction:           0.01

MaxRequestsPerChild 0

Transactions:                  30442 hits
Availability:                 100.00 %
Elapsed time:                  59.40 secs
Data transferred:              34.66 MB
Response time:                  0.03 secs
Transaction rate:             512.49 trans/sec
Throughput:                     0.58 MB/sec
Concurrency:                   14.98
Successful transactions:       30442
Failed transactions:               0
Longest transaction:            0.17
Shortest transaction:           0.02


Steve, do you still recommend a MaxRequestsPerChild of around 2000, and not 0? It would appear that the limiting logic produces some overhead vs no limit, though I realize our goal here is to limit fragmentation.

Steven Levine

2014-12-27 21:17

manager   ~0002971

I suspected the issue was mysql and this seems to confirm it. ab.exe testing against a simple php script run as

  ab -c 20 -n 999999

with

  MaxRequestsPerChild 10000

runs quickly (on the order of 20 msec/trx) here with no errors anywhere. Top confirms that the child processes exit. Getram shows memory usage for the httpd childrem on the order of 30MB max.

After brunch, I'll do some mysql tests.

Note that stopping the siege is not expected to drop the memory utilization. Only ending the child httpd process will do this.

LewisR

2014-12-27 21:19

developer   ~0002972

Last edited: 2014-12-29 01:57

Tested briefly on Hawking, without setting MaxRequestsPerChild. CPUs went high very quickly. RAM consumption increased and continued. After about five minutes, I killed Apache and reverted to the httpd-dll-20141217.zip dll which I was using previously.

More testing in the VM required, with various MaxRequestsPerChild settings.

Another difference between Hawking and eCSVirtual right now is that Hawking is running PHP 5.4.36, and eCSVirtual is still at 5.4.34.

LewisR

2014-12-29 02:03

developer   ~0002973

Steve, when bench testing (siege -b -t60S http://<hosted-url>), vs stress testing, the former of which does not touch on MySQL (index file only), memory utilization does indeed subside once the siege stops. I might speculate from this difference that the MySQL client is keeping the PHP process busy, which in turn is not allowing the child httpd process to shut down.

That said, we may be looking at returning to issue 0000637 to explore that further, as you do seem to have addressed the subject of this ticket.

psmedley

2014-12-29 02:47

administrator   ~0002974

the MySQL comment is interesting, as it supports what Max has been saying about mysql sockets being kept open....

LewisR

2014-12-29 02:59

developer   ~0002975

Last edited: 2014-12-29 03:02

...except that I'm not seeing sockets left open. That may be because in my setup MySQL is not running on the OS/2 box. NetWare does not appear to be accumulating large numbers of unclosed sockets, either (checking...confirmed). Presently, Hawking has opened five sockets on Galileo (the Netware server, running MySQL) which are in time wait. This after Galileo has been up for...58 days, and Hawking has been up for 4 days, 18 hours (a recent record, as I've been able to back off of the every-two-day-reboot schedule).

So, I still think that Max's issue has to do with MySQL (or MySQL being on the same box as Apache).

MySQL, MySQLi, and MySQLnd-related statements in php.ini (eCSVirtual; should be the same on Hawking; not using PDO-MySQL):

[MySQL]
; Allow accessing, from PHP's perspective, local files with LOAD DATA statements
; http://php.net/mysql.allow_local_infile
mysql.allow_local_infile = On
; Allow or prevent persistent links.
; http://php.net/mysql.allow-persistent
mysql.allow_persistent = Off
; If mysqlnd is used: Number of cache slots for the internal result set cache
; http://php.net/mysql.cache_size
mysql.cache_size = 2000
; Maximum number of persistent links. -1 means no limit.
; http://php.net/mysql.max-persistent
mysql.max_persistent = -1
; Maximum number of links (persistent + non-persistent). -1 means no limit.
; http://php.net/mysql.max-links
mysql.max_links = -1
; Default port number for mysql_connect(). If unset, mysql_connect() will use
; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the
; compile-time value defined MYSQL_PORT (in that order). Win32 will only look
; at MYSQL_PORT.
; http://php.net/mysql.default-port
mysql.default_port =
; Default socket name for local MySQL connects. If empty, uses the built-in
; MySQL defaults.
; http://php.net/mysql.default-socket
mysql.default_socket =
; Default host for mysql_connect() (doesn't apply in safe mode).
; http://php.net/mysql.default-host
mysql.default_host =
; Default user for mysql_connect() (doesn't apply in safe mode).
; http://php.net/mysql.default-user
mysql.default_user =
; Default password for mysql_connect() (doesn't apply in safe mode).
; Note that this is generally a *bad* idea to store passwords in this file.
; *Any* user with PHP access can run 'echo get_cfg_var("mysql.default_password")
; and reveal this password! And of course, any users with read access to this
; file will be able to reveal the password as well.
; http://php.net/mysql.default-password
mysql.default_password =
; Maximum time (in seconds) for connect timeout. -1 means no limit
; http://php.net/mysql.connect-timeout
mysql.connect_timeout = 60
; Trace mode. When trace_mode is active (=On), warnings for table/index scans and
; SQL-Errors will be displayed.
; http://php.net/mysql.trace-mode
mysql.trace_mode = Off
[MySQLi]
; Maximum number of persistent links. -1 means no limit.
; http://php.net/mysqli.max-persistent
mysqli.max_persistent = -1
; Allow accessing, from PHP's perspective, local files with LOAD DATA statements
; http://php.net/mysqli.allow_local_infile
;mysqli.allow_local_infile = On
; Allow or prevent persistent links.
; http://php.net/mysqli.allow-persistent
mysqli.allow_persistent = Off
; Maximum number of links. -1 means no limit.
; http://php.net/mysqli.max-links
mysqli.max_links = -1
; If mysqlnd is used: Number of cache slots for the internal result set cache
; http://php.net/mysqli.cache_size
mysqli.cache_size = 2000
; Default port number for mysqli_connect(). If unset, mysqli_connect() will use
; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the
; compile-time value defined MYSQL_PORT (in that order). Win32 will only look
; at MYSQL_PORT.
; http://php.net/mysqli.default-port
mysqli.default_port = 3306
; Default socket name for local MySQL connects. If empty, uses the built-in
; MySQL defaults.
; http://php.net/mysqli.default-socket
mysqli.default_socket =
; Default host for mysql_connect() (doesn't apply in safe mode).
; http://php.net/mysqli.default-host
mysqli.default_host =
; Default user for mysql_connect() (doesn't apply in safe mode).
; http://php.net/mysqli.default-user
mysqli.default_user =
; Default password for mysqli_connect() (doesn't apply in safe mode).
; Note that this is generally a *bad* idea to store passwords in this file.
; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw")
; and reveal this password! And of course, any users with read access to this
; file will be able to reveal the password as well.
; http://php.net/mysqli.default-pw
mysqli.default_pw =
; Allow or prevent reconnect
mysqli.reconnect = On
[mysqlnd]
; Enable / Disable collection of general statstics by mysqlnd which can be
; used to tune and monitor MySQL operations.
; http://php.net/mysqlnd.collect_statistics
mysqlnd.collect_statistics = On
; Enable / Disable collection of memory usage statstics by mysqlnd which can be
; used to tune and monitor MySQL operations.
; http://php.net/mysqlnd.collect_memory_statistics
mysqlnd.collect_memory_statistics = On
; Size of a pre-allocated buffer used when sending commands to MySQL in bytes.
; http://php.net/mysqlnd.net_cmd_buffer_size
;mysqlnd.net_cmd_buffer_size = 4096
; Size of a pre-allocated buffer used for reading data sent by the server in
; bytes.
; http://php.net/mysqlnd.net_read_buffer_size
;mysqlnd.net_read_buffer_size = 32768

Steven Levine

2015-01-10 18:29

manager   ~0003007

apr-1.5.1.git-20150110-1002-shl.diff and httpd-2.2.29.git-20150110-1012-shl.diff are my current incremental patches to the apr and httpd sources. The patches are applied to the sources after Paul's current patches are applied.

If the cumulative patch file is too cumbersome to work with, you can use the attached. SplitPatch.pl to split them into per file patch files.

Steven Levine

2015-01-24 01:34

manager   ~0003017

The patches are included in httpd-dll-20141228.zip and newer.

Steven Levine

2015-02-04 01:32

manager   ~0003021

Reopening because more code needed to avoid queue full issues.

psmedley

2018-10-17 02:12

administrator   ~0003209

Last edited: 2018-10-17 08:46

It likely makes sense to focus on Apache2 2.4.x for this issue going forward. Now that we have builds available, I'll also try and make a current copy of the source diff available here. I should also attach the current diffs I'm using for APR/APR-UTIL as well.

psmedley

2018-10-17 08:47

administrator   ~0003210

Diffs attached
php-5.4.45.diff (268,408 bytes)
httpd-2.4.35.diff (82,724 bytes)   
Only in httpd-2.4.35/build: config_vars.mk
Only in httpd-2.4.35/build: config_vars.sh
Only in httpd-2.4.35/build/pkg: pkginfo
Only in httpd-2.4.35/build: rules.mk
Only in httpd-2.4.35: build.cmd
Only in httpd-2.4.35: build.log
Only in httpd-2.4.35: buildmark.o
Only in httpd-2.4.35: conf.cmd
Only in httpd-2.4.35: config.log
Only in httpd-2.4.35: config.nice
Only in httpd-2.4.35: config.status
diff -ur httpd-2.4.35-o/configure httpd-2.4.35/configure
--- httpd-2.4.35-o/configure	2018-09-18 10:24:26.000000000 +0930
+++ httpd-2.4.35/configure	2018-10-09 11:41:24.000000000 +1030
@@ -17660,8 +17660,8 @@
         # structure, so ask libtool to hide libsed internals:
 
   if test "x$MOD_SED_LDADD" = "x"; then
-    test "x$silent" != "xyes" && echo "  setting MOD_SED_LDADD to \"-export-symbols-regex sed_module\""
-    MOD_SED_LDADD="-export-symbols-regex sed_module"
+    test "x$silent" != "xyes" && echo "  setting MOD_SED_LDADD to \"\""
+    MOD_SED_LDADD=""
   else
     apr_addto_bugger="-export-symbols-regex sed_module"
     for i in $apr_addto_bugger; do
@@ -27373,9 +27373,9 @@
 
   if test "x$MOD_SSL_LDADD" = "x"; then
     test "x$silent" != "xyes" && echo "  setting MOD_SSL_LDADD to \"-export-symbols-regex ssl_module\""
-    MOD_SSL_LDADD="-export-symbols-regex ssl_module"
+    MOD_SSL_LDADD=" "
   else
-    apr_addto_bugger="-export-symbols-regex ssl_module"
+    apr_addto_bugger=" "
     for i in $apr_addto_bugger; do
       apr_addto_duplicate="0"
       for j in $MOD_SSL_LDADD; do
@@ -29547,6 +29547,8 @@
 case $host in
     *mingw*)
         ;;
+    *os2-emx*)
+        ;;
     *)
         NONPORTABLE_SUPPORT="checkgid fcgistarter"
         ;;
Only in httpd-2.4.35: configure.lineno
Only in httpd-2.4.35: configure.log
Only in httpd-2.4.35: configure.orig
Only in httpd-2.4.35/docs/conf/extra: httpd-autoindex.conf
Only in httpd-2.4.35/docs/conf/extra: httpd-dav.conf
Only in httpd-2.4.35/docs/conf/extra: httpd-default.conf
Only in httpd-2.4.35/docs/conf/extra: httpd-info.conf
Only in httpd-2.4.35/docs/conf/extra: httpd-languages.conf
Only in httpd-2.4.35/docs/conf/extra: httpd-manual.conf
Only in httpd-2.4.35/docs/conf/extra: httpd-mpm.conf
Only in httpd-2.4.35/docs/conf/extra: httpd-multilang-errordoc.conf
Only in httpd-2.4.35/docs/conf/extra: httpd-ssl.conf
Only in httpd-2.4.35/docs/conf/extra: httpd-userdir.conf
Only in httpd-2.4.35/docs/conf/extra: httpd-vhosts.conf
Only in httpd-2.4.35/docs/conf/extra: proxy-html.conf
Only in httpd-2.4.35/docs/conf: httpd.conf
Only in httpd-2.4.35: httpd
Only in httpd-2.4.35: httpd.dll
Only in httpd-2.4.35: httpd.exe
Only in httpd-2.4.35: httpd.map
Only in httpd-2.4.35: httpd.xqs
Only in httpd-2.4.35: httpx
Only in httpd-2.4.35: httpx.exe
Only in httpd-2.4.35: httpx.map
Only in httpd-2.4.35: httpx.xqs
Only in httpd-2.4.35/include: ap_config_auto.h
Only in httpd-2.4.35/include: ap_config_layout.h
diff -ur httpd-2.4.35-o/include/ap_config.h httpd-2.4.35/include/ap_config.h
--- httpd-2.4.35-o/include/ap_config.h	2012-08-15 09:29:24.000000000 +0930
+++ httpd-2.4.35/include/ap_config.h	2018-10-14 11:43:28.000000000 +1030
@@ -102,7 +102,7 @@
 #define AP_DECLARE_DATA             __declspec(dllimport)
 #endif
 
-#if !defined(WIN32) || defined(AP_MODULE_DECLARE_STATIC)
+#if (!defined(WIN32) && !defined(__OS2__)) || defined(AP_MODULE_DECLARE_STATIC)
 /**
  * Declare a dso module's exported module structure as AP_MODULE_DECLARE_DATA.
  *
@@ -118,7 +118,7 @@
 #define AP_MODULE_DECLARE(type)            type
 #endif
 #define AP_MODULE_DECLARE_NONSTD(type)     type
-#define AP_MODULE_DECLARE_DATA
+#define AP_MODULE_DECLARE_DATA		
 #else
 /**
  * AP_MODULE_DECLARE_EXPORT is a no-op.  Unless contradicted by the
diff -ur httpd-2.4.35-o/include/httpd.h httpd-2.4.35/include/httpd.h
--- httpd-2.4.35-o/include/httpd.h	2018-09-11 23:34:52.000000000 +0930
+++ httpd-2.4.35/include/httpd.h	2018-10-09 11:41:24.000000000 +1030
@@ -104,13 +104,7 @@
  * directive.
  */
 #ifndef DOCUMENT_LOCATION
-#ifdef OS2
-/* Set default for OS/2 file system */
-#define DOCUMENT_LOCATION  HTTPD_ROOT "/docs"
-#else
-/* Set default for non OS/2 file system */
 #define DOCUMENT_LOCATION  HTTPD_ROOT "/htdocs"
-#endif
 #endif /* DOCUMENT_LOCATION */
 
 /** Maximum number of dynamically loaded modules */
@@ -123,7 +117,7 @@
 
 /** The name of the log files */
 #ifndef DEFAULT_ERRORLOG
-#if defined(OS2) || defined(WIN32)
+#if defined(WIN32)
 #define DEFAULT_ERRORLOG "logs/error.log"
 #else
 #define DEFAULT_ERRORLOG "logs/error_log"
@@ -132,12 +126,7 @@
 
 /** Define this to be what your per-directory security files are called */
 #ifndef DEFAULT_ACCESS_FNAME
-#ifdef OS2
-/* Set default for OS/2 file system */
-#define DEFAULT_ACCESS_FNAME "htaccess"
-#else
 #define DEFAULT_ACCESS_FNAME ".htaccess"
-#endif
 #endif /* DEFAULT_ACCESS_FNAME */
 
 /** The name of the server config file */
Only in httpd-2.4.35/modules: .deps
Only in httpd-2.4.35/modules/aaa: .deps
Only in httpd-2.4.35/modules/aaa: .libs
Only in httpd-2.4.35/modules/aaa: mod_access_compat.la
Only in httpd-2.4.35/modules/aaa: mod_access_compat.lo
Only in httpd-2.4.35/modules/aaa: mod_access_compat.o
Only in httpd-2.4.35/modules/aaa: mod_access_compat.slo
Only in httpd-2.4.35/modules/aaa: mod_allowmethods.la
Only in httpd-2.4.35/modules/aaa: mod_allowmethods.lo
Only in httpd-2.4.35/modules/aaa: mod_allowmethods.o
Only in httpd-2.4.35/modules/aaa: mod_allowmethods.slo
Only in httpd-2.4.35/modules/aaa: mod_auth_basic.la
Only in httpd-2.4.35/modules/aaa: mod_auth_basic.lo
Only in httpd-2.4.35/modules/aaa: mod_auth_basic.o
Only in httpd-2.4.35/modules/aaa: mod_auth_basic.slo
Only in httpd-2.4.35/modules/aaa: mod_auth_digest.la
Only in httpd-2.4.35/modules/aaa: mod_auth_digest.lo
Only in httpd-2.4.35/modules/aaa: mod_auth_digest.o
Only in httpd-2.4.35/modules/aaa: mod_auth_digest.slo
Only in httpd-2.4.35/modules/aaa: mod_auth_form.la
Only in httpd-2.4.35/modules/aaa: mod_auth_form.lo
Only in httpd-2.4.35/modules/aaa: mod_auth_form.o
Only in httpd-2.4.35/modules/aaa: mod_auth_form.slo
Only in httpd-2.4.35/modules/aaa: mod_authn_anon.la
Only in httpd-2.4.35/modules/aaa: mod_authn_anon.lo
Only in httpd-2.4.35/modules/aaa: mod_authn_anon.o
Only in httpd-2.4.35/modules/aaa: mod_authn_anon.slo
Only in httpd-2.4.35/modules/aaa: mod_authn_core.la
Only in httpd-2.4.35/modules/aaa: mod_authn_core.lo
Only in httpd-2.4.35/modules/aaa: mod_authn_core.o
Only in httpd-2.4.35/modules/aaa: mod_authn_core.slo
Only in httpd-2.4.35/modules/aaa: mod_authn_dbd.la
Only in httpd-2.4.35/modules/aaa: mod_authn_dbd.lo
Only in httpd-2.4.35/modules/aaa: mod_authn_dbd.o
Only in httpd-2.4.35/modules/aaa: mod_authn_dbd.slo
Only in httpd-2.4.35/modules/aaa: mod_authn_dbm.la
Only in httpd-2.4.35/modules/aaa: mod_authn_dbm.lo
Only in httpd-2.4.35/modules/aaa: mod_authn_dbm.o
Only in httpd-2.4.35/modules/aaa: mod_authn_dbm.slo
Only in httpd-2.4.35/modules/aaa: mod_authn_file.la
Only in httpd-2.4.35/modules/aaa: mod_authn_file.lo
Only in httpd-2.4.35/modules/aaa: mod_authn_file.o
Only in httpd-2.4.35/modules/aaa: mod_authn_file.slo
Only in httpd-2.4.35/modules/aaa: mod_authn_socache.la
Only in httpd-2.4.35/modules/aaa: mod_authn_socache.lo
Only in httpd-2.4.35/modules/aaa: mod_authn_socache.o
Only in httpd-2.4.35/modules/aaa: mod_authn_socache.slo
Only in httpd-2.4.35/modules/aaa: mod_authz_core.la
Only in httpd-2.4.35/modules/aaa: mod_authz_core.lo
Only in httpd-2.4.35/modules/aaa: mod_authz_core.o
Only in httpd-2.4.35/modules/aaa: mod_authz_core.slo
Only in httpd-2.4.35/modules/aaa: mod_authz_dbd.la
Only in httpd-2.4.35/modules/aaa: mod_authz_dbd.lo
Only in httpd-2.4.35/modules/aaa: mod_authz_dbd.o
Only in httpd-2.4.35/modules/aaa: mod_authz_dbd.slo
Only in httpd-2.4.35/modules/aaa: mod_authz_dbm.la
Only in httpd-2.4.35/modules/aaa: mod_authz_dbm.lo
Only in httpd-2.4.35/modules/aaa: mod_authz_dbm.o
Only in httpd-2.4.35/modules/aaa: mod_authz_dbm.slo
Only in httpd-2.4.35/modules/aaa: mod_authz_groupfile.la
Only in httpd-2.4.35/modules/aaa: mod_authz_groupfile.lo
Only in httpd-2.4.35/modules/aaa: mod_authz_groupfile.o
Only in httpd-2.4.35/modules/aaa: mod_authz_groupfile.slo
Only in httpd-2.4.35/modules/aaa: mod_authz_host.la
Only in httpd-2.4.35/modules/aaa: mod_authz_host.lo
Only in httpd-2.4.35/modules/aaa: mod_authz_host.o
Only in httpd-2.4.35/modules/aaa: mod_authz_host.slo
Only in httpd-2.4.35/modules/aaa: mod_authz_owner.la
Only in httpd-2.4.35/modules/aaa: mod_authz_owner.lo
Only in httpd-2.4.35/modules/aaa: mod_authz_owner.o
Only in httpd-2.4.35/modules/aaa: mod_authz_owner.slo
Only in httpd-2.4.35/modules/aaa: mod_authz_user.la
Only in httpd-2.4.35/modules/aaa: mod_authz_user.lo
Only in httpd-2.4.35/modules/aaa: mod_authz_user.o
Only in httpd-2.4.35/modules/aaa: mod_authz_user.slo
Only in httpd-2.4.35/modules/aaa: modules.mk
Only in httpd-2.4.35/modules/aaa: Makefile
Only in httpd-2.4.35/modules/arch/unix: .deps
Only in httpd-2.4.35/modules/arch/unix: modules.mk
Only in httpd-2.4.35/modules/arch/unix: Makefile
Only in httpd-2.4.35/modules/arch/win32: .deps
Only in httpd-2.4.35/modules/arch/win32: modules.mk
Only in httpd-2.4.35/modules/arch/win32: Makefile
Only in httpd-2.4.35/modules/cache: .deps
Only in httpd-2.4.35/modules/cache: .libs
Only in httpd-2.4.35/modules/cache: cache_storage.lo
Only in httpd-2.4.35/modules/cache: cache_storage.o
Only in httpd-2.4.35/modules/cache: cache_storage.slo
Only in httpd-2.4.35/modules/cache: cache_util.lo
Only in httpd-2.4.35/modules/cache: cache_util.o
Only in httpd-2.4.35/modules/cache: cache_util.slo
Only in httpd-2.4.35/modules/cache: mod_cache_disk.la
Only in httpd-2.4.35/modules/cache: mod_cache_disk.lo
Only in httpd-2.4.35/modules/cache: mod_cache_disk.o
Only in httpd-2.4.35/modules/cache: mod_cache_disk.slo
Only in httpd-2.4.35/modules/cache: mod_cache_socache.la
Only in httpd-2.4.35/modules/cache: mod_cache_socache.lo
Only in httpd-2.4.35/modules/cache: mod_cache_socache.o
Only in httpd-2.4.35/modules/cache: mod_cache_socache.slo
Only in httpd-2.4.35/modules/cache: mod_cache.la
Only in httpd-2.4.35/modules/cache: mod_cache.lo
Only in httpd-2.4.35/modules/cache: mod_cache.o
Only in httpd-2.4.35/modules/cache: mod_cache.slo
Only in httpd-2.4.35/modules/cache: mod_socache_dbm.la
Only in httpd-2.4.35/modules/cache: mod_socache_dbm.lo
Only in httpd-2.4.35/modules/cache: mod_socache_dbm.o
Only in httpd-2.4.35/modules/cache: mod_socache_dbm.slo
Only in httpd-2.4.35/modules/cache: mod_socache_memcache.la
Only in httpd-2.4.35/modules/cache: mod_socache_memcache.lo
Only in httpd-2.4.35/modules/cache: mod_socache_memcache.o
Only in httpd-2.4.35/modules/cache: mod_socache_memcache.slo
Only in httpd-2.4.35/modules/cache: mod_socache_shmcb.la
Only in httpd-2.4.35/modules/cache: mod_socache_shmcb.lo
Only in httpd-2.4.35/modules/cache: mod_socache_shmcb.o
Only in httpd-2.4.35/modules/cache: mod_socache_shmcb.slo
Only in httpd-2.4.35/modules/cache: modules.mk
Only in httpd-2.4.35/modules/cache: Makefile
Only in httpd-2.4.35/modules/cluster: .deps
Only in httpd-2.4.35/modules/cluster: .libs
Only in httpd-2.4.35/modules/cluster: mod_heartbeat.la
Only in httpd-2.4.35/modules/cluster: mod_heartbeat.lo
Only in httpd-2.4.35/modules/cluster: mod_heartbeat.o
Only in httpd-2.4.35/modules/cluster: mod_heartbeat.slo
Only in httpd-2.4.35/modules/cluster: mod_heartmonitor.la
Only in httpd-2.4.35/modules/cluster: mod_heartmonitor.lo
Only in httpd-2.4.35/modules/cluster: mod_heartmonitor.o
Only in httpd-2.4.35/modules/cluster: mod_heartmonitor.slo
Only in httpd-2.4.35/modules/cluster: modules.mk
Only in httpd-2.4.35/modules/cluster: Makefile
Only in httpd-2.4.35/modules/core: .deps
Only in httpd-2.4.35/modules/core: .libs
Only in httpd-2.4.35/modules/core: libmod_so.la
Only in httpd-2.4.35/modules/core: mod_macro.la
Only in httpd-2.4.35/modules/core: mod_macro.lo
Only in httpd-2.4.35/modules/core: mod_macro.o
Only in httpd-2.4.35/modules/core: mod_macro.slo
Only in httpd-2.4.35/modules/core: mod_so.lo
Only in httpd-2.4.35/modules/core: mod_so.o
Only in httpd-2.4.35/modules/core: mod_watchdog.la
Only in httpd-2.4.35/modules/core: mod_watchdog.lo
Only in httpd-2.4.35/modules/core: mod_watchdog.o
Only in httpd-2.4.35/modules/core: mod_watchdog.slo
Only in httpd-2.4.35/modules/core: modules.mk
Only in httpd-2.4.35/modules/core: Makefile
Only in httpd-2.4.35/modules/database: .deps
Only in httpd-2.4.35/modules/database: .libs
Only in httpd-2.4.35/modules/database: mod_dbd.la
Only in httpd-2.4.35/modules/database: mod_dbd.lo
Only in httpd-2.4.35/modules/database: mod_dbd.o
Only in httpd-2.4.35/modules/database: mod_dbd.slo
Only in httpd-2.4.35/modules/database: modules.mk
Only in httpd-2.4.35/modules/database: Makefile
Only in httpd-2.4.35/modules/dav/fs: .deps
Only in httpd-2.4.35/modules/dav/fs: .libs
Only in httpd-2.4.35/modules/dav/fs: dbm.lo
Only in httpd-2.4.35/modules/dav/fs: dbm.o
Only in httpd-2.4.35/modules/dav/fs: dbm.slo
Only in httpd-2.4.35/modules/dav/fs: lock.lo
Only in httpd-2.4.35/modules/dav/fs: lock.o
Only in httpd-2.4.35/modules/dav/fs: lock.slo
Only in httpd-2.4.35/modules/dav/fs: mod_dav_fs.la
Only in httpd-2.4.35/modules/dav/fs: mod_dav_fs.lo
Only in httpd-2.4.35/modules/dav/fs: mod_dav_fs.o
Only in httpd-2.4.35/modules/dav/fs: mod_dav_fs.slo
Only in httpd-2.4.35/modules/dav/fs: modules.mk
Only in httpd-2.4.35/modules/dav/fs: Makefile
Only in httpd-2.4.35/modules/dav/fs: repos.lo
Only in httpd-2.4.35/modules/dav/fs: repos.o
Only in httpd-2.4.35/modules/dav/fs: repos.slo
Only in httpd-2.4.35/modules/dav/lock: .deps
Only in httpd-2.4.35/modules/dav/lock: .libs
Only in httpd-2.4.35/modules/dav/lock: locks.lo
Only in httpd-2.4.35/modules/dav/lock: locks.o
Only in httpd-2.4.35/modules/dav/lock: locks.slo
Only in httpd-2.4.35/modules/dav/lock: mod_dav_lock.la
Only in httpd-2.4.35/modules/dav/lock: mod_dav_lock.lo
Only in httpd-2.4.35/modules/dav/lock: mod_dav_lock.o
Only in httpd-2.4.35/modules/dav/lock: mod_dav_lock.slo
Only in httpd-2.4.35/modules/dav/lock: modules.mk
Only in httpd-2.4.35/modules/dav/lock: Makefile
Only in httpd-2.4.35/modules/dav/main: .deps
Only in httpd-2.4.35/modules/dav/main: .libs
Only in httpd-2.4.35/modules/dav/main: liveprop.lo
Only in httpd-2.4.35/modules/dav/main: liveprop.o
Only in httpd-2.4.35/modules/dav/main: liveprop.slo
Only in httpd-2.4.35/modules/dav/main: mod_dav.la
Only in httpd-2.4.35/modules/dav/main: mod_dav.lo
Only in httpd-2.4.35/modules/dav/main: mod_dav.o
Only in httpd-2.4.35/modules/dav/main: mod_dav.slo
Only in httpd-2.4.35/modules/dav/main: modules.mk
Only in httpd-2.4.35/modules/dav/main: Makefile
Only in httpd-2.4.35/modules/dav/main: props.lo
Only in httpd-2.4.35/modules/dav/main: props.o
Only in httpd-2.4.35/modules/dav/main: props.slo
Only in httpd-2.4.35/modules/dav/main: providers.lo
Only in httpd-2.4.35/modules/dav/main: providers.o
Only in httpd-2.4.35/modules/dav/main: providers.slo
Only in httpd-2.4.35/modules/dav/main: std_liveprop.lo
Only in httpd-2.4.35/modules/dav/main: std_liveprop.o
Only in httpd-2.4.35/modules/dav/main: std_liveprop.slo
Only in httpd-2.4.35/modules/dav/main: util_lock.lo
Only in httpd-2.4.35/modules/dav/main: util_lock.o
Only in httpd-2.4.35/modules/dav/main: util_lock.slo
Only in httpd-2.4.35/modules/dav/main: util.lo
Only in httpd-2.4.35/modules/dav/main: util.o
Only in httpd-2.4.35/modules/dav/main: util.slo
Only in httpd-2.4.35/modules/debugging: .deps
Only in httpd-2.4.35/modules/debugging: .libs
Only in httpd-2.4.35/modules/debugging: mod_dumpio.la
Only in httpd-2.4.35/modules/debugging: mod_dumpio.lo
Only in httpd-2.4.35/modules/debugging: mod_dumpio.o
Only in httpd-2.4.35/modules/debugging: mod_dumpio.slo
Only in httpd-2.4.35/modules/debugging: modules.mk
Only in httpd-2.4.35/modules/debugging: Makefile
Only in httpd-2.4.35/modules/echo: .deps
Only in httpd-2.4.35/modules/echo: .libs
Only in httpd-2.4.35/modules/echo: mod_echo.la
Only in httpd-2.4.35/modules/echo: mod_echo.lo
Only in httpd-2.4.35/modules/echo: mod_echo.o
Only in httpd-2.4.35/modules/echo: mod_echo.slo
Only in httpd-2.4.35/modules/echo: modules.mk
Only in httpd-2.4.35/modules/echo: Makefile
Only in httpd-2.4.35/modules/examples: .deps
Only in httpd-2.4.35/modules/examples: modules.mk
Only in httpd-2.4.35/modules/examples: Makefile
Only in httpd-2.4.35/modules/experimental: .deps
Only in httpd-2.4.35/modules/experimental: modules.mk
Only in httpd-2.4.35/modules/experimental: Makefile
Only in httpd-2.4.35/modules/filters: .deps
Only in httpd-2.4.35/modules/filters: .libs
Only in httpd-2.4.35/modules/filters: mod_buffer.la
Only in httpd-2.4.35/modules/filters: mod_buffer.lo
Only in httpd-2.4.35/modules/filters: mod_buffer.o
Only in httpd-2.4.35/modules/filters: mod_buffer.slo
Only in httpd-2.4.35/modules/filters: mod_charset_lite.la
Only in httpd-2.4.35/modules/filters: mod_charset_lite.lo
Only in httpd-2.4.35/modules/filters: mod_charset_lite.o
Only in httpd-2.4.35/modules/filters: mod_charset_lite.slo
Only in httpd-2.4.35/modules/filters: mod_data.la
Only in httpd-2.4.35/modules/filters: mod_data.lo
Only in httpd-2.4.35/modules/filters: mod_data.o
Only in httpd-2.4.35/modules/filters: mod_data.slo
Only in httpd-2.4.35/modules/filters: mod_deflate.la
Only in httpd-2.4.35/modules/filters: mod_deflate.lo
Only in httpd-2.4.35/modules/filters: mod_deflate.o
Only in httpd-2.4.35/modules/filters: mod_deflate.slo
diff -ur httpd-2.4.35-o/modules/filters/mod_ext_filter.c httpd-2.4.35/modules/filters/mod_ext_filter.c
--- httpd-2.4.35-o/modules/filters/mod_ext_filter.c	2016-12-23 23:06:26.000000000 +1030
+++ httpd-2.4.35/modules/filters/mod_ext_filter.c	2018-10-09 11:41:24.000000000 +1030
@@ -368,15 +368,15 @@
         (core_dir_config *)ap_get_core_module_config(r->per_dir_config);
     apr_status_t rv;
 
-#ifdef RLIMIT_CPU
+#if defined(RLIMIT_CPU) && !defined(OS2)
     rv = apr_procattr_limit_set(procattr, APR_LIMIT_CPU, conf->limit_cpu);
     ap_assert(rv == APR_SUCCESS); /* otherwise, we're out of sync with APR */
 #endif
-#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
+#if (defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)) && !defined(OS2)
     rv = apr_procattr_limit_set(procattr, APR_LIMIT_MEM, conf->limit_mem);
     ap_assert(rv == APR_SUCCESS); /* otherwise, we're out of sync with APR */
 #endif
-#ifdef RLIMIT_NPROC
+#if defined(RLIMIT_NPROC) && !defined(OS2)
     rv = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC, conf->limit_nproc);
     ap_assert(rv == APR_SUCCESS); /* otherwise, we're out of sync with APR */
 #endif
Only in httpd-2.4.35/modules/filters: mod_ext_filter.la
Only in httpd-2.4.35/modules/filters: mod_ext_filter.lo
Only in httpd-2.4.35/modules/filters: mod_ext_filter.o
Only in httpd-2.4.35/modules/filters: mod_ext_filter.slo
Only in httpd-2.4.35/modules/filters: mod_filter.la
Only in httpd-2.4.35/modules/filters: mod_filter.lo
Only in httpd-2.4.35/modules/filters: mod_filter.o
Only in httpd-2.4.35/modules/filters: mod_filter.slo
Only in httpd-2.4.35/modules/filters: mod_include.la
Only in httpd-2.4.35/modules/filters: mod_include.lo
Only in httpd-2.4.35/modules/filters: mod_include.o
Only in httpd-2.4.35/modules/filters: mod_include.slo
Only in httpd-2.4.35/modules/filters: mod_ratelimit.la
Only in httpd-2.4.35/modules/filters: mod_ratelimit.lo
Only in httpd-2.4.35/modules/filters: mod_ratelimit.o
Only in httpd-2.4.35/modules/filters: mod_ratelimit.slo
Only in httpd-2.4.35/modules/filters: mod_reflector.la
Only in httpd-2.4.35/modules/filters: mod_reflector.lo
Only in httpd-2.4.35/modules/filters: mod_reflector.o
Only in httpd-2.4.35/modules/filters: mod_reflector.slo
Only in httpd-2.4.35/modules/filters: mod_reqtimeout.la
Only in httpd-2.4.35/modules/filters: mod_reqtimeout.lo
Only in httpd-2.4.35/modules/filters: mod_reqtimeout.o
Only in httpd-2.4.35/modules/filters: mod_reqtimeout.slo
Only in httpd-2.4.35/modules/filters: mod_request.la
Only in httpd-2.4.35/modules/filters: mod_request.lo
Only in httpd-2.4.35/modules/filters: mod_request.o
Only in httpd-2.4.35/modules/filters: mod_request.slo
Only in httpd-2.4.35/modules/filters: mod_sed.la
Only in httpd-2.4.35/modules/filters: mod_sed.lo
Only in httpd-2.4.35/modules/filters: mod_sed.o
Only in httpd-2.4.35/modules/filters: mod_sed.slo
Only in httpd-2.4.35/modules/filters: mod_substitute.la
Only in httpd-2.4.35/modules/filters: mod_substitute.lo
Only in httpd-2.4.35/modules/filters: mod_substitute.o
Only in httpd-2.4.35/modules/filters: mod_substitute.slo
Only in httpd-2.4.35/modules/filters: modules.mk
Only in httpd-2.4.35/modules/filters: Makefile
Only in httpd-2.4.35/modules/filters: regexp.lo
Only in httpd-2.4.35/modules/filters: regexp.o
Only in httpd-2.4.35/modules/filters: regexp.slo
Only in httpd-2.4.35/modules/filters: sed0.lo
Only in httpd-2.4.35/modules/filters: sed0.o
Only in httpd-2.4.35/modules/filters: sed0.slo
Only in httpd-2.4.35/modules/filters: sed1.lo
Only in httpd-2.4.35/modules/filters: sed1.o
Only in httpd-2.4.35/modules/filters: sed1.slo
Only in httpd-2.4.35/modules/generators: .deps
Only in httpd-2.4.35/modules/generators: .libs
Only in httpd-2.4.35/modules/generators: mod_asis.la
Only in httpd-2.4.35/modules/generators: mod_asis.lo
Only in httpd-2.4.35/modules/generators: mod_asis.o
Only in httpd-2.4.35/modules/generators: mod_asis.slo
Only in httpd-2.4.35/modules/generators: mod_autoindex.la
Only in httpd-2.4.35/modules/generators: mod_autoindex.lo
Only in httpd-2.4.35/modules/generators: mod_autoindex.o
Only in httpd-2.4.35/modules/generators: mod_autoindex.slo
diff -ur httpd-2.4.35-o/modules/generators/mod_cgi.c httpd-2.4.35/modules/generators/mod_cgi.c
--- httpd-2.4.35-o/modules/generators/mod_cgi.c	2017-09-08 22:40:16.000000000 +0930
+++ httpd-2.4.35/modules/generators/mod_cgi.c	2018-10-09 11:41:24.000000000 +1030
@@ -54,7 +54,7 @@
 #include "mod_cgi.h"
 
 #if APR_HAVE_STRUCT_RLIMIT
-#if defined (RLIMIT_CPU) || defined (RLIMIT_NPROC) || defined (RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
+#if defined ((RLIMIT_CPU) || defined (RLIMIT_NPROC) || defined (RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)) && !defined(OS2)
 #define AP_CGI_USE_RLIMIT
 #endif
 #endif
@@ -403,6 +403,7 @@
     int i;
 #endif
 
+
     RAISE_SIGSTOP(CGI_CHILD);
 #ifdef DEBUG_CGI
     fprintf(dbg, "Attempting to exec %s as CGI child (argv0 = %s)\n",
Only in httpd-2.4.35/modules/generators: mod_info.la
Only in httpd-2.4.35/modules/generators: mod_info.lo
Only in httpd-2.4.35/modules/generators: mod_info.o
Only in httpd-2.4.35/modules/generators: mod_info.slo
Only in httpd-2.4.35/modules/generators: mod_status.la
Only in httpd-2.4.35/modules/generators: mod_status.lo
Only in httpd-2.4.35/modules/generators: mod_status.o
Only in httpd-2.4.35/modules/generators: mod_status.slo
Only in httpd-2.4.35/modules/generators: modules.mk
Only in httpd-2.4.35/modules/generators: Makefile
Only in httpd-2.4.35/modules/http: .deps
Only in httpd-2.4.35/modules/http: .libs
Only in httpd-2.4.35/modules/http: byterange_filter.lo
Only in httpd-2.4.35/modules/http: byterange_filter.o
Only in httpd-2.4.35/modules/http: chunk_filter.lo
Only in httpd-2.4.35/modules/http: chunk_filter.o
Only in httpd-2.4.35/modules/http: http_core.lo
Only in httpd-2.4.35/modules/http: http_core.o
Only in httpd-2.4.35/modules/http: http_etag.lo
Only in httpd-2.4.35/modules/http: http_etag.o
Only in httpd-2.4.35/modules/http: http_filters.lo
Only in httpd-2.4.35/modules/http: http_filters.o
Only in httpd-2.4.35/modules/http: http_protocol.lo
Only in httpd-2.4.35/modules/http: http_protocol.o
Only in httpd-2.4.35/modules/http: http_request.lo
Only in httpd-2.4.35/modules/http: http_request.o
Only in httpd-2.4.35/modules/http: libmod_http.la
Only in httpd-2.4.35/modules/http: mod_mime.la
Only in httpd-2.4.35/modules/http: mod_mime.lo
Only in httpd-2.4.35/modules/http: mod_mime.o
Only in httpd-2.4.35/modules/http: mod_mime.slo
Only in httpd-2.4.35/modules/http: modules.mk
Only in httpd-2.4.35/modules/http: Makefile
Only in httpd-2.4.35/modules/http2: .deps
Only in httpd-2.4.35/modules/http2: modules.mk
Only in httpd-2.4.35/modules/http2: Makefile
Only in httpd-2.4.35/modules/ldap: .deps
Only in httpd-2.4.35/modules/ldap: modules.mk
Only in httpd-2.4.35/modules/ldap: Makefile
Only in httpd-2.4.35/modules/loggers: .deps
Only in httpd-2.4.35/modules/loggers: .libs
Only in httpd-2.4.35/modules/loggers: mod_log_config.la
Only in httpd-2.4.35/modules/loggers: mod_log_config.lo
Only in httpd-2.4.35/modules/loggers: mod_log_config.o
Only in httpd-2.4.35/modules/loggers: mod_log_config.slo
Only in httpd-2.4.35/modules/loggers: mod_log_debug.la
Only in httpd-2.4.35/modules/loggers: mod_log_debug.lo
Only in httpd-2.4.35/modules/loggers: mod_log_debug.o
Only in httpd-2.4.35/modules/loggers: mod_log_debug.slo
Only in httpd-2.4.35/modules/loggers: mod_log_forensic.la
Only in httpd-2.4.35/modules/loggers: mod_log_forensic.lo
Only in httpd-2.4.35/modules/loggers: mod_log_forensic.o
Only in httpd-2.4.35/modules/loggers: mod_log_forensic.slo
Only in httpd-2.4.35/modules/loggers: mod_logio.la
Only in httpd-2.4.35/modules/loggers: mod_logio.lo
Only in httpd-2.4.35/modules/loggers: mod_logio.o
Only in httpd-2.4.35/modules/loggers: mod_logio.slo
Only in httpd-2.4.35/modules/loggers: modules.mk
Only in httpd-2.4.35/modules/loggers: Makefile
Only in httpd-2.4.35/modules/lua: .deps
Only in httpd-2.4.35/modules/lua: modules.mk
Only in httpd-2.4.35/modules/lua: Makefile
Only in httpd-2.4.35/modules/mappers: .deps
Only in httpd-2.4.35/modules/mappers: .libs
Only in httpd-2.4.35/modules/mappers: mod_actions.la
Only in httpd-2.4.35/modules/mappers: mod_actions.lo
Only in httpd-2.4.35/modules/mappers: mod_actions.o
Only in httpd-2.4.35/modules/mappers: mod_actions.slo
Only in httpd-2.4.35/modules/mappers: mod_alias.la
Only in httpd-2.4.35/modules/mappers: mod_alias.lo
Only in httpd-2.4.35/modules/mappers: mod_alias.o
Only in httpd-2.4.35/modules/mappers: mod_alias.slo
Only in httpd-2.4.35/modules/mappers: mod_dir.la
Only in httpd-2.4.35/modules/mappers: mod_dir.lo
Only in httpd-2.4.35/modules/mappers: mod_dir.o
Only in httpd-2.4.35/modules/mappers: mod_dir.slo
Only in httpd-2.4.35/modules/mappers: mod_negotiation.la
Only in httpd-2.4.35/modules/mappers: mod_negotiation.lo
Only in httpd-2.4.35/modules/mappers: mod_negotiation.o
Only in httpd-2.4.35/modules/mappers: mod_negotiation.slo
Only in httpd-2.4.35/modules/mappers: mod_rewrite.la
Only in httpd-2.4.35/modules/mappers: mod_rewrite.lo
Only in httpd-2.4.35/modules/mappers: mod_rewrite.o
Only in httpd-2.4.35/modules/mappers: mod_rewrite.slo
Only in httpd-2.4.35/modules/mappers: mod_speling.la
Only in httpd-2.4.35/modules/mappers: mod_speling.lo
Only in httpd-2.4.35/modules/mappers: mod_speling.o
Only in httpd-2.4.35/modules/mappers: mod_speling.slo
Only in httpd-2.4.35/modules/mappers: mod_userdir.la
Only in httpd-2.4.35/modules/mappers: mod_userdir.lo
Only in httpd-2.4.35/modules/mappers: mod_userdir.o
Only in httpd-2.4.35/modules/mappers: mod_userdir.slo
Only in httpd-2.4.35/modules/mappers: mod_vhost_alias.la
Only in httpd-2.4.35/modules/mappers: mod_vhost_alias.lo
Only in httpd-2.4.35/modules/mappers: mod_vhost_alias.o
Only in httpd-2.4.35/modules/mappers: mod_vhost_alias.slo
Only in httpd-2.4.35/modules/mappers: modules.mk
Only in httpd-2.4.35/modules/mappers: Makefile
Only in httpd-2.4.35/modules/md: .deps
Only in httpd-2.4.35/modules/md: modules.mk
Only in httpd-2.4.35/modules/md: Makefile
Only in httpd-2.4.35/modules/metadata: .deps
Only in httpd-2.4.35/modules/metadata: .libs
Only in httpd-2.4.35/modules/metadata: mod_env.la
Only in httpd-2.4.35/modules/metadata: mod_env.lo
Only in httpd-2.4.35/modules/metadata: mod_env.o
Only in httpd-2.4.35/modules/metadata: mod_env.slo
Only in httpd-2.4.35/modules/metadata: mod_expires.la
Only in httpd-2.4.35/modules/metadata: mod_expires.lo
Only in httpd-2.4.35/modules/metadata: mod_expires.o
Only in httpd-2.4.35/modules/metadata: mod_expires.slo
Only in httpd-2.4.35/modules/metadata: mod_headers.la
Only in httpd-2.4.35/modules/metadata: mod_headers.lo
Only in httpd-2.4.35/modules/metadata: mod_headers.o
Only in httpd-2.4.35/modules/metadata: mod_headers.slo
Only in httpd-2.4.35/modules/metadata: mod_mime_magic.la
Only in httpd-2.4.35/modules/metadata: mod_mime_magic.lo
Only in httpd-2.4.35/modules/metadata: mod_mime_magic.o
Only in httpd-2.4.35/modules/metadata: mod_mime_magic.slo
Only in httpd-2.4.35/modules/metadata: mod_remoteip.la
Only in httpd-2.4.35/modules/metadata: mod_remoteip.lo
Only in httpd-2.4.35/modules/metadata: mod_remoteip.o
Only in httpd-2.4.35/modules/metadata: mod_remoteip.slo
Only in httpd-2.4.35/modules/metadata: mod_setenvif.la
Only in httpd-2.4.35/modules/metadata: mod_setenvif.lo
Only in httpd-2.4.35/modules/metadata: mod_setenvif.o
Only in httpd-2.4.35/modules/metadata: mod_setenvif.slo
Only in httpd-2.4.35/modules/metadata: mod_unique_id.la
Only in httpd-2.4.35/modules/metadata: mod_unique_id.lo
Only in httpd-2.4.35/modules/metadata: mod_unique_id.o
Only in httpd-2.4.35/modules/metadata: mod_unique_id.slo
Only in httpd-2.4.35/modules/metadata: mod_usertrack.la
Only in httpd-2.4.35/modules/metadata: mod_usertrack.lo
Only in httpd-2.4.35/modules/metadata: mod_usertrack.o
Only in httpd-2.4.35/modules/metadata: mod_usertrack.slo
Only in httpd-2.4.35/modules/metadata: mod_version.la
Only in httpd-2.4.35/modules/metadata: mod_version.lo
Only in httpd-2.4.35/modules/metadata: mod_version.o
Only in httpd-2.4.35/modules/metadata: mod_version.slo
Only in httpd-2.4.35/modules/metadata: modules.mk
Only in httpd-2.4.35/modules/metadata: Makefile
Only in httpd-2.4.35/modules: Makefile
Only in httpd-2.4.35/modules/proxy: .deps
Only in httpd-2.4.35/modules/proxy: .libs
Only in httpd-2.4.35/modules/proxy: ajp_header.lo
Only in httpd-2.4.35/modules/proxy: ajp_header.o
Only in httpd-2.4.35/modules/proxy: ajp_header.slo
Only in httpd-2.4.35/modules/proxy: ajp_link.lo
Only in httpd-2.4.35/modules/proxy: ajp_link.o
Only in httpd-2.4.35/modules/proxy: ajp_link.slo
Only in httpd-2.4.35/modules/proxy: ajp_msg.lo
Only in httpd-2.4.35/modules/proxy: ajp_msg.o
Only in httpd-2.4.35/modules/proxy: ajp_msg.slo
Only in httpd-2.4.35/modules/proxy: ajp_utils.lo
Only in httpd-2.4.35/modules/proxy: ajp_utils.o
Only in httpd-2.4.35/modules/proxy: ajp_utils.slo
Only in httpd-2.4.35/modules/proxy/balancers: .deps
Only in httpd-2.4.35/modules/proxy/balancers: .libs
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_bybusyness.la
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_bybusyness.lo
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_bybusyness.o
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_bybusyness.slo
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_byrequests.la
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_byrequests.lo
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_byrequests.o
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_byrequests.slo
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_bytraffic.la
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_bytraffic.lo
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_bytraffic.o
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_bytraffic.slo
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_heartbeat.la
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_heartbeat.lo
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_heartbeat.o
Only in httpd-2.4.35/modules/proxy/balancers: mod_lbmethod_heartbeat.slo
Only in httpd-2.4.35/modules/proxy/balancers: modules.mk
Only in httpd-2.4.35/modules/proxy/balancers: Makefile
Only in httpd-2.4.35/modules/proxy: mod_proxy_ajp.la
Only in httpd-2.4.35/modules/proxy: mod_proxy_ajp.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy_ajp.o
Only in httpd-2.4.35/modules/proxy: mod_proxy_ajp.slo
Only in httpd-2.4.35/modules/proxy: mod_proxy_balancer.la
Only in httpd-2.4.35/modules/proxy: mod_proxy_balancer.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy_balancer.o
Only in httpd-2.4.35/modules/proxy: mod_proxy_balancer.slo
Only in httpd-2.4.35/modules/proxy: mod_proxy_connect.la
Only in httpd-2.4.35/modules/proxy: mod_proxy_connect.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy_connect.o
Only in httpd-2.4.35/modules/proxy: mod_proxy_connect.slo
Only in httpd-2.4.35/modules/proxy: mod_proxy_express.la
Only in httpd-2.4.35/modules/proxy: mod_proxy_express.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy_express.o
Only in httpd-2.4.35/modules/proxy: mod_proxy_express.slo
Only in httpd-2.4.35/modules/proxy: mod_proxy_fcgi.la
Only in httpd-2.4.35/modules/proxy: mod_proxy_fcgi.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy_fcgi.o
Only in httpd-2.4.35/modules/proxy: mod_proxy_fcgi.slo
Only in httpd-2.4.35/modules/proxy: mod_proxy_ftp.la
Only in httpd-2.4.35/modules/proxy: mod_proxy_ftp.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy_ftp.o
Only in httpd-2.4.35/modules/proxy: mod_proxy_ftp.slo
Only in httpd-2.4.35/modules/proxy: mod_proxy_hcheck.la
Only in httpd-2.4.35/modules/proxy: mod_proxy_hcheck.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy_hcheck.o
Only in httpd-2.4.35/modules/proxy: mod_proxy_hcheck.slo
Only in httpd-2.4.35/modules/proxy: mod_proxy_http.la
Only in httpd-2.4.35/modules/proxy: mod_proxy_http.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy_http.o
Only in httpd-2.4.35/modules/proxy: mod_proxy_http.slo
Only in httpd-2.4.35/modules/proxy: mod_proxy_scgi.la
Only in httpd-2.4.35/modules/proxy: mod_proxy_scgi.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy_scgi.o
Only in httpd-2.4.35/modules/proxy: mod_proxy_scgi.slo
Only in httpd-2.4.35/modules/proxy: mod_proxy_uwsgi.la
Only in httpd-2.4.35/modules/proxy: mod_proxy_uwsgi.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy_uwsgi.o
Only in httpd-2.4.35/modules/proxy: mod_proxy_uwsgi.slo
Only in httpd-2.4.35/modules/proxy: mod_proxy_wstunnel.la
Only in httpd-2.4.35/modules/proxy: mod_proxy_wstunnel.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy_wstunnel.o
Only in httpd-2.4.35/modules/proxy: mod_proxy_wstunnel.slo
Only in httpd-2.4.35/modules/proxy: mod_proxy.la
Only in httpd-2.4.35/modules/proxy: mod_proxy.lo
Only in httpd-2.4.35/modules/proxy: mod_proxy.o
Only in httpd-2.4.35/modules/proxy: mod_proxy.slo
Only in httpd-2.4.35/modules/proxy: modules.mk
Only in httpd-2.4.35/modules/proxy: Makefile
Only in httpd-2.4.35/modules/proxy: proxy_util.lo
Only in httpd-2.4.35/modules/proxy: proxy_util.o
Only in httpd-2.4.35/modules/proxy: proxy_util.slo
Only in httpd-2.4.35/modules/session: .deps
Only in httpd-2.4.35/modules/session: .libs
Only in httpd-2.4.35/modules/session: mod_session_cookie.la
Only in httpd-2.4.35/modules/session: mod_session_cookie.lo
Only in httpd-2.4.35/modules/session: mod_session_cookie.o
Only in httpd-2.4.35/modules/session: mod_session_cookie.slo
Only in httpd-2.4.35/modules/session: mod_session_dbd.la
Only in httpd-2.4.35/modules/session: mod_session_dbd.lo
Only in httpd-2.4.35/modules/session: mod_session_dbd.o
Only in httpd-2.4.35/modules/session: mod_session_dbd.slo
Only in httpd-2.4.35/modules/session: mod_session.la
Only in httpd-2.4.35/modules/session: mod_session.lo
Only in httpd-2.4.35/modules/session: mod_session.o
Only in httpd-2.4.35/modules/session: mod_session.slo
Only in httpd-2.4.35/modules/session: modules.mk
Only in httpd-2.4.35/modules/session: Makefile
Only in httpd-2.4.35/modules/slotmem: .deps
Only in httpd-2.4.35/modules/slotmem: .libs
Only in httpd-2.4.35/modules/slotmem: mod_slotmem_plain.la
Only in httpd-2.4.35/modules/slotmem: mod_slotmem_plain.lo
Only in httpd-2.4.35/modules/slotmem: mod_slotmem_plain.o
Only in httpd-2.4.35/modules/slotmem: mod_slotmem_plain.slo
Only in httpd-2.4.35/modules/slotmem: mod_slotmem_shm.la
Only in httpd-2.4.35/modules/slotmem: mod_slotmem_shm.lo
Only in httpd-2.4.35/modules/slotmem: mod_slotmem_shm.o
Only in httpd-2.4.35/modules/slotmem: mod_slotmem_shm.slo
Only in httpd-2.4.35/modules/slotmem: modules.mk
Only in httpd-2.4.35/modules/slotmem: Makefile
Only in httpd-2.4.35/modules/ssl: .deps
Only in httpd-2.4.35/modules/ssl: .libs
Only in httpd-2.4.35/modules/ssl: mod_ssl.la
Only in httpd-2.4.35/modules/ssl: mod_ssl.lo
Only in httpd-2.4.35/modules/ssl: mod_ssl.o
Only in httpd-2.4.35/modules/ssl: mod_ssl.slo
Only in httpd-2.4.35/modules/ssl: modules.mk
Only in httpd-2.4.35/modules/ssl: Makefile
Only in httpd-2.4.35/modules/ssl: ssl_engine_config.lo
Only in httpd-2.4.35/modules/ssl: ssl_engine_config.o
Only in httpd-2.4.35/modules/ssl: ssl_engine_config.slo
Only in httpd-2.4.35/modules/ssl: ssl_engine_init.lo
Only in httpd-2.4.35/modules/ssl: ssl_engine_init.o
Only in httpd-2.4.35/modules/ssl: ssl_engine_init.slo
Only in httpd-2.4.35/modules/ssl: ssl_engine_io.lo
Only in httpd-2.4.35/modules/ssl: ssl_engine_io.o
Only in httpd-2.4.35/modules/ssl: ssl_engine_io.slo
Only in httpd-2.4.35/modules/ssl: ssl_engine_kernel.lo
Only in httpd-2.4.35/modules/ssl: ssl_engine_kernel.o
Only in httpd-2.4.35/modules/ssl: ssl_engine_kernel.slo
Only in httpd-2.4.35/modules/ssl: ssl_engine_log.lo
Only in httpd-2.4.35/modules/ssl: ssl_engine_log.o
Only in httpd-2.4.35/modules/ssl: ssl_engine_log.slo
Only in httpd-2.4.35/modules/ssl: ssl_engine_mutex.lo
Only in httpd-2.4.35/modules/ssl: ssl_engine_mutex.o
Only in httpd-2.4.35/modules/ssl: ssl_engine_mutex.slo
Only in httpd-2.4.35/modules/ssl: ssl_engine_ocsp.lo
Only in httpd-2.4.35/modules/ssl: ssl_engine_ocsp.o
Only in httpd-2.4.35/modules/ssl: ssl_engine_ocsp.slo
diff -ur httpd-2.4.35-o/modules/ssl/ssl_engine_pphrase.c httpd-2.4.35/modules/ssl/ssl_engine_pphrase.c
--- httpd-2.4.35-o/modules/ssl/ssl_engine_pphrase.c	2015-09-30 21:01:42.000000000 +0930
+++ httpd-2.4.35/modules/ssl/ssl_engine_pphrase.c	2018-10-09 11:41:24.000000000 +1030
@@ -250,7 +250,7 @@
          * user (but not the dialog program) a few more
          * chances...
          */
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__OS2__) /* 2011-01-31 */
         if ((sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN
              || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE)
 #else
@@ -268,7 +268,7 @@
                             * 5 * APR_USEC_PER_SEC);
             continue;
         }
-#ifdef WIN32
+#if defined(WIN32) || defined(__OS2__) /* 2011-01-31 */
         if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN) {
             ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02577)
                          "Init: SSLPassPhraseDialog builtin is not "
@@ -450,7 +450,8 @@
     if ((p = strchr(buf, '\n')) != NULL) {
         *p = '\0';
     }
-#ifdef WIN32
+#if defined(WIN32) || defined(__OS2__) /* 2011-01-31 */
+
     /* XXX: apr_sometest */
     if ((p = strchr(buf, '\r')) != NULL) {
         *p = '\0';
@@ -510,7 +511,7 @@
                          "Init: Requesting pass phrase via piped dialog");
         }
         else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */
-#ifdef WIN32
+#if defined(WIN32) || defined(__OS2__) /* 2011-01-31 */
             PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD);
             memset(buf, 0, (unsigned int)bufsize);
             return (-1);
Only in httpd-2.4.35/modules/ssl: ssl_engine_pphrase.lo
Only in httpd-2.4.35/modules/ssl: ssl_engine_pphrase.o
Only in httpd-2.4.35/modules/ssl: ssl_engine_pphrase.slo
Only in httpd-2.4.35/modules/ssl: ssl_engine_rand.lo
Only in httpd-2.4.35/modules/ssl: ssl_engine_rand.o
Only in httpd-2.4.35/modules/ssl: ssl_engine_rand.slo
Only in httpd-2.4.35/modules/ssl: ssl_engine_vars.lo
Only in httpd-2.4.35/modules/ssl: ssl_engine_vars.o
Only in httpd-2.4.35/modules/ssl: ssl_engine_vars.slo
Only in httpd-2.4.35/modules/ssl: ssl_scache.lo
Only in httpd-2.4.35/modules/ssl: ssl_scache.o
Only in httpd-2.4.35/modules/ssl: ssl_scache.slo
Only in httpd-2.4.35/modules/ssl: ssl_util_ocsp.lo
Only in httpd-2.4.35/modules/ssl: ssl_util_ocsp.o
Only in httpd-2.4.35/modules/ssl: ssl_util_ocsp.slo
Only in httpd-2.4.35/modules/ssl: ssl_util_ssl.lo
Only in httpd-2.4.35/modules/ssl: ssl_util_ssl.o
Only in httpd-2.4.35/modules/ssl: ssl_util_ssl.slo
Only in httpd-2.4.35/modules/ssl: ssl_util_stapling.lo
Only in httpd-2.4.35/modules/ssl: ssl_util_stapling.o
Only in httpd-2.4.35/modules/ssl: ssl_util_stapling.slo
Only in httpd-2.4.35/modules/ssl: ssl_util.lo
Only in httpd-2.4.35/modules/ssl: ssl_util.o
Only in httpd-2.4.35/modules/ssl: ssl_util.slo
Only in httpd-2.4.35/modules/test: .deps
Only in httpd-2.4.35/modules/test: .libs
Only in httpd-2.4.35/modules/test: mod_dialup.la
Only in httpd-2.4.35/modules/test: mod_dialup.lo
Only in httpd-2.4.35/modules/test: mod_dialup.o
Only in httpd-2.4.35/modules/test: mod_dialup.slo
Only in httpd-2.4.35/modules/test: modules.mk
Only in httpd-2.4.35/modules/test: Makefile
Only in httpd-2.4.35: modules.c
Only in httpd-2.4.35: modules.lo
Only in httpd-2.4.35: modules.o
Only in httpd-2.4.35: Makefile
Only in httpd-2.4.35/os: .deps
Only in httpd-2.4.35/os: Makefile
Only in httpd-2.4.35/os/os2: .deps
Only in httpd-2.4.35/os/os2: .libs
diff -ur httpd-2.4.35-o/os/os2/core_header.def httpd-2.4.35/os/os2/core_header.def
--- httpd-2.4.35-o/os/os2/core_header.def	2009-08-26 18:26:12.000000000 +0930
+++ httpd-2.4.35/os/os2/core_header.def	2018-10-09 11:41:24.000000000 +1030
@@ -3,17 +3,17 @@
 DATA NONSHARED
 
 EXPORTS
-  "main"
+  "_main"
 
 ; One for mod_dav from socket library
-  "_swaps"
+;  "__swaps"
 
 ; And some more for mod_unique_id
-  "gethostname"
-  "gethostbyname"
-  "_swapl"
-  "h_errno"
-  "inet_ntoa"
+;  "_gethostname"
+;  "_gethostbyname"
+  "__swapl"
+;  "_h_errno"
+;  "_inet_ntoa"
 
 ; mod_proxy needs this one
-  "inet_addr"
+;  "_inet_addr"
diff -ur httpd-2.4.35-o/os/os2/core.mk httpd-2.4.35/os/os2/core.mk
--- httpd-2.4.35-o/os/os2/core.mk	2009-08-26 18:26:12.000000000 +0930
+++ httpd-2.4.35/os/os2/core.mk	2018-10-14 16:08:34.000000000 +1030
@@ -1,7 +1,8 @@
 # Some rules for making a shared core dll on OS/2
 
 os2core: httpd.dll $(CORE_IMPLIB)
-	$(LIBTOOL) --mode=link gcc -Zstack 512 $(LDFLAGS) $(EXTRA_LDFLAGS) -o httpd $(CORE_IMPLIB)
+	$(LIBTOOL) --mode=link gcc -Zstack 2048 $(LDFLAGS) $(EXTRA_LDFLAGS) -o httpx $(CORE_IMPLIB) -lssl -lcrypto -lz -lcx
+	cp -p httpx.exe httpd.exe
 
 httpd.dll: $(PROGRAM_DEPENDENCIES) $(CORE_IMPLIB)
-	$(LINK) -Zdll $(EXTRA_LDFLAGS) -s -o $@ server/exports.lo modules.lo $(PROGRAM_DEPENDENCIES) $(AP_LIBS) server/ApacheCoreOS2.def
+	$(LINK) -Zdll -Zomf $(EXTRA_LDFLAGS) -o $@ buildmark.o server/exports.lo modules.lo $(PROGRAM_DEPENDENCIES) $(AP_LIBS) server/ApacheCoreOS2.def -lpcre -lcx
Only in httpd-2.4.35/os/os2: libos.la
Only in httpd-2.4.35/os/os2: Makefile
diff -ur httpd-2.4.35-o/os/os2/util_os2.c httpd-2.4.35/os/os2/util_os2.c
--- httpd-2.4.35-o/os/os2/util_os2.c	2009-08-26 18:26:12.000000000 +0930
+++ httpd-2.4.35/os/os2/util_os2.c	2018-10-09 11:41:24.000000000 +1030
@@ -16,6 +16,9 @@
 
 #define INCL_DOS
 #define INCL_DOSERRORS
+#ifdef __KLIBC__
+#include <os2safe.h>
+#endif
 #include <os2.h>
 #include "ap_config.h"
 #include "httpd.h"
@@ -27,7 +30,6 @@
 #include <string.h>
 #include "apr_strings.h"
 
-
 AP_DECLARE(apr_status_t) ap_os_create_privileged_process(
     const request_rec *r,
     apr_proc_t *newproc, const char *progname,
@@ -37,3 +39,4 @@
 {
     return apr_proc_create(newproc, progname, args, env, attr, p);
 }
+
Only in httpd-2.4.35/os/os2: util_os2.lo
Only in httpd-2.4.35/os/os2: util_os2.o
Only in httpd-2.4.35: patch.log
Only in httpd-2.4.35/server: .deps
Only in httpd-2.4.35/server: .libs
Only in httpd-2.4.35/server: ApacheCoreOS2.def
Only in httpd-2.4.35/server: ApacheCoreOS2.la
diff -ur httpd-2.4.35-o/server/config.c httpd-2.4.35/server/config.c
--- httpd-2.4.35-o/server/config.c	2018-06-01 00:40:26.000000000 +0930
+++ httpd-2.4.35/server/config.c	2018-10-09 11:41:24.000000000 +1030
@@ -117,6 +117,7 @@
                                     const char * const *aszSucc,
                                     int nOrder)
 {
+printf("entered ap_hook_post_config\n");
     ap_LINK_post_config_t *pHook;
 
     if (!_hooks.link_post_config) {
@@ -134,6 +135,7 @@
 
     if (apr_hook_debug_enabled)
         apr_hook_debug_show("post_config", aszPre, aszSucc);
+printf("leaving ap_hook_post_config\n");
 }
 
 AP_DECLARE(apr_array_header_t *) ap_hook_get_post_config(void)
Only in httpd-2.4.35/server: config.lo
Only in httpd-2.4.35/server: config.o
Only in httpd-2.4.35/server: connection.lo
Only in httpd-2.4.35/server: connection.o
Only in httpd-2.4.35/server: core_filters.lo
Only in httpd-2.4.35/server: core_filters.o
diff -ur httpd-2.4.35-o/server/core.c httpd-2.4.35/server/core.c
--- httpd-2.4.35-o/server/core.c	2018-08-15 06:33:42.000000000 +0930
+++ httpd-2.4.35/server/core.c	2018-10-09 11:41:24.000000000 +1030
@@ -52,7 +52,7 @@
 
 #include "mod_so.h" /* for ap_find_loaded_module_symbol */
 
-#if defined(RLIMIT_CPU) || defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS) || defined (RLIMIT_NPROC)
+#if (defined(RLIMIT_CPU) || defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS) || defined (RLIMIT_NPROC)) && !defined(__OS2__)
 #include "unixd.h"
 #endif
 #if APR_HAVE_UNISTD_H
@@ -3729,7 +3729,7 @@
     return (apr_size_t)conf->limit_xml_body;
 }
 
-#if !defined (RLIMIT_CPU) || !(defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)) || !defined (RLIMIT_NPROC)
+#if !defined (RLIMIT_CPU) || !(defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)) || !defined (RLIMIT_NPROC) || defined (OS2)
 static const char *no_set_limit(cmd_parms *cmd, void *conf_,
                                 const char *arg, const char *arg2)
 {
@@ -3740,7 +3740,7 @@
 }
 #endif
 
-#ifdef RLIMIT_CPU
+#if defined(RLIMIT_CPU) && !defined(OS2)
 static const char *set_limit_cpu(cmd_parms *cmd, void *conf_,
                                  const char *arg, const char *arg2)
 {
@@ -3751,7 +3751,7 @@
 }
 #endif
 
-#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)
+#if (defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)) && !defined(OS2)
 static const char *set_limit_mem(cmd_parms *cmd, void *conf_,
                                  const char *arg, const char * arg2)
 {
@@ -3769,7 +3769,7 @@
 }
 #endif
 
-#ifdef RLIMIT_NPROC
+#if defined(RLIMIT_NPROC) && !defined(OS2)
 static const char *set_limit_nproc(cmd_parms *cmd, void *conf_,
                                    const char *arg, const char * arg2)
 {
@@ -4460,7 +4460,7 @@
               "Maximum number of reversals in Ranges in a request before returning the entire "
               "resource, or 0 for unlimited"),
 /* System Resource Controls */
-#ifdef RLIMIT_CPU
+#if defined(RLIMIT_CPU) && !defined(OS2)
 AP_INIT_TAKE12("RLimitCPU", set_limit_cpu,
   (void*)APR_OFFSETOF(core_dir_config, limit_cpu),
   OR_ALL, "Soft/hard limits for max CPU usage in seconds"),
@@ -4468,7 +4468,7 @@
 AP_INIT_TAKE12("RLimitCPU", no_set_limit, NULL,
   OR_ALL, "Soft/hard limits for max CPU usage in seconds"),
 #endif
-#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined (RLIMIT_AS)
+#if (defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined (RLIMIT_AS)) && !defined(OS2)
 AP_INIT_TAKE12("RLimitMEM", set_limit_mem,
   (void*)APR_OFFSETOF(core_dir_config, limit_mem),
   OR_ALL, "Soft/hard limits for max memory usage per process"),
@@ -4476,7 +4476,7 @@
 AP_INIT_TAKE12("RLimitMEM", no_set_limit, NULL,
   OR_ALL, "Soft/hard limits for max memory usage per process"),
 #endif
-#ifdef RLIMIT_NPROC
+#if defined(RLIMIT_NPROC) && !defined(OS2)
 AP_INIT_TAKE12("RLimitNPROC", set_limit_nproc,
   (void*)APR_OFFSETOF(core_dir_config, limit_nproc),
   OR_ALL, "soft/hard limits for max number of processes per uid"),
Only in httpd-2.4.35/server: core.c.orig
Only in httpd-2.4.35/server: core.lo
Only in httpd-2.4.35/server: core.o
Only in httpd-2.4.35/server: eoc_bucket.lo
Only in httpd-2.4.35/server: eoc_bucket.o
Only in httpd-2.4.35/server: eor_bucket.lo
Only in httpd-2.4.35/server: eor_bucket.o
Only in httpd-2.4.35/server: error_bucket.lo
Only in httpd-2.4.35/server: error_bucket.o
Only in httpd-2.4.35/server: export_files
Only in httpd-2.4.35/server: export_vars.h
Only in httpd-2.4.35/server: exports.c
Only in httpd-2.4.35/server: exports.lo
Only in httpd-2.4.35/server: exports.o
Only in httpd-2.4.35/server: gen_test_char
Only in httpd-2.4.35/server: gen_test_char.exe
Only in httpd-2.4.35/server: gen_test_char.lo
Only in httpd-2.4.35/server: gen_test_char.map
Only in httpd-2.4.35/server: gen_test_char.o
Only in httpd-2.4.35/server: httpd.exp
Only in httpd-2.4.35/server: libmain.la
Only in httpd-2.4.35/server: listen.lo
Only in httpd-2.4.35/server: listen.o
Only in httpd-2.4.35/server: log.lo
Only in httpd-2.4.35/server: log.o
diff -ur httpd-2.4.35-o/server/main.c httpd-2.4.35/server/main.c
--- httpd-2.4.35-o/server/main.c	2018-07-06 04:56:56.000000000 +0930
+++ httpd-2.4.35/server/main.c	2018-10-12 19:11:20.000000000 +1030
@@ -45,6 +45,15 @@
 #include <unistd.h>
 #endif
 
+#ifdef __OS2__x
+#define INCL_LOADEXCEPTQ
+// 2013-03-24 SHL
+#define INCL_DOSEXCEPTIONS
+#define INCL_DOSPROCESS
+#include <os2.h>
+#include "exceptq.h"
+#endif
+
 /* WARNING: Win32 binds http_main.c dynamically to the server. Please place
  *          extern functions and global data in another appropriate module.
  *
@@ -463,8 +472,48 @@
     destroy_and_exit_process(process, 1);
 }
 
+// 2013-03-24 SHL FIXME to be gone
+#ifdef __OS2__
+
+// #define CHECK_EXCEPTION_CHAIN
+
+#ifdef CHECK_EXCEPTION_CHAIN
+
+/**
+ * Check exception handler chain validity
+ * @param pRegRec points to EXCEPTIONREGISTRATIONRECORD or NULL
+ * @return 1 if OK else 0
+ * @note Sprinkle calls to this function in worker_main()
+ */
+
+static int IsExceptionHandlerChainOK(void)
+{
+  PTIB ptib;
+  PPIB ppib;
+  EXCEPTIONREGISTRATIONRECORD *pRegRec;
+  DosGetInfoBlocks(&ptib, &ppib);
+
+  pRegRec = ptib->tib_pexchain;         // Check full chain
+
+  for (;;) {
+    pRegRec = pRegRec->prev_structure;
+    if (pRegRec == END_OF_CHAIN)
+      return 1;                 // OK = end of chain
+    if ((PVOID)pRegRec < ptib->tib_pstack)
+      return 0;                 // Oops
+    if ((PVOID)pRegRec >= ptib->tib_pstacklimit)
+      return 0;                 // Oops
+  } // for
+}
+#endif
+
+#endif // __OS2__
+
 int main(int argc, const char * const argv[])
 {
+#ifdef __OS2__
+    EXCEPTIONREGISTRATIONRECORD exRegRec;
+#endif
     char c;
     int showcompile = 0, showdirectives = 0;
     const char *confname = SERVER_CONFIG_FILE;
@@ -484,6 +533,9 @@
     int rc = OK;
 
     AP_MONCONTROL(0); /* turn off profiling of startup */
+#ifdef __OS2__x
+    LoadExceptq(&exRegRec, "I", "Apache2");
+#endif
 
     process = init_process(&argc, &argv);
     ap_pglobal = process->pool;
@@ -831,6 +883,17 @@
     }
     destroy_and_exit_process(process, rc);
 
+#ifdef __OS2__
+#ifdef CHECK_EXCEPTION_CHAIN // 2013-03-27 SHL
+    // 2013-03-24 SHL
+    if (!IsExceptionHandlerChainOK())
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+                     "exception chain corrupted in main at #0");
+#endif
+
+//    UninstallExceptq(&exRegRec);
+#endif
+
     /* NOTREACHED */
     return !OK;
 }
Only in httpd-2.4.35/server: main.c.orig
Only in httpd-2.4.35/server: main.lo
Only in httpd-2.4.35/server: main.o
Only in httpd-2.4.35/server/mpm: .deps
Only in httpd-2.4.35/server/mpm/mpmt_os2: .deps
Only in httpd-2.4.35/server/mpm/mpmt_os2: .libs
Only in httpd-2.4.35/server/mpm/mpmt_os2: libmpmt_os2.la
Only in httpd-2.4.35/server/mpm/mpmt_os2: modules.mk
diff -ur httpd-2.4.35-o/server/mpm/mpmt_os2/mpmt_os2_child.c httpd-2.4.35/server/mpm/mpmt_os2/mpmt_os2_child.c
--- httpd-2.4.35-o/server/mpm/mpmt_os2/mpmt_os2_child.c	2011-12-05 10:38:00.000000000 +1030
+++ httpd-2.4.35/server/mpm/mpmt_os2/mpmt_os2_child.c	2018-10-12 19:11:32.000000000 +1030
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+//#define USE_EXCEPTQ
+// #define CHECK_EXCEPTION_CHAIN
+
 #define INCL_NOPMAPI
 #define INCL_DOS
 #define INCL_DOSERRORS
@@ -33,9 +36,16 @@
 #include "apr_poll.h"
 #include "mpm_common.h"
 #include "apr_strings.h"
+#ifdef __KLIBC__
+#include <os2safe.h>
+#endif
 #include <os2.h>
 #include <process.h>
 
+#ifdef USE_EXCEPTQ
+#include "exceptq.h"
+#endif
+
 APLOG_USE_MODULE(mpm_mpmt_os2);
 
 /* XXXXXX move these to header file private to this MPM */
@@ -72,12 +82,17 @@
 extern int ap_min_spare_threads;
 extern int ap_max_spare_threads;
 extern HMTX ap_mpm_accept_mutex;
+extern int ap_thread_stack_size;
 
-static void worker_main(void *vpArg);
+// 2013-03-29 SHL was static - better for debug this way
+void worker_main(void *vpArg);
 static void clean_child_exit(int code);
 static void set_signals();
-static void server_maintenance(void *vpArg);
-
+// 2013-03-29 SHL was static - better for debug this way
+void server_maintenance(void *vpArg);
+#ifdef CHECK_EXCEPTION_CHAIN // 2013-03-27 SHL
+static int IsExceptionHandlerChainOK(void);
+#endif
 
 static void clean_child_exit(int code)
 {
@@ -88,7 +103,9 @@
     exit(code);
 }
 
-
+/**
+ * Initialize MPM data structures and loop accepting connection requests
+ */
 
 void ap_mpm_child_main(apr_pool_t *pconf)
 {
@@ -167,10 +184,12 @@
         clean_child_exit(APEXIT_CHILDFATAL);
     }
 
+#if 0 // 2013-03-24 SHL Moved to add_worker by Paul way back when
     /* Create initial pool of worker threads */
     for (c = 0; c < ap_min_spare_threads; c++) {
-//        ap_scoreboard_image->servers[child_slot][c].tid = _beginthread(worker_main, NULL, 128*1024, (void *)c);
+        ap_scoreboard_image->servers[child_slot][c].tid = _beginthread(worker_main, NULL, 128*1024, (void *)c);
     }
+#endif
 
     /* Start maintenance thread */
     server_maint_tid = _beginthread(server_maintenance, NULL, 32768, NULL);
@@ -197,7 +216,7 @@
         apr_pool_t *pconn;
         worker_args_t *worker_args;
         int last_poll_idx = 0;
-
+    apr_socket_t *csd;
         apr_pool_create(&pconn, pchild);
         worker_args = apr_palloc(pconn, sizeof(worker_args_t));
         worker_args->pconn = pconn;
@@ -211,7 +230,7 @@
             rc = DosRequestMutexSem(ap_mpm_accept_mutex, SEM_INDEFINITE_WAIT);
 
             if (shutdown_pending) {
-                DosReleaseMutexSem(ap_mpm_accept_mutex);
+                rc = DosReleaseMutexSem(ap_mpm_accept_mutex);
                 break;
             }
 
@@ -219,7 +238,7 @@
 
             if (rv == APR_SUCCESS) {
                 rv = apr_pollset_poll(pollset, -1, &num_poll_results, &poll_results);
-                DosReleaseMutexSem(ap_mpm_accept_mutex);
+                rc = DosReleaseMutexSem(ap_mpm_accept_mutex);
             }
 
             if (rv == APR_SUCCESS) {
@@ -233,6 +252,7 @@
             }
         }
 
+#if 0
         if (rv != APR_SUCCESS) {
             if (!APR_STATUS_IS_EINTR(rv)) {
                 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(00194)
@@ -240,6 +260,34 @@
                 clean_child_exit(APEXIT_CHILDFATAL);
             }
         } else {
+#else
+       if (rv != APR_SUCCESS) {
+            if (APR_STATUS_IS_EAGAIN(rv)) {
+                // 2013-03-26 SHL
+                ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, ap_server_conf,
+                             "apr_socket_accept");
+                apr_sleep(5 * 1000L);
+            }
+            else if (!APR_STATUS_IS_EINTR(rv)) {
+                // 2013-03-24 SHL
+                if (rc == ERROR_SEM_OWNER_DIED) {
+                    PID   pidSemaphoreOwner;
+                    TID   tidSemaphoreOwner;
+                    ULONG ulRequestCount;
+                    rc = DosQueryMutexSem(ap_mpm_accept_mutex,
+                                          &pidSemaphoreOwner,
+                                          &tidSemaphoreOwner,
+                                          &ulRequestCount);
+                  ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc),
+                               ap_server_conf, "Sem owner died pidSemaphoreOwner = %d, tidSemaphoreOwner = %d, ulRequestCount = %ul rc = %ul at ap_mpm_child_main #0",
+                               pidSemaphoreOwner, tidSemaphoreOwner, ulRequestCount, rc);
+                }
+                ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
+                             "apr_socket_accept");
+                clean_child_exit(APEXIT_CHILDFATAL);
+            }
+        } else {
+#endif
             DosWriteQueue(workq, WORKTYPE_CONN, sizeof(worker_args_t), worker_args, 0);
             requests_this_child++;
         }
@@ -287,7 +335,6 @@
 }
 
 
-
 void add_worker()
 {
     int thread_slot;
@@ -298,7 +345,7 @@
         if (ap_scoreboard_image->servers[child_slot][thread_slot].status == SERVER_DEAD) {
             ap_scoreboard_image->servers[child_slot][thread_slot].status = SERVER_STARTING;
             ap_scoreboard_image->servers[child_slot][thread_slot].tid =
-                _beginthread(worker_main, NULL, stacksize, (void *)thread_slot);
+                _beginthread(worker_main, NULL, ap_thread_stack_size, (void *)thread_slot);
             break;
         }
     }
@@ -312,11 +359,54 @@
                                         PVOID p)
 {
     int c;
+    APIRET apiret;
+    HMODULE hmod;
+
+#ifdef CHECK_EXCEPTION_CHAIN // 2013-03-27 SHL
+    if (!IsExceptionHandlerChainOK())
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                     "exception chain corrupted in thread_exception_handler at #0");
+#endif
 
     if (pReportRec->fHandlerFlags & EH_NESTED_CALL) {
         return XCPT_CONTINUE_SEARCH;
     }
 
+    // 2013-03-18 SHL
+    // Bypass exceptions we don't handle or exceptions we ignore
+    // Keep in sync with exceptq selections since exceptq will ignore anyway
+    if ((pReportRec->ExceptionNum  & XCPT_SEVERITY_CODE) != XCPT_FATAL_EXCEPTION ||
+        pReportRec->ExceptionNum  == XCPT_ASYNC_PROCESS_TERMINATE ||
+        pReportRec->ExceptionNum  == XCPT_PROCESS_TERMINATE ||
+        pReportRec->ExceptionNum  == XCPT_UNWIND ||
+        pReportRec->ExceptionNum  == XCPT_SIGNAL ||
+        pReportRec->ExceptionNum  == XCPT_BREAKPOINT ||
+        pReportRec->ExceptionNum  == XCPT_SINGLE_STEP)
+    {
+        return XCPT_CONTINUE_SEARCH;
+    }
+
+    if (pReportRec->ExceptionNum == XCPT_ACCESS_VIOLATION) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                     "caught exception (XCPT_ACCESS_VIOLATION) in worker thread, initiating child shutdown pid=%d tid=%d",
+                     getpid(),
+                     _gettid());
+
+    }
+    else if (pReportRec->ExceptionNum == XCPT_INTEGER_DIVIDE_BY_ZERO) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                     "caught exception (XCPT_INTEGER_DIVIDE_BY_ZERO) in worker thread, initiating child shutdown pid=%d, tid=%d",
+                     getpid(),
+                     _gettid());
+    }
+    else {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                     "Unknown OS/2 exception (%lx) in worker thread, initiating child shutdown pid=%d, tid=%d",
+                     pReportRec->ExceptionNum,
+                     getpid(),
+                     _gettid());
+    }
+
     if (pReportRec->ExceptionNum == XCPT_ACCESS_VIOLATION ||
         pReportRec->ExceptionNum == XCPT_INTEGER_DIVIDE_BY_ZERO) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(00195)
@@ -326,21 +416,65 @@
                 ap_scoreboard_image->servers[child_slot][c].status = SERVER_DEAD;
                 break;
             }
-        }
+        } // for
 
+#if 0 /* allow exceptq to process all exceptions */
         /* Shut down process ASAP, it could be quite unhealthy & leaking resources */
         shutdown_pending = 1;
         ap_scoreboard_image->parent[child_slot].quiescing = 1;
         kill(getpid(), SIGHUP);
         DosUnwindException(UNWIND_ALL, 0, 0);
+#endif
+    } // if fatal
+
+#if 1 // FIXME to be gone - this handler only invoked is USE_EXCEPTQ not defined
+    apiret = DosLoadModule (0, 0, "exceptq" ,&hmod);
+    if (apiret) {
+        // Silently ignore if not in LIBPATH
+        if (apiret != ERROR_FILE_NOT_FOUND)
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                         "DosLoadModule(exceptq) reported error %u", apiret);
+    }
+    else {
+        ERR pfn;
+        apiret = DosQueryProcAddr(hmod, 0, "MYHANDLER", (PFN*)&pfn);
+        if (apiret)
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                         "DosQueryProcAddr(MYHANDLER) reported error %u", apiret);
+        else {
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                         "Invoking exceptq handler");
+            (*pfn)(pReportRec, pRegRec, pContext, p);
+        }
+        DosFreeModule(hmod);
     }
 
+    /* Shut down process ASAP, it could be quite unhealthy & leaking resources */
+    shutdown_pending = 1;
+    ap_scoreboard_image->parent[child_slot].quiescing = 1;
+
+    kill(getpid(), SIGHUP);
+
+#ifdef CHECK_EXCEPTION_CHAIN // 2013-03-27 SHL
+    if (!IsExceptionHandlerChainOK())
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                     "exception chain corrupted in thread_exception_handler at #2");
+#endif
+
+    DosUnwindException(UNWIND_ALL, 0, 0);
+
+#ifdef CHECK_EXCEPTION_CHAIN // 2013-03-27 SHL
+    if (!IsExceptionHandlerChainOK())
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                     "exception chain corrupted in thread_exception_handler at #3");
+#endif
+#endif // USE_EXCEPTQ
     return XCPT_CONTINUE_SEARCH;
 }
 
 
-
-static void worker_main(void *vpArg)
+// 2013-03-28 SHL was static - better for debug this way
+void worker_main(void *vpArg)
 {
     apr_thread_t *thd = NULL;
     apr_os_thread_t osthd;
@@ -357,11 +491,19 @@
     ULONG len;
     BYTE priority;
     int thread_slot = (int)vpArg;
+#ifndef USE_EXCEPTQ
     EXCEPTIONREGISTRATIONRECORD reg_rec = { NULL, thread_exception_handler };
+#else
+    EXCEPTIONREGISTRATIONRECORD exRegRec;
+#endif
     ap_sb_handle_t *sbh;
 
+#ifndef USE_EXCEPTQ
     /* Trap exceptions in this thread so we don't take down the whole process */
     DosSetExceptionHandler( &reg_rec );
+#else
+    LoadExceptq(&exRegRec, "I", "Apache2");
+#endif
 
     osthd = apr_os_thread_current();
     apr_os_thread_put(&thd, &osthd, pchild);
@@ -384,13 +526,20 @@
     bucket_alloc = apr_bucket_alloc_create_ex(allocator);
 
     while (rc = DosReadQueue(workq, &rd, &len, (PPVOID)&worker_args, 0, DCWW_WAIT, &priority, NULLHANDLE),
-           rc == 0 && rd.ulData != WORKTYPE_EXIT) {
+           rc == 0 && rd.ulData != WORKTYPE_EXIT)
+    {
         pconn = worker_args->pconn;
         ap_create_sb_handle(&sbh, pconn, child_slot, thread_slot);
         current_conn = ap_run_create_connection(pconn, ap_server_conf,
                                                 worker_args->conn_sd, conn_id,
                                                 sbh, bucket_alloc);
 
+#ifdef CHECK_EXCEPTION_CHAIN // 2013-03-27 SHL
+      if (!IsExceptionHandlerChainOK())
+          ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                       "exception chain corrupted in worker_main at #5");
+#endif
+
         if (current_conn) {
             current_conn->current_thread = thd;
             ap_process_connection(current_conn, worker_args->conn_sd);
@@ -400,18 +549,52 @@
         apr_pool_destroy(pconn);
         ap_update_child_status_from_indexes(child_slot, thread_slot,
                                             SERVER_READY, NULL);
-    }
+    } // while
+
+#ifdef CHECK_EXCEPTION_CHAIN // 2013-03-27 SHL
+    if (!IsExceptionHandlerChainOK())
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                     "exception chain corrupted in worker_main at #7");
+#endif
 
     ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_DEAD,
                                         NULL);
 
     apr_bucket_alloc_destroy(bucket_alloc);
+
     apr_allocator_destroy(allocator);
-}
 
+#ifdef CHECK_EXCEPTION_CHAIN // 2013-03-27 SHL
+    if (!IsExceptionHandlerChainOK())
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                     "exception chain corrupted in worker_main at #10");
+#endif
 
+// 2013-03-24 SHL
+#ifndef USE_EXCEPTQ
+    DosUnsetExceptionHandler(&reg_rec);
+#else
+    UninstallExceptq(&exRegRec);
+#endif
 
-static void server_maintenance(void *vpArg)
+#ifdef CHECK_EXCEPTION_CHAIN // 2013-03-27 SHL
+    if (!IsExceptionHandlerChainOK())
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
+                     "exception chain corrupted in worker_main at #11");
+#endif
+
+#ifdef CHECK_EXCEPTION_CHAIN // 2013-03-27 SHL
+    // 2013-03-24 SHL for Dave
+    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
+                     "thread 0x%x ending",
+                     ap_scoreboard_image->servers[child_slot][thread_slot].tid);
+#endif
+
+}
+
+
+// 2013-03-28 SHL was static - better for debug
+void server_maintenance(void *vpArg)
 {
     int num_idle, num_needed;
     ULONG num_pending = 0;
@@ -450,7 +633,6 @@
 }
 
 
-
 /* Signal handling routines */
 
 static void sig_term(int sig)
@@ -461,7 +643,6 @@
 }
 
 
-
 static void sig_hup(int sig)
 {
     shutdown_pending = 1;
@@ -469,7 +650,6 @@
 }
 
 
-
 static void set_signals()
 {
     struct sigaction sa;
@@ -486,3 +666,34 @@
     if (sigaction(SIGHUP, &sa, NULL) < 0)
         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00199) "sigaction(SIGHUP)");
 }
+
+/**
+ * Check exception handler chain validity
+ * @param pRegRec points to EXCEPTIONREGISTRATIONRECORD or NULL
+ * @return 1 if OK else 0
+ * @note Sprinkle calls to this function in worker_main()
+ */
+
+#ifdef CHECK_EXCEPTION_CHAIN // 2013-03-27 SHL
+int IsExceptionHandlerChainOK(void)
+{
+  PTIB ptib;
+  PPIB ppib;
+  EXCEPTIONREGISTRATIONRECORD *pRegRec;
+
+  DosGetInfoBlocks(&ptib, &ppib);
+
+  pRegRec = ptib->tib_pexchain;
+
+  for (;;) {
+    pRegRec = pRegRec->prev_structure;
+    if (pRegRec == END_OF_CHAIN)
+      return 1;                 // OK = end of chain
+    if ((PVOID)pRegRec < ptib->tib_pstack)
+      return 0;                 // Oops
+    if ((PVOID)pRegRec >= ptib->tib_pstacklimit)
+      return 0;                 // Oops
+  } // for
+}
+#endif
+
Only in httpd-2.4.35/server/mpm/mpmt_os2: mpmt_os2_child.lo
Only in httpd-2.4.35/server/mpm/mpmt_os2: mpmt_os2_child.o
diff -ur httpd-2.4.35-o/server/mpm/mpmt_os2/mpmt_os2.c httpd-2.4.35/server/mpm/mpmt_os2/mpmt_os2.c
--- httpd-2.4.35-o/server/mpm/mpmt_os2/mpmt_os2.c	2016-04-01 22:56:04.000000000 +1030
+++ httpd-2.4.35/server/mpm/mpmt_os2/mpmt_os2.c	2018-10-09 11:41:24.000000000 +1030
@@ -39,7 +39,6 @@
 #define INCL_NOPMAPI
 #define INCL_DOS
 #define INCL_DOSERRORS
-
 #include "ap_config.h"
 #include "httpd.h"
 #include "mpm_default.h"
@@ -54,6 +53,9 @@
 #include "mpm_common.h"
 #include "scoreboard.h"
 #include "apr_strings.h"
+#ifdef __KLIBC__
+#include <os2safe.h>
+#endif
 #include <os2.h>
 #include <process.h>
 
@@ -68,6 +70,8 @@
 #define HARD_THREAD_LIMIT 256
 #endif
 
+#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
+
 server_rec *ap_server_conf;
 static apr_pool_t *pconf = NULL;  /* Pool for config stuff */
 
@@ -77,6 +81,7 @@
 static int ap_thread_limit = 0;
 int ap_min_spare_threads = 0;
 int ap_max_spare_threads = 0;
+int ap_thread_stack_size = 128 * 1024;
 
 /* Keep track of a few interesting statistics */
 int ap_max_daemons_limit = -1;
@@ -116,8 +121,21 @@
     pconf = _pconf;
     ap_server_conf = s;
     restart_pending = 0;
+    ULONG    CurMaxFH      = 0;          /* Current count of handles         */
+    LONG     ReqCount      = 0;          /* Number to adjust file handles    */
+    PID   pidSemaphoreOwner;   /* will get PID of sem owner */
+    TID   tidSemaphoreOwner;   /* will get TID of sem owner */
+    ULONG ulRequestCount;      /* will get the request count for the sem */
+
+    // DosSetMaxFH(ap_thread_limit * 2);
+
+    rc = DosSetRelMaxFH(&ReqCount,     /* Using 0 here will return the       */
+                        &CurMaxFH);    /* current number of file handles     */
+
+    ReqCount = ap_thread_limit * 2;
+
+    rc = DosSetRelMaxFH(&ReqCount,&CurMaxFH);     /* Change handle maximum */
 
-    DosSetMaxFH(ap_thread_limit * 2);
     listener_shm_name = apr_psprintf(pconf, "/sharemem/httpd/parent_info.%d", getppid());
     rc = DosGetNamedSharedMem((PPVOID)&parent_info, listener_shm_name, PAG_READ);
     is_parent_process = rc != 0;
@@ -136,6 +154,7 @@
             ap_listeners = lr;
             apr_sockaddr_info_get(&lr->bind_addr, "0.0.0.0", APR_UNSPEC,
                                   DEFAULT_HTTP_PORT, 0, s->process->pool);
+
             apr_socket_create(&lr->sd, lr->bind_addr->family,
                               SOCK_STREAM, 0, s->process->pool);
         }
@@ -156,10 +175,15 @@
         return DONE;
     }
     else {
-        /* Parent process */
+        /* Parent process or DosGetNamedSharedMem problem */
         int rc;
         is_parent_process = TRUE;
 
+        // 2013-03-24 SHL
+        if (rc != ERROR_FILE_NOT_FOUND)
+            ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), s,
+                         "DosGetNamedSharedMem returned %d", rc);
+
         if (ap_setup_listeners(ap_server_conf) < 1) {
             ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s, APLOGNO(00200)
                          "no listening sockets available, shutting down");
@@ -174,6 +198,25 @@
 
         if (rc != OK) {
             ap_remove_pid(pconf, ap_pid_fname);
+            rc = DosQueryMutexSem(ap_mpm_accept_mutex,
+                                  &pidSemaphoreOwner,
+                                  &tidSemaphoreOwner,
+                                  &ulRequestCount);
+            // 2013-03-24 SHL was APLOG_INFO
+            if (rc == 0)
+                ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS,
+                             ap_server_conf, "pidSemaphoreOwner = %d, tidSemaphoreOwner = %d, ulRequestCount = %ul",
+                             pidSemaphoreOwner, tidSemaphoreOwner, ulRequestCount);
+
+            // 2013-03-24 SHL
+            else if (rc == ERROR_SEM_OWNER_DIED)
+                ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc),
+                             ap_server_conf, "Sem owner died pidSemaphoreOwner = %d, tidSemaphoreOwner = %d, ulRequestCount = %ul",
+                             pidSemaphoreOwner, tidSemaphoreOwner, ulRequestCount);
+            else
+                ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), s,
+                             "DosQueryMutexSem returned %d", rc);
+
             ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00201)
                          "caught %s, shutting down",
                          (rc == DONE) ? "SIGTERM" : "error");
@@ -315,8 +358,11 @@
 
     /* Signal children to shut down, either gracefully or immediately */
     for (slot=0; slot<HARD_SERVER_LIMIT; slot++) {
+
+    if (ap_scoreboard_image->parent[slot].pid!=0){
       kill(ap_scoreboard_image->parent[slot].pid, is_graceful ? SIGHUP : SIGTERM);
     }
+    }
 
     DosFreeMem(parent_info);
     return restart_pending ? OK : DONE;
@@ -583,10 +629,24 @@
     return NULL;
 }
 
+static const char *set_thread_stacksize(cmd_parms *cmd, void *dummy, 
+                                        const char *arg)
+{
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+    if (err != NULL) {
+        return err;
+    }
+
+    ap_thread_stack_size = atoi(arg);
+    return NULL;
+}
+
 
 
 static const command_rec mpmt_os2_cmds[] = {
 LISTEN_COMMANDS,
+AP_INIT_TAKE1("ThreadStackSize", set_thread_stacksize, NULL, RSRC_CONF,
+              "Stack size each created thread will use."),
 AP_INIT_TAKE1( "StartServers", set_daemons_to_start, NULL, RSRC_CONF,
   "Number of child processes launched at server startup" ),
 AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
@@ -604,7 +664,7 @@
 
 AP_DECLARE_MODULE(mpm_mpmt_os2) = {
     MPM20_MODULE_STUFF,
-    NULL,            /* hook to run before apache parses args */
+    ap_mpm_rewrite_args,            /* hook to run before apache parses args */
     NULL,            /* create per-directory config structure */
     NULL,            /* merge per-directory config structures */
     NULL,            /* create per-server config structure */
Only in httpd-2.4.35/server/mpm/mpmt_os2: mpmt_os2.lo
Only in httpd-2.4.35/server/mpm/mpmt_os2: mpmt_os2.o
Only in httpd-2.4.35/server/mpm/mpmt_os2: Makefile
Only in httpd-2.4.35/server/mpm: Makefile
Only in httpd-2.4.35/server: mpm_common.lo
Only in httpd-2.4.35/server: mpm_common.o
Only in httpd-2.4.35/server: mpm_fdqueue.lo
Only in httpd-2.4.35/server: mpm_fdqueue.o
diff -ur httpd-2.4.35-o/server/mpm_unix.c httpd-2.4.35/server/mpm_unix.c
--- httpd-2.4.35-o/server/mpm_unix.c	2018-01-11 08:18:04.000000000 +1030
+++ httpd-2.4.35/server/mpm_unix.c	2018-10-09 11:41:24.000000000 +1030
@@ -798,6 +798,7 @@
         status = "httpd (no pid file) not running";
     }
     else {
+#ifndef __OS2__
         /* With containerization, httpd may get the same PID at each startup,
          * handle it as if it were not running (it obviously can't).
          */
@@ -812,6 +813,7 @@
                                   "httpd (pid %" APR_PID_T_FMT "?) not running",
                                   otherpid);
         }
+#endif
     }
 
     if (!strcmp(dash_k_arg, "start") || dash_k_arg == dash_k_arg_noarg) {
Only in httpd-2.4.35/server: mpm_unix.lo
Only in httpd-2.4.35/server: mpm_unix.o
Only in httpd-2.4.35/server: Makefile
diff -ur httpd-2.4.35-o/server/Makefile.in httpd-2.4.35/server/Makefile.in
--- httpd-2.4.35-o/server/Makefile.in	2018-02-20 23:19:52.000000000 +1030
+++ httpd-2.4.35/server/Makefile.in	2018-10-09 11:41:24.000000000 +1030
@@ -74,8 +74,8 @@
 # Rule to make def file for OS/2 core dll
 ApacheCoreOS2.def: exports.c export_vars.h $(top_srcdir)/os/$(OS_DIR)/core_header.def
 	cat $(top_srcdir)/os/$(OS_DIR)/core_header.def > $@
-	$(CPP) $< $(ALL_CPPFLAGS) $(ALL_INCLUDES) | grep "ap_hack_" | sed -e 's/^.*[)]\(.*\);$$/  "\1"/' >> $@
-	$(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) export_vars.h | grep "^[a-z]" | sed -e 's/^\(.*\)$$/  "\1"/' >> $@
+	$(CPP) $< $(ALL_CPPFLAGS) $(ALL_INCLUDES) | grep "ap_hack_" | sed -e 's/^.*[)]\(.*\);$$/  "_\1"/' >> $@
+	$(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) export_vars.h | grep "^[a-z]" | sed -e 's/^\(.*\)$$/  "_\1"/' >> $@
 
 # Rule to make exp file for AIX DSOs
 httpd.exp: exports.c export_vars.h
Only in httpd-2.4.35/server: Makefile.in.orig
Only in httpd-2.4.35/server: protocol.lo
Only in httpd-2.4.35/server: protocol.o
Only in httpd-2.4.35/server: provider.lo
Only in httpd-2.4.35/server: provider.o
Only in httpd-2.4.35/server: request.lo
Only in httpd-2.4.35/server: request.o
Only in httpd-2.4.35/server: scoreboard.lo
Only in httpd-2.4.35/server: scoreboard.o
Only in httpd-2.4.35/server: test_char.h
Only in httpd-2.4.35/server: util_cfgtree.lo
Only in httpd-2.4.35/server: util_cfgtree.o
Only in httpd-2.4.35/server: util_charset.lo
Only in httpd-2.4.35/server: util_charset.o
Only in httpd-2.4.35/server: util_cookies.lo
Only in httpd-2.4.35/server: util_cookies.o
Only in httpd-2.4.35/server: util_debug.lo
Only in httpd-2.4.35/server: util_debug.o
Only in httpd-2.4.35/server: util_ebcdic.lo
Only in httpd-2.4.35/server: util_ebcdic.o
Only in httpd-2.4.35/server: util_expr_eval.lo
Only in httpd-2.4.35/server: util_expr_eval.o
Only in httpd-2.4.35/server: util_expr_parse.lo
Only in httpd-2.4.35/server: util_expr_parse.o
Only in httpd-2.4.35/server: util_expr_scan.lo
Only in httpd-2.4.35/server: util_expr_scan.o
Only in httpd-2.4.35/server: util_fcgi.lo
Only in httpd-2.4.35/server: util_fcgi.o
Only in httpd-2.4.35/server: util_filter.lo
Only in httpd-2.4.35/server: util_filter.o
Only in httpd-2.4.35/server: util_md5.lo
Only in httpd-2.4.35/server: util_md5.o
Only in httpd-2.4.35/server: util_mutex.lo
Only in httpd-2.4.35/server: util_mutex.o
Only in httpd-2.4.35/server: util_pcre.lo
Only in httpd-2.4.35/server: util_pcre.o
Only in httpd-2.4.35/server: util_regex.lo
Only in httpd-2.4.35/server: util_regex.o
diff -ur httpd-2.4.35-o/server/util_script.c httpd-2.4.35/server/util_script.c
--- httpd-2.4.35-o/server/util_script.c	2018-08-16 00:31:08.000000000 +0930
+++ httpd-2.4.35/server/util_script.c	2018-10-09 11:41:24.000000000 +1030
@@ -39,6 +39,9 @@
 
 #ifdef OS2
 #define INCL_DOS
+#ifdef __KLIBC__
+#include <os2safe.h>
+#endif
 #include <os2.h>
 #endif
 
Only in httpd-2.4.35/server: util_script.lo
Only in httpd-2.4.35/server: util_script.o
Only in httpd-2.4.35/server: util_time.lo
Only in httpd-2.4.35/server: util_time.o
Only in httpd-2.4.35/server: util_xml.lo
Only in httpd-2.4.35/server: util_xml.o
Only in httpd-2.4.35/server: util.lo
Only in httpd-2.4.35/server: util.o
Only in httpd-2.4.35/server: vhost.lo
Only in httpd-2.4.35/server: vhost.o
Only in httpd-2.4.35/srclib: .deps
Only in httpd-2.4.35/srclib: apr
Only in httpd-2.4.35/srclib: Makefile
Only in httpd-2.4.35/support: .deps
Only in httpd-2.4.35/support: ab
Only in httpd-2.4.35/support: ab.exe
Only in httpd-2.4.35/support: ab.lo
Only in httpd-2.4.35/support: ab.map
Only in httpd-2.4.35/support: ab.o
Only in httpd-2.4.35/support: apachectl
Only in httpd-2.4.35/support: apxs
Only in httpd-2.4.35/support: dbmmanage
Only in httpd-2.4.35/support: envvars-std
Only in httpd-2.4.35/support: htcacheclean
Only in httpd-2.4.35/support: htcacheclean.exe
Only in httpd-2.4.35/support: htcacheclean.lo
Only in httpd-2.4.35/support: htcacheclean.map
Only in httpd-2.4.35/support: htcacheclean.o
Only in httpd-2.4.35/support: htdbm
Only in httpd-2.4.35/support: htdbm.exe
Only in httpd-2.4.35/support: htdbm.lo
Only in httpd-2.4.35/support: htdbm.map
Only in httpd-2.4.35/support: htdbm.o
Only in httpd-2.4.35/support: htdigest
Only in httpd-2.4.35/support: htdigest.exe
Only in httpd-2.4.35/support: htdigest.lo
Only in httpd-2.4.35/support: htdigest.map
Only in httpd-2.4.35/support: htdigest.o
Only in httpd-2.4.35/support: htpasswd
diff -ur httpd-2.4.35-o/support/htpasswd.c httpd-2.4.35/support/htpasswd.c
--- httpd-2.4.35-o/support/htpasswd.c	2018-03-16 09:23:42.000000000 +1030
+++ httpd-2.4.35/support/htpasswd.c	2018-10-09 11:41:24.000000000 +1030
@@ -64,6 +64,16 @@
 #define unlink _unlink
 #endif
 
+#ifdef __OS2__
+#define INCL_LOADEXCEPTQ
+// 2013-03-24 SHL
+#define INCL_DOSEXCEPTIONS
+#define INCL_DOSPROCESS
+#include <os2safe.h>
+#include <os2.h>
+#include "exceptq.h"
+#endif
+
 #define APHTP_NEWFILE        1
 #define APHTP_NOFILE         2
 #define APHTP_DELUSER        4
@@ -278,6 +288,9 @@
  */
 int main(int argc, const char * const argv[])
 {
+#ifdef __OS2__
+    EXCEPTIONREGISTRATIONRECORD exRegRec;
+#endif
     apr_file_t *fpw = NULL;
     char line[MAX_STRING_LEN];
     char *pwfilename = NULL;
@@ -296,7 +309,12 @@
     apr_xlate_t *to_ascii;
 #endif
 
+#ifdef __OS2__
+    LoadExceptq(&exRegRec, "I", "htpasswd");
+#endif
+
     apr_app_initialize(&argc, &argv, NULL);
+
     atexit(terminate);
     apr_pool_create(&pool, NULL);
     apr_pool_abort_set(abort_on_oom, pool);
@@ -520,5 +538,8 @@
         exit(ERR_FILEPERM);
     }
     apr_file_close(ftemp);
+#ifdef __OS2__
+    UninstallExceptq(&exRegRec);
+#endif
     return 0;
 }
Only in httpd-2.4.35/support: htpasswd.c.orig
Only in httpd-2.4.35/support: htpasswd.exe
Only in httpd-2.4.35/support: htpasswd.lo
Only in httpd-2.4.35/support: htpasswd.map
Only in httpd-2.4.35/support: htpasswd.o
Only in httpd-2.4.35/support: httxt2dbm
Only in httpd-2.4.35/support: httxt2dbm.exe
Only in httpd-2.4.35/support: httxt2dbm.lo
Only in httpd-2.4.35/support: httxt2dbm.map
Only in httpd-2.4.35/support: httxt2dbm.o
Only in httpd-2.4.35/support: log_server_status
Only in httpd-2.4.35/support: logresolve
Only in httpd-2.4.35/support: logresolve.exe
Only in httpd-2.4.35/support: logresolve.lo
Only in httpd-2.4.35/support: logresolve.map
Only in httpd-2.4.35/support: logresolve.o
Only in httpd-2.4.35/support: logresolve.pl
Only in httpd-2.4.35/support: Makefile
Only in httpd-2.4.35/support: passwd_common.lo
Only in httpd-2.4.35/support: passwd_common.o
Only in httpd-2.4.35/support: phf_abuse_log.cgi
Only in httpd-2.4.35/support: rotatelogs
Only in httpd-2.4.35/support: rotatelogs.exe
Only in httpd-2.4.35/support: rotatelogs.lo
Only in httpd-2.4.35/support: rotatelogs.map
Only in httpd-2.4.35/support: rotatelogs.o
Only in httpd-2.4.35/support: split-logfile
Only in httpd-2.4.35/test: .deps
Only in httpd-2.4.35/test: Makefile
httpd-2.4.35.diff (82,724 bytes)   
apr-1.6.3.diff (122,307 bytes)   
Only in apr-1.6.3: .make.dirs
Only in apr-1.6.3: a.out
Only in apr-1.6.3: apr-1-config
Only in apr-1.6.3: apr.pc
Only in apr-1.6.3/atomic/unix: builtins.lo
Only in apr-1.6.3/atomic/unix: builtins.o
Only in apr-1.6.3/atomic/unix: ia32.lo
Only in apr-1.6.3/atomic/unix: ia32.o
Only in apr-1.6.3/atomic/unix: mutex.lo
Only in apr-1.6.3/atomic/unix: mutex.o
Only in apr-1.6.3/atomic/unix: ppc.lo
Only in apr-1.6.3/atomic/unix: ppc.o
Only in apr-1.6.3/atomic/unix: s390.lo
Only in apr-1.6.3/atomic/unix: s390.o
Only in apr-1.6.3/atomic/unix: solaris.lo
Only in apr-1.6.3/atomic/unix: solaris.o
diff -ur apr-1.6.3-o/build/aplibtool.c apr-1.6.3/build/aplibtool.c
--- apr-1.6.3-o/build/aplibtool.c	2011-10-16 07:56:14.000000000 +1030
+++ apr-1.6.3/build/aplibtool.c	2018-01-26 18:08:34.000000000 +1030
@@ -36,7 +36,11 @@
 #  define CC         "gcc"
 #  define GEN_EXPORTS "emxexp"
 #  define DEF2IMPLIB_CMD "emximp"
-#  define SHARE_SW   "-Zdll -Zmtd"
+#if 1
+#  define SHARE_SW   "-Zdll -Zmap -Zhigh-mem"
+#else
+#  define SHARE_SW   "-Zdll -Zmap"
+#endif
 #  define USE_OMF true
 #  define TRUNCATE_DLL_NAME
 #  define DYNAMIC_LIB_EXT "dll"
@@ -45,7 +49,7 @@
 #  if USE_OMF
      /* OMF is the native format under OS/2 */
 #    define STATIC_LIB_EXT "lib"
-#    define OBJECT_EXT     "obj"
+#    define OBJECT_EXT     "o"
 #    define LIBRARIAN      "emxomfar"
 #  else
      /* but the alternative, a.out, can fork() which is sometimes necessary */
@@ -262,7 +266,7 @@
     if (strcmp(ext, "la") == 0) {
         newarg = (char *)malloc(strlen(arg) + 10);
         strcpy(newarg, arg);
-        newarg[pathlen] = 0;
+        newarg[name - arg] = 0;
         strcat(newarg, ".libs/");
 
         if (strncmp(name, "lib", 3) == 0) {
@@ -353,7 +357,6 @@
           newarg = truncate_dll_name(newarg);
         }
 #endif
-
         cmd_data->arglist[cmd_data->num_args++] = newarg;
         cmd_data->output_name = newarg;
         return true;
Only in apr-1.6.3/build: aplibtool.exe
Only in apr-1.6.3/build: apr_rules.mk
Only in apr-1.6.3/build/pkg: pkginfo
Only in apr-1.6.3: build.log
Only in apr-1.6.3: conf.cmd
Only in apr-1.6.3: config.log
Only in apr-1.6.3: config.nice
Only in apr-1.6.3: config.status
diff -ur apr-1.6.3-o/configure.in apr-1.6.3/configure.in
--- apr-1.6.3-o/configure.in	2017-10-03 23:25:18.000000000 +1030
+++ apr-1.6.3/configure.in	2018-01-26 18:08:34.000000000 +1030
@@ -243,6 +243,23 @@
     echo "using aplibtool"
     LIBTOOL="$srcdir/build/aplibtool"
     gcc $CFLAGS $CPPFLAGS -o $LIBTOOL.exe $LIBTOOL.c
+    # Determine ECHO
+    # Test print first, because it will be a builtin if present.
+    if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+       test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+        ECHO='print -r --'
+    elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+        ECHO='printf %s\n'
+    else
+        # Use this function as a fallback that always works.
+        func_fallback_echo ()
+        {
+            eval 'cat <<_ACEOF
+$1
+_ACEOF'
+        }
+        ECHO='func_fallback_echo'
+    fi
     ;;
 *)
     if test "x$LTFLAGS" = "x"; then
Only in apr-1.6.3: configure.log
diff -ur apr-1.6.3-o/dso/os2/dso.c apr-1.6.3/dso/os2/dso.c
--- apr-1.6.3-o/dso/os2/dso.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/dso/os2/dso.c	2018-01-26 18:08:34.000000000 +1030
@@ -18,6 +18,7 @@
 #include "apr_strings.h"
 #include "apr_portable.h"
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #if APR_HAS_DSO
@@ -50,13 +51,23 @@
     (*res_handle)->load_error = APR_SUCCESS;
     (*res_handle)->failed_module = NULL;
 
-    if ((rc = DosLoadModule(failed_module, sizeof(failed_module), path, &handle)) != 0) {
+    rc = DosLoadModule(failed_module, sizeof(failed_module), path, &handle);
+
+   if ((rc != 0)&&(rc!=87)) {
         (*res_handle)->load_error = APR_FROM_OS_ERROR(rc);
         (*res_handle)->failed_module = apr_pstrdup(ctx, failed_module);
         return APR_FROM_OS_ERROR(rc);
     }
 
+   if (rc==87){
+        int rc2;
+        HMODULE handle2;
+        rc2=DosQueryModuleHandle(path,&handle2);
+        (*res_handle)->handle  = handle2;
+        }
+   if (rc==0) 
     (*res_handle)->handle  = handle;
+
     apr_pool_cleanup_register(ctx, *res_handle, dso_cleanup, apr_pool_cleanup_null);
     return APR_SUCCESS;
 }
@@ -80,7 +91,16 @@
     if (symname == NULL || ressym == NULL)
         return APR_ESYMNOTFOUND;
 
-    if ((rc = DosQueryProcAddr(handle->handle, 0, symname, &func)) != 0) {
+#if defined(__INNOTEK_LIBC__)
+    void *retval;
+    char *symbol = (char*)malloc(sizeof(char)*(strlen(symname)+2));
+    sprintf(symbol, "_%s", symname);
+    rc = DosQueryProcAddr(handle->handle, 0, symbol, &func);
+    free(symbol);
+#else
+    rc = DosQueryProcAddr(handle->handle, 0, symname, &func);
+#endif
+    if (rc != 0) {
         handle->load_error = APR_FROM_OS_ERROR(rc);
         return handle->load_error;
     }
Only in apr-1.6.3/dso/os2: dso.lo
Only in apr-1.6.3/dso/os2: dso.o
Only in apr-1.6.3/encoding: apr_escape.lo
Only in apr-1.6.3/encoding: apr_escape.o
Only in apr-1.6.3: env.cmd
Only in apr-1.6.3/file_io/os2: buffer.lo
Only in apr-1.6.3/file_io/os2: buffer.o
Only in apr-1.6.3/file_io/os2: copy.lo
Only in apr-1.6.3/file_io/os2: copy.o
Only in apr-1.6.3/file_io/os2: dir_make_recurse.lo
Only in apr-1.6.3/file_io/os2: dir_make_recurse.o
diff -ur apr-1.6.3-o/file_io/os2/dir.c apr-1.6.3/file_io/os2/dir.c
--- apr-1.6.3-o/file_io/os2/dir.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/file_io/os2/dir.c	2018-01-26 18:08:34.000000000 +1030
@@ -21,6 +21,16 @@
 #include "apr_portable.h"
 #include <string.h>
 
+#if ( defined(__INNOTEK_LIBCxx__) || defined(__WATCOMC__) )
+/* Paul - I didn't see F_OK defined in io.h so I add this incase - asking Bird
+ * says in fcntl.h or unistd.h
+ */
+#ifndef F_OK
+#define F_OK  0
+#endif
+#include <io.h>
+#endif
+
 static apr_status_t dir_cleanup(void *thedir)
 {
     apr_dir_t *dir = thedir;
@@ -46,6 +56,14 @@
     thedir->validentry = FALSE;
     *new = thedir;
     apr_pool_cleanup_register(pool, thedir, dir_cleanup, apr_pool_cleanup_null);
+    /* In testdir, a call to a non-existent directory and the expected return is
+     * APR_ENOENT. I am adding a quick access( ), which is supported by new gcc and
+     * Open Watcom. If the dir doesn' exist we bug-out with the correct error.
+     */
+#if ( defined(__INNOTEK_LIBC__) || defined(__WATCOMC__) )
+    if(access(dirname, F_OK) != 0) return APR_ENOENT;
+#endif
+
     return APR_SUCCESS;
 }
 
Only in apr-1.6.3/file_io/os2: dir.lo
Only in apr-1.6.3/file_io/os2: dir.o
Only in apr-1.6.3/file_io/os2: fileacc.lo
Only in apr-1.6.3/file_io/os2: fileacc.o
diff -ur apr-1.6.3-o/file_io/os2/filedup.c apr-1.6.3/file_io/os2/filedup.c
--- apr-1.6.3-o/file_io/os2/filedup.c	2013-10-04 00:05:18.000000000 +0930
+++ apr-1.6.3/file_io/os2/filedup.c	2018-01-26 18:08:34.000000000 +1030
@@ -51,6 +51,7 @@
     dup_file->flags = old_file->flags & ~APR_INHERIT;
     /* TODO - dup pipes correctly */
     dup_file->pipe = old_file->pipe;
+    dup_file->ungetchar = old_file->ungetchar;
 
     if (*new_file == NULL) {
         apr_pool_cleanup_register(dup_file->pool, dup_file, apr_file_cleanup,
Only in apr-1.6.3/file_io/os2: filedup.lo
Only in apr-1.6.3/file_io/os2: filedup.o
Only in apr-1.6.3/file_io/os2: filepath_util.lo
Only in apr-1.6.3/file_io/os2: filepath_util.o
Only in apr-1.6.3/file_io/os2: filepath.lo
Only in apr-1.6.3/file_io/os2: filepath.o
diff -ur apr-1.6.3-o/file_io/os2/filestat.c apr-1.6.3/file_io/os2/filestat.c
--- apr-1.6.3-o/file_io/os2/filestat.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/file_io/os2/filestat.c	2018-01-26 18:08:34.000000000 +1030
@@ -84,7 +84,123 @@
     return APR_FROM_OS_ERROR(rc);
 }
 
+#ifdef __KLIBC__
+static apr_filetype_e filetype_from_mode(mode_t mode)
+{
+    apr_filetype_e type;
+
+    switch (mode & S_IFMT) {
+    case S_IFREG:
+        type = APR_REG;  break;
+    case S_IFDIR:
+        type = APR_DIR;  break;
+    case S_IFLNK:
+        type = APR_LNK;  break;
+    case S_IFCHR:
+        type = APR_CHR;  break;
+    case S_IFBLK:
+        type = APR_BLK;  break;
+#if defined(S_IFFIFO)
+    case S_IFFIFO:
+        type = APR_PIPE; break;
+#endif
+#if !defined(BEOS) && defined(S_IFSOCK)
+    case S_IFSOCK:
+        type = APR_SOCK; break;
+#endif
+
+    default:
+	/* Work around missing S_IFxxx values above
+         * for Linux et al.
+         */
+#if !defined(S_IFFIFO) && defined(S_ISFIFO)
+    	if (S_ISFIFO(mode)) {
+            type = APR_PIPE;
+	} else
+#endif
+#if !defined(BEOS) && !defined(S_IFSOCK) && defined(S_ISSOCK)
+    	if (S_ISSOCK(mode)) {
+            type = APR_SOCK;
+	} else
+#endif
+        type = APR_UNKFILE;
+    }
+    return type;
+}
+
+static void fill_out_finfo(apr_finfo_t *finfo, struct_stat *info,
+                           apr_int32_t wanted)
+{ 
+    finfo->valid = APR_FINFO_MIN | APR_FINFO_IDENT | APR_FINFO_NLINK
+                 | APR_FINFO_OWNER | APR_FINFO_PROT;
+    finfo->protection = apr_unix_mode2perms(info->st_mode);
+    finfo->filetype = filetype_from_mode(info->st_mode);
+    finfo->user = info->st_uid;
+    finfo->group = info->st_gid;
+    finfo->size = info->st_size;
+    finfo->inode = info->st_ino;
+    finfo->device = info->st_dev;
+    finfo->nlink = info->st_nlink;
+    apr_time_ansi_put(&finfo->atime, info->st_atime);
+#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+    finfo->atime += info->st_atim.tv_nsec / APR_TIME_C(1000);
+#elif defined(HAVE_STRUCT_STAT_ST_ATIMENSEC)
+    finfo->atime += info->st_atimensec / APR_TIME_C(1000);
+#elif defined(HAVE_STRUCT_STAT_ST_ATIME_N)
+    finfo->ctime += info->st_atime_n / APR_TIME_C(1000);
+#endif
+
+    apr_time_ansi_put(&finfo->mtime, info->st_mtime);
+#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+    finfo->mtime += info->st_mtim.tv_nsec / APR_TIME_C(1000);
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
+    finfo->mtime += info->st_mtimensec / APR_TIME_C(1000);
+#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
+    finfo->ctime += info->st_mtime_n / APR_TIME_C(1000);
+#endif
+
+    apr_time_ansi_put(&finfo->ctime, info->st_ctime);
+#ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
+    finfo->ctime += info->st_ctim.tv_nsec / APR_TIME_C(1000);
+#elif defined(HAVE_STRUCT_STAT_ST_CTIMENSEC)
+    finfo->ctime += info->st_ctimensec / APR_TIME_C(1000);
+#elif defined(HAVE_STRUCT_STAT_ST_CTIME_N)
+    finfo->ctime += info->st_ctime_n / APR_TIME_C(1000);
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+#ifdef DEV_BSIZE
+    finfo->csize = (apr_off_t)info->st_blocks * (apr_off_t)DEV_BSIZE;
+#else
+    finfo->csize = (apr_off_t)info->st_blocks * (apr_off_t)512;
+#endif
+    finfo->valid |= APR_FINFO_CSIZE;
+#endif
+}
+
+apr_status_t apr_file_info_get_locked(apr_finfo_t *finfo, apr_int32_t wanted,
+                                      apr_file_t *thefile)
+{
+
+    struct_stat info;
 
+    if (thefile->buffered) {
+        apr_status_t rv = apr_file_flush_locked(thefile);
+        if (rv != APR_SUCCESS)
+            return rv;
+    }
+
+    if (fstat(thefile->filedes, &info) == 0) {
+        finfo->pool = thefile->pool;
+        finfo->fname = thefile->fname;
+        fill_out_finfo(finfo, &info, wanted);
+        return (wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS;
+    }
+    else {
+        return errno;
+    }
+}
+#endif
 
 APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo, apr_int32_t wanted, 
                                    apr_file_t *thefile)
@@ -130,6 +246,29 @@
     return APR_ENOTIMPL;
 }
 
+/* duplciated from dir_make_recurse.c */
+
+#define IS_SEP(c) (c == '/' || c == '\\')
+
+/* Remove trailing separators that don't affect the meaning of PATH. */
+static const char *path_canonicalize(const char *path, apr_pool_t *pool)
+{
+    /* At some point this could eliminate redundant components.  For
+     * now, it just makes sure there is no trailing slash. */
+    apr_size_t len = strlen(path);
+    apr_size_t orig_len = len;
+
+    while ((len > 0) && IS_SEP(path[len - 1])) {
+        len--;
+    }
+
+    if (len != orig_len) {
+        return apr_pstrndup(pool, path, len);
+    }
+    else {
+        return path;
+    }
+}
 
 APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, const char *fname,
                               apr_int32_t wanted, apr_pool_t *cont)
@@ -140,8 +279,10 @@
     finfo->protection = 0;
     finfo->filetype = APR_NOFILE;
     finfo->name = NULL;
-    rc = DosQueryPathInfo(fname, FIL_STANDARD, &fstatus, sizeof(fstatus));
-    
+
+    /* remove trailing / from any paths, otherwise DosQueryPathInfo will fail */
+    const char *newfname = path_canonicalize(fname, cont);
+    rc = DosQueryPathInfo(newfname, FIL_STANDARD, &fstatus, sizeof(fstatus));
     if (rc == 0) {
         FS3_to_finfo(finfo, &fstatus);
         finfo->fname = fname;
@@ -172,7 +313,12 @@
         return APR_FROM_OS_ERROR(rc);
     }
 
+#ifndef __INNOTEK_LIBC__
     return (wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS;
+#else
+    return APR_SUCCESS;
+#endif
+
 }
 
 
diff -ur apr-1.6.3-o/file_io/os2/maperrorcode.c apr-1.6.3/file_io/os2/maperrorcode.c
--- apr-1.6.3-o/file_io/os2/maperrorcode.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/file_io/os2/maperrorcode.c	2018-01-26 18:08:34.000000000 +1030
@@ -18,8 +18,8 @@
 #include "apr_arch_file_io.h"
 #include "apr_file_io.h"
 #include <errno.h>
-#include <string.h>
 #include "apr_errno.h"
+#include <string.h>
 
 static int errormap[][2] = {
     { NO_ERROR,                   APR_SUCCESS      },
@@ -37,7 +37,7 @@
     { ERROR_NEGATIVE_SEEK,        APR_ESPIPE       },
     { ERROR_NO_SIGNAL_SENT,       ESRCH            },
     { ERROR_NO_DATA,              APR_EAGAIN       },
-    { SOCEINTR,                 EINTR           },
+    { SOCEINTR,         	EINTR           },
     { SOCEWOULDBLOCK,           EWOULDBLOCK     },
     { SOCEINPROGRESS,           EINPROGRESS     },
     { SOCEALREADY,              EALREADY        },
@@ -70,7 +70,8 @@
     { SOCEHOSTDOWN,             EHOSTDOWN       },
     { SOCEHOSTUNREACH,          EHOSTUNREACH    },
     { SOCENOTEMPTY,             ENOTEMPTY       },
-    { SOCEPIPE,                 EPIPE           }
+    { SOCEPIPE,                 EPIPE           },
+    { SOCEFAULT,		EFAULT		}
 };
 
 #define MAPSIZE (sizeof(errormap)/sizeof(errormap[0]))
@@ -81,15 +82,13 @@
 
     if (err < APR_OS_START_SYSERR)
         return err;
-
     err -= APR_OS_START_SYSERR;
-
     for (index=0; index<MAPSIZE && errormap[index][0] != err; index++);
     
     if (index<MAPSIZE)
         rv = errormap[index][1];
     else
-        fprintf(stderr, "apr_canonical_error: Unknown OS/2 error code %d\n", err );
+        fprintf(stderr, "apr_canonical_error: Unknown OS/2 error code %d\n",err);
         
     return rv;
 }
diff -ur apr-1.6.3-o/file_io/os2/open.c apr-1.6.3/file_io/os2/open.c
--- apr-1.6.3-o/file_io/os2/open.c	2013-11-02 22:06:02.000000000 +1030
+++ apr-1.6.3/file_io/os2/open.c	2018-01-26 18:08:34.000000000 +1030
@@ -28,6 +28,59 @@
     return apr_file_close(file);
 }
 
+#ifdef __INNOTEK_LIBC__
+static apr_status_t file_cleanup(apr_file_t *file)
+{
+    apr_status_t rv = APR_SUCCESS;
+
+    if (close(file->filedes) == 0) {
+        file->filedes = -1;
+        if (file->flags & APR_DELONCLOSE) {
+            unlink(file->fname);
+        }
+#if APR_HAS_THREADS
+        if (file->mutex) {
+            rv = apr_thread_mutex_destroy(file->mutex);
+        }
+#endif
+    }
+    else {
+        /* Are there any error conditions other than EINTR or EBADF? */
+        rv = errno;
+    }
+#ifndef WAITIO_USES_POLL
+    if (file->pollset != NULL) {
+        int pollset_rv = apr_pollset_destroy(file->pollset);
+        /* If the file close failed, return its error value,
+         * not apr_pollset_destroy()'s.
+         */
+        if (rv == APR_SUCCESS) {
+            rv = pollset_rv;
+        }
+    }
+#endif /* !WAITIO_USES_POLL */
+    return rv;
+}
+
+apr_status_t apr_unix_file_cleanup(void *thefile)
+{
+    apr_file_t *file = thefile;
+    apr_status_t flush_rv = APR_SUCCESS, rv = APR_SUCCESS;
+
+    if (file->buffered) {
+        flush_rv = apr_file_flush(file);
+    }
+
+    rv = file_cleanup(file);
+
+    return rv != APR_SUCCESS ? rv : flush_rv;
+}
+
+apr_status_t apr_unix_child_file_cleanup(void *thefile)
+{
+    return file_cleanup(thefile);
+}
+#endif
 
 
 APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, const char *fname, apr_int32_t flag,  apr_fileperms_t perm, apr_pool_t *pool)
@@ -36,6 +89,9 @@
     int mflags = OPEN_FLAGS_FAIL_ON_ERROR|OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT;
     int rv;
     ULONG action;
+    ULONG    CurMaxFH      = 0;          /* Current count of handles         */
+    LONG     ReqCount      = 0;          /* Number to adjust file handles    */
+
     apr_file_t *dafile = (apr_file_t *)apr_palloc(pool, sizeof(apr_file_t));
 
     if (flag & APR_FOPEN_NONBLOCK) {
@@ -89,7 +145,16 @@
     }
     
     rv = DosOpen(fname, &(dafile->filedes), &action, 0, 0, oflags, mflags, NULL);
-    
+
+    if (rv == ERROR_TOO_MANY_OPEN_FILES) {
+	rv = DosSetRelMaxFH(&ReqCount,     /* Using 0 here will return the       */
+                      &CurMaxFH);    /* current number of file handles     */
+	ReqCount      = 10L;         /* Want 10 more file handles         */
+	rv = DosSetRelMaxFH(&ReqCount,&CurMaxFH);     /* Change handle maximum */
+
+	rv = DosOpen(fname, &(dafile->filedes), &action, 0, 0, oflags, mflags, NULL);
+    }    
+
     if (rv == 0 && (flag & APR_FOPEN_APPEND)) {
         ULONG newptr;
         rv = DosSetFilePtr(dafile->filedes, 0, FILE_END, &newptr );
@@ -100,7 +165,7 @@
     
     if (rv != 0)
         return APR_FROM_OS_ERROR(rv);
-    
+   
     dafile->isopen = TRUE;
     dafile->fname = apr_pstrdup(pool, fname);
     dafile->filePtr = 0;
@@ -108,6 +173,8 @@
     dafile->dataRead = 0;
     dafile->direction = 0;
     dafile->pipe = FALSE;
+    dafile->ungetchar = -1;
+
 
     if (!(flag & APR_FOPEN_NOCLEANUP)) {
         apr_pool_cleanup_register(dafile->pool, dafile, apr_file_cleanup, apr_file_cleanup);
@@ -127,6 +194,12 @@
     if (file && file->isopen) {
         /* XXX: flush here is not mutex protected */
         status = apr_file_flush(file);
+
+	/* 2014-11-18 SHL ensure client sees ERROR_BROKEN_PIPE */
+        if (file->pipe == 1) {
+            DosCloseEventSem(file->pipeSem);
+            DosDisConnectNPipe(file->filedes);
+        }
         rc = DosClose(file->filedes);
     
         if (rc == 0) {
@@ -197,6 +270,7 @@
     (*file)->flags = flags;
     (*file)->pipe = FALSE;
     (*file)->buffered = (flags & APR_FOPEN_BUFFERED) > 0;
+    (*file)->ungetchar = -1;
 
     if ((*file)->buffered) {
         apr_status_t rv;
@@ -279,11 +353,9 @@
     ULONG state;
 
     rv = DosQueryFHState(thefile->filedes, &state);
-
     if (rv == 0 && (state & OPEN_FLAGS_NOINHERIT) != 0) {
         rv = DosSetFHState(thefile->filedes, state & ~OPEN_FLAGS_NOINHERIT);
     }
-
     return APR_FROM_OS_ERROR(rv);
 }
 
@@ -295,10 +367,14 @@
     ULONG state;
 
     rv = DosQueryFHState(thefile->filedes, &state);
-
     if (rv == 0 && (state & OPEN_FLAGS_NOINHERIT) == 0) {
-        rv = DosSetFHState(thefile->filedes, state | OPEN_FLAGS_NOINHERIT);
+/*        rv = DosSetFHState(thefile->filedes, state | OPEN_FLAGS_NOINHERIT);*/
     }
-
     return APR_FROM_OS_ERROR(rv);
 }
+
+APR_DECLARE(apr_status_t) apr_file_link(const char *from_path, 
+                                          const char *to_path)
+{
+    return APR_ENOTIMPL;;
+}
diff -ur apr-1.6.3-o/file_io/os2/pipe.c apr-1.6.3/file_io/os2/pipe.c
--- apr-1.6.3-o/file_io/os2/pipe.c	2016-03-25 11:58:12.000000000 +1030
+++ apr-1.6.3/file_io/os2/pipe.c	2018-01-26 18:08:34.000000000 +1030
@@ -31,9 +31,11 @@
     ULONG rc, action;
     static int id = 0;
     char pipename[50];
+    ULONG    CurMaxFH      = 0;          /* Current count of handles         */
+    LONG     ReqCount      = 0;          /* Number to adjust file handles    */
 
     sprintf(pipename, "/pipe/%d.%d", getpid(), id++);
-    rc = DosCreateNPipe(pipename, filedes, NP_ACCESS_INBOUND, NP_NOWAIT|1, 4096, 4096, 0);
+    rc = DosCreateNPipe(pipename, filedes, NP_ACCESS_INBOUND, NP_NOWAIT|0x01, 4096, 4096, 0);
 
     if (rc)
         return APR_FROM_OS_ERROR(rc);
@@ -49,6 +51,18 @@
                   OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
                   OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYREADWRITE,
                   NULL);
+    if (rc == ERROR_TOO_MANY_OPEN_FILES) {
+	rc = DosSetRelMaxFH(&ReqCount,     /* Using 0 here will return the       */
+                      &CurMaxFH);    /* current number of file handles     */
+	ReqCount      = 10L;         /* Want 10 more file handles         */
+	rc = DosSetRelMaxFH(&ReqCount,&CurMaxFH);     /* Change handle maximum */
+
+	rc = DosOpen (pipename, filedes+1, &action, 0, FILE_NORMAL,
+                  OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
+                  OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYREADWRITE,
+                  NULL);
+
+    }    
 
     if (rc) {
         DosClose(filedes[0]);
@@ -85,6 +99,7 @@
     (*in)->flags = 0;
     (*in)->pipe = 1;
     (*in)->timeout = -1;
+    (*in)->ungetchar = -1;
     (*in)->blocking = BLK_ON;
     apr_pool_cleanup_register(pool_in, *in, apr_file_cleanup,
             apr_pool_cleanup_null);
@@ -96,7 +111,8 @@
     (*out)->isopen = TRUE;
     (*out)->buffered = FALSE;
     (*out)->flags = 0;
-    (*out)->pipe = 1;
+    (*out)->pipe = 2;			// 2014-11-17 SHL mark as client pipe
+    (*out)->ungetchar = -1;
     (*out)->timeout = -1;
     (*out)->blocking = BLK_ON;
     apr_pool_cleanup_register(pool_out, *out, apr_file_cleanup,
@@ -173,23 +189,24 @@
 
 APR_DECLARE(apr_status_t) apr_file_pipe_timeout_set(apr_file_t *thepipe, apr_interval_time_t timeout)
 {
+    int rc = 0;
+
     if (thepipe->pipe == 1) {
         thepipe->timeout = timeout;
 
-        if (thepipe->timeout >= 0) {
-            if (thepipe->blocking != BLK_OFF) {
+        if ((thepipe->timeout >= 0) && (thepipe->blocking != BLK_OFF) ) {
                 thepipe->blocking = BLK_OFF;
-                return APR_FROM_OS_ERROR(DosSetNPHState(thepipe->filedes, NP_NOWAIT));
-            }
+            rc = DosSetNPHState(thepipe->filedes, NP_NOWAIT);
         }
-        else if (thepipe->timeout == -1) {
-            if (thepipe->blocking != BLK_ON) {
+        else if ( (thepipe->timeout == -1) && (thepipe->blocking != BLK_ON) ) {
                 thepipe->blocking = BLK_ON;
-                return APR_FROM_OS_ERROR(DosSetNPHState(thepipe->filedes, NP_WAIT));
-            }
-        }
+            rc = DosSetNPHState(thepipe->filedes, NP_WAIT);
     }
-    return APR_EINVAL;
+
+        return APR_FROM_OS_ERROR(rc);
+
+    } else return APR_EINVAL;
+
 }
 
 
@@ -216,6 +233,7 @@
     (*file)->pipe = 1;
     (*file)->blocking = BLK_UNKNOWN; /* app needs to make a timeout call */
     (*file)->timeout = -1;
+    (*file)->ungetchar = -1;
     (*file)->filedes = *thefile;
 
     if (register_cleanup) {
Only in apr-1.6.3/file_io/os2: pipe.c.orig
diff -ur apr-1.6.3-o/file_io/os2/readwrite.c apr-1.6.3/file_io/os2/readwrite.c
--- apr-1.6.3-o/file_io/os2/readwrite.c	2011-02-18 21:54:40.000000000 +1030
+++ apr-1.6.3/file_io/os2/readwrite.c	2018-01-26 18:08:34.000000000 +1030
@@ -24,20 +24,34 @@
 
 #include <malloc.h>
 
-APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size_t *nbytes)
+APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size_t *len)
 {
     ULONG rc = 0;
-    ULONG bytesread;
+    ULONG bytes_read = 0;
 
-    if (!thefile->isopen) {
-        *nbytes = 0;
-        return APR_EBADF;
+    if (*len <= 0) {
+        *len = 0;
+        return APR_SUCCESS;
     }
-
+#if 1
+    /* Handle the ungetchar if there is one */
+    /* copied from win32/readwrite.c */
+    if (thefile->ungetchar != -1) {
+        bytes_read = 1;
+        *(char *)buf = (char)thefile->ungetchar;
+        buf = (char *)buf + 1;
+        (*len)--;
+        thefile->ungetchar = -1;
+        if (*len == 0) {
+            *len = bytes_read;
+            return APR_SUCCESS;
+        }
+    }
+#endif
     if (thefile->buffered) {
         char *pos = (char *)buf;
         ULONG blocksize;
-        ULONG size = *nbytes;
+        ULONG size = *len;
 
         apr_thread_mutex_lock(thefile->mutex);
 
@@ -56,20 +70,20 @@
 
         while (rc == 0 && size > 0) {
             if (thefile->bufpos >= thefile->dataRead) {
-                ULONG bytesread;
+                ULONG bytes_read;
                 rc = DosRead(thefile->filedes, thefile->buffer,
-                             thefile->bufsize, &bytesread);
-
-                if (bytesread == 0) {
+                             thefile->bufsize, &bytes_read);
+                if (bytes_read == 0) {
                     if (rc == 0)
                         thefile->eof_hit = TRUE;
                     break;
                 }
-
-                thefile->dataRead = bytesread;
+		else {
+	                thefile->dataRead = bytes_read;
                 thefile->filePtr += thefile->dataRead;
                 thefile->bufpos = 0;
             }
+            }
 
             blocksize = size > thefile->dataRead - thefile->bufpos ? thefile->dataRead - thefile->bufpos : size;
             memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
@@ -78,40 +92,50 @@
             size -= blocksize;
         }
 
-        *nbytes = rc == 0 ? pos - (char *)buf : 0;
+        *len = rc == 0 ? pos - (char *)buf : 0;
         apr_thread_mutex_unlock(thefile->mutex);
 
-        if (*nbytes == 0 && rc == 0 && thefile->eof_hit) {
+        if (*len == 0 && rc == 0 && thefile->eof_hit) {
             return APR_EOF;
         }
 
         return APR_FROM_OS_ERROR(rc);
     } else {
-        if (thefile->pipe)
-            DosResetEventSem(thefile->pipeSem, &rc);
-
-        rc = DosRead(thefile->filedes, buf, *nbytes, &bytesread);
-
-        if (rc == ERROR_NO_DATA && thefile->timeout != 0) {
-            int rcwait = DosWaitEventSem(thefile->pipeSem, thefile->timeout >= 0 ? thefile->timeout / 1000 : SEM_INDEFINITE_WAIT);
+        /* Unbuffered i/o */
+        apr_size_t nbytes;
 
-            if (rcwait == 0) {
-                rc = DosRead(thefile->filedes, buf, *nbytes, &bytesread);
+        // 2014-11-11 SHL reworked to support ERROR_MORE_DATA etc.
+	for (;;) {
+	    int post_count;
+        if (thefile->pipe)
+		DosResetEventSem(thefile->pipeSem, &post_count);
+	    rc = DosRead(thefile->filedes, buf, *len, &nbytes);
+	    if (!thefile->pipe)
+		break;			// Blocking i/o - we are done
+	    if (rc == ERROR_MORE_DATA) {
+		// Buffer is full - caller will read more eventually
+		rc = NO_ERROR;
+		break;
             }
-            else if (rcwait == ERROR_TIMEOUT) {
-                *nbytes = 0;
+	    if (thefile->timeout == 0)
+		break;
+	    if (rc != ERROR_NO_DATA)
+		break;
+	    rc = DosWaitEventSem(thefile->pipeSem, thefile->timeout >= 0 ? thefile->timeout / 1000 : SEM_INDEFINITE_WAIT);
+	    if (rc == ERROR_TIMEOUT) {
+		*len = 0;
                 return APR_TIMEUP;
             }
-        }
+	} // for
 
         if (rc) {
-            *nbytes = 0;
+	    *len = 0;
             return APR_FROM_OS_ERROR(rc);
         }
 
-        *nbytes = bytesread;
+	*len = nbytes;
         
-        if (bytesread == 0) {
+	if (nbytes == 0) {
             thefile->eof_hit = TRUE;
             return APR_EOF;
         }
@@ -126,17 +150,14 @@
 {
     ULONG rc = 0;
     ULONG byteswritten;
-
     if (!thefile->isopen) {
         *nbytes = 0;
         return APR_EBADF;
     }
-
     if (thefile->buffered) {
         char *pos = (char *)buf;
         int blocksize;
         int size = *nbytes;
-
         apr_thread_mutex_lock(thefile->mutex);
 
         if ( thefile->direction == 0 ) {
@@ -147,19 +168,18 @@
             thefile->bufpos = thefile->dataRead = 0;
             thefile->direction = 1;
         }
-
         while (rc == 0 && size > 0) {
-            if (thefile->bufpos == thefile->bufsize) /* write buffer is full */
+	    if (thefile->bufpos == thefile->bufsize){ /* write buffer is full */
                 /* XXX bug; - rc is double-transformed os->apr below */
                 rc = apr_file_flush(thefile);
-
-            blocksize = size > thefile->bufsize - thefile->bufpos ? thefile->bufsize - thefile->bufpos : size;
+		}
+	    blocksize = size > thefile->bufsize - thefile->bufpos ? 
+	                       thefile->bufsize - thefile->bufpos : size;
             memcpy(thefile->buffer + thefile->bufpos, pos, blocksize);
             thefile->bufpos += blocksize;
             pos += blocksize;
             size -= blocksize;
         }
-
         apr_thread_mutex_unlock(thefile->mutex);
         return APR_FROM_OS_ERROR(rc);
     } else {
@@ -167,20 +187,16 @@
             FILELOCK all = { 0, 0x7fffffff };
             ULONG newpos;
             rc = DosSetFileLocks(thefile->filedes, NULL, &all, -1, 0);
-
             if (rc == 0) {
                 rc = DosSetFilePtr(thefile->filedes, 0, FILE_END, &newpos);
-
                 if (rc == 0) {
-                    rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
+	            rc = DosWrite(thefile->filedes, (PVOID)buf, *nbytes, &byteswritten);
                 }
-
                 DosSetFileLocks(thefile->filedes, &all, NULL, -1, 0);
             }
         } else {
             rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
         }
-
         if (rc) {
             *nbytes = 0;
             return APR_FROM_OS_ERROR(rc);
@@ -193,94 +209,84 @@
 
 
 
-#ifdef HAVE_WRITEV
-
 APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile, const struct iovec *vec, apr_size_t nvec, apr_size_t *nbytes)
 {
-    int bytes;
+    apr_status_t rv = APR_SUCCESS;
+    apr_size_t i;
+    apr_size_t bwrote = 0;
+    char *buf;
 
-    if (thefile->buffered) {
-        apr_status_t rv = apr_file_flush(thefile);
+    *nbytes = 0;
+    for (i = 0; i < nvec; i++) {
+	buf = vec[i].iov_base;
+	bwrote = vec[i].iov_len;
+	rv = apr_file_write(thefile, buf, &bwrote);
+	*nbytes += bwrote;
         if (rv != APR_SUCCESS) {
-            return rv;
+	    break;
         }
     }
-
-    if ((bytes = writev(thefile->filedes, vec, nvec)) < 0) {
-        *nbytes = 0;
-        return errno;
-    }
-    else {
-        *nbytes = bytes;
-        return APR_SUCCESS;
+    return rv;
     }
-}
-#endif
 
 
 
 APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile)
 {
-    ULONG rc;
-    ULONG byteswritten;
+    apr_size_t nbytes = 1;
 
-    if (!thefile->isopen) {
-        return APR_EBADF;
+    return apr_file_write(thefile, &ch, &nbytes);
     }
 
-    rc = DosWrite(thefile->filedes, &ch, 1, &byteswritten);
 
-    if (rc) {
-        return APR_FROM_OS_ERROR(rc);
-    }
     
-    return APR_SUCCESS;
-}
-
-
-
 APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile)
 {
-    apr_off_t offset = -1;
-    return apr_file_seek(thefile, APR_CUR, &offset);
+    thefile->ungetchar = (unsigned char)ch;
+    return APR_SUCCESS; 
 }
 
 
 APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile)
 {
-    ULONG rc;
-    apr_size_t bytesread;
+    apr_size_t nbytes = 1;
+
+    return apr_file_read(thefile, ch, &nbytes);
 
-    if (!thefile->isopen) {
-        return APR_EBADF;
     }
 
-    bytesread = 1;
-    rc = apr_file_read(thefile, ch, &bytesread);
 
-    if (rc) {
-        return rc;
-    }
     
-    if (bytesread == 0) {
-        thefile->eof_hit = TRUE;
-        return APR_EOF;
+APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile)
+{
+    return apr_file_write_full(thefile, str, strlen(str), NULL);
     }
     
-    return APR_SUCCESS;
-}
 
 
-
-APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile)
+apr_status_t apr_file_flush_locked(apr_file_t *thefile)
 {
-    apr_size_t len;
+    apr_status_t rv = APR_SUCCESS;
+
+    if (thefile->direction == 1 && thefile->bufpos) {
+	apr_ssize_t written;
+
+	do {
+	    written = write(thefile->filedes, thefile->buffer, thefile->bufpos);
+	} while (written == -1 && errno == EINTR);
+	if (written == -1) {
+	    rv = errno;
+	} else {
+	    thefile->filePtr += written;
+	    thefile->bufpos = 0;
+}
+    }
 
-    len = strlen(str);
-    return apr_file_write(thefile, str, &len); 
+    return rv;
 }
 
 
+
 APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile)
 {
     if (thefile->buffered) {
@@ -349,10 +355,61 @@
 }
 
 
+/* Pull from unix code to start a sync up */
+#if (defined(__INNOTEK_LIBC__) || defined(__WATCOMC__) )
+
+struct apr_file_printf_data {
+    apr_vformatter_buff_t vbuff;
+    apr_file_t *fptr;
+    char *buf;
+};
+
+static int file_printf_flush(apr_vformatter_buff_t *buff)
+{
+    struct apr_file_printf_data *data = (struct apr_file_printf_data *)buff;
+
+    if (apr_file_write_full(data->fptr, data->buf,
+	                    data->vbuff.curpos - data->buf, NULL)) {
+	return -1;
+    }
+
+    data->vbuff.curpos = data->buf;
+    return 0;
+}
 
 APR_DECLARE_NONSTD(int) apr_file_printf(apr_file_t *fptr, 
                                         const char *format, ...)
 {
+    struct apr_file_printf_data data;
+    va_list ap;
+    int count;
+
+    /* don't really need a HUGE_STRING_LEN anymore */
+    data.buf = malloc(HUGE_STRING_LEN);
+    if (data.buf == NULL) {
+	return -1;
+    }
+    data.vbuff.curpos = data.buf;
+    data.vbuff.endpos = data.buf + HUGE_STRING_LEN;
+    data.fptr = fptr;
+    va_start(ap, format);
+    count = apr_vformatter(file_printf_flush,
+	                   (apr_vformatter_buff_t *)&data, format, ap);
+    /* apr_vformatter does not call flush for the last bits */
+    if (count >= 0) file_printf_flush((apr_vformatter_buff_t *)&data);
+
+    va_end(ap);
+
+    free(data.buf);
+
+    return count;
+}
+
+#else
+
+APR_DECLARE_NONSTD(int) apr_file_printf(apr_file_t *fptr, 
+	                                const char *format, ...)
+{
     int cc;
     va_list ap;
     char *buf;
@@ -369,7 +426,7 @@
     free(buf);
     return (cc == APR_SUCCESS) ? len : -1;
 }
-
+#endif
 
 
 apr_status_t apr_file_check_read(apr_file_t *fd)
diff -ur apr-1.6.3-o/file_io/os2/seek.c apr-1.6.3/file_io/os2/seek.c
--- apr-1.6.3-o/file_io/os2/seek.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/file_io/os2/seek.c	2018-01-26 18:08:34.000000000 +1030
@@ -55,6 +55,7 @@
 
 APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, apr_seek_where_t where, apr_off_t *offset)
 {
+#ifndef __KLIBC__
     if (!thefile->isopen) {
         return APR_EBADF;
     }
@@ -100,6 +101,51 @@
 
         return APR_FROM_OS_ERROR(DosSetFilePtr(thefile->filedes, *offset, where, (ULONG *)offset));
     }
+#else
+    apr_off_t rv;
+
+    thefile->eof_hit = 0;
+
+    if (thefile->buffered) {
+        int rc = EINVAL;
+        apr_finfo_t finfo;
+
+        file_lock(thefile);
+
+        switch (where) {
+        case APR_SET:
+            rc = setptr(thefile, *offset);
+            break;
+
+        case APR_CUR:
+            rc = setptr(thefile, thefile->filePtr - thefile->dataRead + thefile->bufpos + *offset);
+            break;
+
+        case APR_END:
+            rc = apr_file_info_get_locked(&finfo, APR_FINFO_SIZE, thefile);
+            if (rc == APR_SUCCESS)
+                rc = setptr(thefile, finfo.size + *offset);
+            break;
+        }
+
+        *offset = thefile->filePtr - thefile->dataRead + thefile->bufpos;
+
+        file_unlock(thefile);
+
+        return rc;
+    }
+    else {
+        rv = lseek(thefile->filedes, *offset, where);
+        if (rv == -1) {
+            *offset = -1;
+            return errno;
+        }
+        else {
+            *offset = rv;
+            return APR_SUCCESS;
+        }
+    }
+#endif
 }
 
 
diff -ur apr-1.6.3-o/file_io/unix/fileacc.c apr-1.6.3/file_io/unix/fileacc.c
--- apr-1.6.3-o/file_io/unix/fileacc.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/file_io/unix/fileacc.c	2018-01-26 18:08:34.000000000 +1030
@@ -31,7 +31,7 @@
     return f->flags;
 }
 
-#if !defined(OS2) && !defined(WIN32)
+#if (!defined(OS2) && !defined(WIN32)) || defined (__KLIBC__)
 mode_t apr_unix_perms2mode(apr_fileperms_t perms)
 {
     mode_t mode = 0;
diff -ur apr-1.6.3-o/file_io/unix/mktemp.c apr-1.6.3/file_io/unix/mktemp.c
--- apr-1.6.3-o/file_io/unix/mktemp.c	2014-02-13 05:52:46.000000000 +1030
+++ apr-1.6.3/file_io/unix/mktemp.c	2018-01-26 18:08:34.000000000 +1030
@@ -81,7 +81,9 @@
 #include <fcntl.h>
 #endif
 #include <stdio.h>
+#ifndef __INNOTEK_LIBC__
 #include <stdlib.h>
+#endif
 #include <string.h>
 #include <ctype.h>
 #ifdef HAVE_TIME_H
@@ -189,6 +191,11 @@
 #else
     fd = mkstemp(template);
 #endif
+
+#ifdef __INNOTEK_LIBC__
+          setmode(fd, O_BINARY);
+#endif 
+
     
     if (fd == -1) {
         return errno;
diff -ur apr-1.6.3-o/include/apr_errno.h apr-1.6.3/include/apr_errno.h
--- apr-1.6.3-o/include/apr_errno.h	2016-03-04 02:41:16.000000000 +1030
+++ apr-1.6.3/include/apr_errno.h	2018-01-26 18:08:34.000000000 +1030
@@ -853,7 +853,7 @@
 
 #define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR)
 #define APR_TO_OS_ERROR(e)   (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR)
-
+#define apr_get_os_error()    (errno)
 #define INCL_DOSERRORS
 #define INCL_DOS
 
@@ -934,7 +934,7 @@
                 || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED)
 #define APR_STATUS_IS_ENAMETOOLONG(s)   ((s) == APR_ENAMETOOLONG \
                 || (s) == APR_OS_START_SYSERR + ERROR_FILENAME_EXCED_RANGE \
-                || (s) == APR_OS_START_SYSERR + SOCENAMETOOLONG)
+                || (s) == APR_OS_START_SYSERR + SOCENAMETOOLONG  || (s) == SOCENAMETOOLONG)
 #define APR_STATUS_IS_ENOENT(s)         ((s) == APR_ENOENT \
                 || (s) == APR_OS_START_SYSERR + ERROR_FILE_NOT_FOUND \
                 || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \
@@ -954,9 +954,12 @@
                 || (s) == APR_OS_START_SYSERR + ERROR_INVALID_FUNCTION)
 #define APR_STATUS_IS_ESPIPE(s)         ((s) == APR_ESPIPE \
                 || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK)
+/* 2015-02-06 SHL SHL Add more */
 #define APR_STATUS_IS_EAGAIN(s)         ((s) == APR_EAGAIN \
                 || (s) == APR_OS_START_SYSERR + ERROR_NO_DATA \
                 || (s) == APR_OS_START_SYSERR + SOCEWOULDBLOCK \
+                || (s) == APR_OS_START_SYSERR + ENOBUFS \
+                || (s) == APR_OS_START_SYSERR + SOCENOBUFS \
                 || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION)
 #define APR_STATUS_IS_EINTR(s)          ((s) == APR_EINTR \
                 || (s) == APR_OS_START_SYSERR + SOCEINTR)
Only in apr-1.6.3/include: apr_errno.h.orig
diff -ur apr-1.6.3-o/include/apr_network_io.h apr-1.6.3/include/apr_network_io.h
--- apr-1.6.3-o/include/apr_network_io.h	2016-03-03 22:40:40.000000000 +1030
+++ apr-1.6.3/include/apr_network_io.h	2018-01-26 18:08:34.000000000 +1030
@@ -21,6 +21,11 @@
  * @brief APR Network library
  */
 
+#ifdef __KLIBC__
+/* we don't want to include nerror.h from types.h - define this so it doesn't get included */
+#define _NERROR_H_ 1
+#endif
+
 #include "apr.h"
 #include "apr_pools.h"
 #include "apr_file_io.h"
diff -ur apr-1.6.3-o/include/apr_poll.h apr-1.6.3/include/apr_poll.h
--- apr-1.6.3-o/include/apr_poll.h	2016-03-25 11:49:34.000000000 +1030
+++ apr-1.6.3/include/apr_poll.h	2018-01-26 18:08:34.000000000 +1030
@@ -279,8 +279,9 @@
  * @remark If the pollset was not created with APR_POLLSET_WAKEABLE the
  *         return value is APR_EINIT.
  */
+#ifndef __OS2__
 APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset);
-
+#endif
 /**
  * Poll the descriptors in the poll structure
  * @param aprset The poll structure we will be using. 
@@ -305,14 +306,17 @@
  * Return a printable representation of the pollset method.
  * @param pollset The pollset to use
  */
+#ifndef __OS2__
 APR_DECLARE(const char *) apr_pollset_method_name(apr_pollset_t *pollset);
+#endif
 
 /**
  * Return a printable representation of the default pollset method
  * (APR_POLLSET_DEFAULT).
  */
+#ifndef __OS2__
 APR_DECLARE(const char *) apr_poll_method_defname(void);
-
+#endif
 /** Opaque structure used for pollcb API */
 typedef struct apr_pollcb_t apr_pollcb_t;
 
@@ -352,12 +356,13 @@
  * @remark Pollcb is only supported on some platforms; the apr_pollcb_create_ex()
  *         call will fail with APR_ENOTIMPL on platforms where it is not supported.
  */
+#ifndef __OS2__
 APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **pollcb,
                                                apr_uint32_t size,
                                                apr_pool_t *p,
                                                apr_uint32_t flags,
                                                apr_pollset_method_e method);
-
+#endif
 /**
  * Add a socket or file descriptor to a pollcb
  * @param pollcb The pollcb to which to add the descriptor
Only in apr-1.6.3/include: apr_poll.h.orig
diff -ur apr-1.6.3-o/include/apr_portable.h apr-1.6.3/include/apr_portable.h
--- apr-1.6.3-o/include/apr_portable.h	2016-04-13 21:35:20.000000000 +0930
+++ apr-1.6.3/include/apr_portable.h	2018-01-26 18:08:34.000000000 +1030
@@ -406,7 +406,7 @@
  * to by sock will be reused and updated with the given socket.
  * @param sock The pool to use.
  * @param thesock The socket to convert to.
- * @param cont The socket we are converting to an apr type.
+ * @param cont The pool to use.
  * @remark If it is a true socket, it is best to call apr_os_sock_make()
  *         and provide APR with more information about the socket.
  */
@@ -415,6 +415,14 @@
                                           apr_pool_t *cont);
 
 /**
+ * Deregister socket cleanup function for socket.
+ * Ensures sockets not owned by process are not closed during pool cleanup.
+ * Supports use case where httpd mpm passes listen sockets to child process.
+ * @param sock The socket to have cleanup deregistered.
+ */
+APR_DECLARE(void) apr_sock_cleanup_kill(apr_socket_t *sock);
+
+/**
  * Create a socket from an existing descriptor and local and remote
  * socket addresses.
  * @param apr_sock The new socket that has been set up
Only in apr-1.6.3/include: apr_portable.h.orig
diff -ur apr-1.6.3-o/include/apr_support.h apr-1.6.3/include/apr_support.h
--- apr-1.6.3-o/include/apr_support.h	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/include/apr_support.h	2018-01-26 18:08:34.000000000 +1030
@@ -45,7 +45,7 @@
  *        otherwise wait for data to be able to be written. 
  * @return APR_TIMEUP if we run out of time.
  */
-apr_status_t apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s,
+APR_DECLARE(apr_status_t) apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s,
                                         int for_read);
 
 /** @} */
Only in apr-1.6.3/include: apr.h
diff -ur apr-1.6.3-o/include/apr.h.in apr-1.6.3/include/apr.h.in
--- apr-1.6.3-o/include/apr.h.in	2017-05-24 02:06:02.000000000 +0930
+++ apr-1.6.3/include/apr.h.in	2018-01-26 18:08:34.000000000 +1030
@@ -185,6 +185,10 @@
 #ifdef OS2
 #define INCL_DOS
 #define INCL_DOSERRORS
+#define INCL_EXAPIS
+#ifdef __KLIBC__
+#include <os2safe.h>
+#endif
 #include <os2.h>
 #endif
 
diff -ur apr-1.6.3-o/include/arch/os2/apr_arch_file_io.h apr-1.6.3/include/arch/os2/apr_arch_file_io.h
--- apr-1.6.3-o/include/arch/os2/apr_arch_file_io.h	2011-02-18 21:54:40.000000000 +1030
+++ apr-1.6.3/include/arch/os2/apr_arch_file_io.h	2018-01-26 18:08:34.000000000 +1030
@@ -25,11 +25,17 @@
 #include "apr_errno.h"
 #include "apr_poll.h"
 
+#ifdef __KLIBC__
+#include <sys/stat.h>
+#endif
+
 /* We have an implementation of mkstemp but it's not very multi-threading 
  * friendly & is part of the POSIX emulation rather than native so don't
  * use it.
  */
+#ifndef __INNOTEK_LIBC__x
 #undef HAVE_MKSTEMP
+#endif
 
 #define APR_FILE_DEFAULT_BUFSIZE 4096
 #define APR_FILE_BUFSIZE APR_FILE_DEFAULT_BUFSIZE
@@ -37,25 +43,32 @@
 struct apr_file_t {
     apr_pool_t *pool;
     HFILE filedes;
+    int pipe;
+    HEV pipeSem;
+    int timeout;
+    apr_int32_t flags;
+
+    /* File specific info */
     char * fname;
     int isopen;
-    int buffered;
     int eof_hit;
-    apr_int32_t flags;
-    int timeout;
-    int pipe;
-    HEV pipeSem;
+    int buffered;
+    int ungetchar;    /* Last char provided by an unget op. (-1 = no char)*/
     enum { BLK_UNKNOWN, BLK_OFF, BLK_ON } blocking;
 
     /* Stuff for buffered mode */
     char *buffer;
-    apr_size_t bufsize;        /* Read/Write position in buffer             */
     apr_size_t bufpos;         /* Read/Write position in buffer             */
-    unsigned long dataRead;    /* amount of valid data read into buffer     */
+    apr_size_t bufsize;        /* Read/Write position in buffer             */
+    apr_size_t dataRead;    /* amount of valid data read into buffer     */
     int direction;             /* buffer being used for 0 = read, 1 = write */
-    unsigned long filePtr;     /* position in file of handle                */
+    apr_off_t filePtr;     /* position in file of handle                */
     apr_thread_mutex_t *mutex; /* mutex semaphore, must be owned to access
                                   the above fields                          */
+#ifndef WAITIO_USES_POLL
+    /* if there is a timeout set, then this pollset is used */
+    apr_pollset_t *pollset;
+#endif
 };
 
 struct apr_dir_t {
@@ -66,6 +79,26 @@
     int validentry;
 };
 
+#ifdef __INNOTEK_LIBC__
+apr_status_t apr_unix_file_cleanup(void *);
+apr_status_t apr_unix_child_file_cleanup(void *);
+#if APR_HAS_THREADS
+#define file_lock(f)   do { \
+                           if ((f)->mutex) \
+                               apr_thread_mutex_lock((f)->mutex); \
+                       } while (0)
+#define file_unlock(f) do { \
+                           if ((f)->mutex) \
+                               apr_thread_mutex_unlock((f)->mutex); \
+                       } while (0)
+#else
+#define file_lock(f)   do {} while (0)
+#define file_unlock(f) do {} while (0)
+#endif
+typedef struct stat struct_stat;
+#endif
+
+
 apr_status_t apr_file_cleanup(void *);
 apr_status_t apr_os2_time_to_apr_time(apr_time_t *result, FDATE os2date, 
                                       FTIME os2time);
@@ -81,6 +114,10 @@
 apr_status_t filepath_drive_get(char **rootpath, char drive, 
                                 apr_int32_t flags, apr_pool_t *p);
 apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p);
-
+#ifdef __KLIBC__
+apr_status_t apr_file_flush_locked(apr_file_t *thefile);
+apr_status_t apr_file_info_get_locked(apr_finfo_t *finfo, apr_int32_t wanted,
+                                      apr_file_t *thefile);
+#endif
 #endif  /* ! FILE_IO_H */
 
diff -ur apr-1.6.3-o/include/arch/os2/apr_arch_os2calls.h apr-1.6.3/include/arch/os2/apr_arch_os2calls.h
--- apr-1.6.3-o/include/arch/os2/apr_arch_os2calls.h	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/include/arch/os2/apr_arch_os2calls.h	2018-01-26 18:08:34.000000000 +1030
@@ -14,10 +14,14 @@
  * limitations under the License.
  */
 
+#ifndef APR_ARCH_OS2CALLS_H
+#define APR_ARCH_OS2CALLS_H
+#warning xxx
 #include "apr_errno.h"
 #include <sys/types.h>
 #include <sys/socket.h>
 
+//#ifdef TCPV40HDRS
 extern int (*apr_os2_socket)(int, int, int);
 extern int (*apr_os2_select)(int *, int, int, int, long);
 extern int (*apr_os2_sock_errno)();
@@ -57,3 +61,5 @@
 #define writev apr_os2_writev
 #define sendto apr_os2_sendto
 #define recvfrom apr_os2_recvfrom
+//#endif
+#endif /* !defined APR_ARCH_OS2CALLS_H */
diff -ur apr-1.6.3-o/include/arch/os2/apr_arch_proc_mutex.h apr-1.6.3/include/arch/os2/apr_arch_proc_mutex.h
--- apr-1.6.3-o/include/arch/os2/apr_arch_proc_mutex.h	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/include/arch/os2/apr_arch_proc_mutex.h	2018-01-26 18:08:34.000000000 +1030
@@ -26,6 +26,5 @@
     TID owner;
     int lock_count;
 };
-
 #endif  /* PROC_MUTEX_H */
 
diff -ur apr-1.6.3-o/include/arch/os2/apr_arch_threadproc.h apr-1.6.3/include/arch/os2/apr_arch_threadproc.h
--- apr-1.6.3-o/include/arch/os2/apr_arch_threadproc.h	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/include/arch/os2/apr_arch_threadproc.h	2018-01-26 18:08:34.000000000 +1030
@@ -16,6 +16,7 @@
 
 #include "apr_thread_proc.h"
 #include "apr_file_io.h"
+#include <pthread.h>
 
 #ifndef THREAD_PROC_H
 #define THREAD_PROC_H
@@ -34,9 +35,10 @@
 struct apr_thread_t {
     apr_pool_t *pool;
     struct apr_threadattr_t *attr;
+    pthread_t *td;
     unsigned long tid;
-    apr_thread_start_t func;
     void *data;
+    apr_thread_start_t func;
     apr_status_t exitval;
 };
 
diff -ur apr-1.6.3-o/include/arch/unix/apr_arch_poll_private.h apr-1.6.3/include/arch/unix/apr_arch_poll_private.h
--- apr-1.6.3-o/include/arch/unix/apr_arch_poll_private.h	2017-09-12 00:53:22.000000000 +0930
+++ apr-1.6.3/include/arch/unix/apr_arch_poll_private.h	2018-01-26 18:08:34.000000000 +1030
@@ -17,6 +17,7 @@
 #ifndef APR_ARCH_POLL_PRIVATE_H
 #define APR_ARCH_POLL_PRIVATE_H
 
+#ifndef __KLIBC__
 #if HAVE_POLL_H
 #include <poll.h>
 #endif
@@ -24,6 +25,7 @@
 #if HAVE_SYS_POLL_H
 #include <sys/poll.h>
 #endif
+#endif
 
 #ifdef HAVE_PORT_CREATE
 #include <port.h>
Only in apr-1.6.3/include/arch/unix: apr_private.h
Only in apr-1.6.3/include/private: apr_escape_test_char.h
diff -ur apr-1.6.3-o/locks/os2/proc_mutex.c apr-1.6.3/locks/os2/proc_mutex.c
--- apr-1.6.3-o/locks/os2/proc_mutex.c	2017-06-02 08:12:00.000000000 +0930
+++ apr-1.6.3/locks/os2/proc_mutex.c	2018-01-26 18:08:34.000000000 +1030
@@ -85,9 +85,11 @@
     ULONG rc;
     char *semname;
 
+#if 0
     if (mech != APR_LOCK_DEFAULT) {
         return APR_ENOTIMPL;
     }
+#endif
 
     new = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t));
     new->pool       = pool;
@@ -120,6 +122,13 @@
     new->owner      = 0;
     new->lock_count = 0;
 
+#ifdef __INNOTEK_LIBC__
+    if (!fname) {
+        /* Reinitializing unnamed mutexes is a noop in the Unix code. */
+        return APR_SUCCESS;
+    }
+#endif
+
     semname = fixed_name(fname, pool);
     rc = DosOpenMutexSem(semname, &(new->hMutex));
     *mutex = new;
Only in apr-1.6.3/locks/os2: proc_mutex.c.orig
diff -ur apr-1.6.3-o/locks/os2/thread_rwlock.c apr-1.6.3/locks/os2/thread_rwlock.c
--- apr-1.6.3-o/locks/os2/thread_rwlock.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/locks/os2/thread_rwlock.c	2018-01-26 18:08:34.000000000 +1030
@@ -118,6 +118,7 @@
 
         if (rc)
             DosReleaseMutexSem(rwlock->write_lock);
+
     }
 
     return APR_FROM_OS_ERROR(rc);
diff -ur apr-1.6.3-o/memory/unix/apr_pools.c apr-1.6.3/memory/unix/apr_pools.c
--- apr-1.6.3-o/memory/unix/apr_pools.c	2017-04-03 20:48:36.000000000 +0930
+++ apr-1.6.3/memory/unix/apr_pools.c	2018-01-26 18:08:34.000000000 +1030
@@ -407,6 +407,8 @@
 #elif APR_ALLOCATOR_USES_MMAP
     if ((node = mmap(NULL, size, PROT_READ|PROT_WRITE,
                      MAP_PRIVATE|MAP_ANON, -1, 0)) == MAP_FAILED)
+#elif defined(__KLIBC__) /* must use _lmalloc here or calls to DosReadQueue fail */
+    if ((node = _lmalloc(size)) == NULL)
 #else
     if ((node = malloc(size)) == NULL)
 #endif
@@ -971,7 +973,8 @@
     }
 
     *active->ref = NULL;
-    allocator_free(pool->allocator, active->next);
+    if (active->next)
+        allocator_free(pool->allocator, active->next);
     active->next = active;
     active->ref = &active->next;
 
Only in apr-1.6.3/memory/unix: apr_pools.c.orig
diff -ur apr-1.6.3-o/misc/unix/errorcodes.c apr-1.6.3/misc/unix/errorcodes.c
--- apr-1.6.3-o/misc/unix/errorcodes.c	2014-05-10 05:30:14.000000000 +0930
+++ apr-1.6.3/misc/unix/errorcodes.c	2018-01-26 18:08:34.000000000 +1030
@@ -145,9 +145,8 @@
 }
 
 
-#ifdef OS2
+#if defined(OS2) 
 #include <ctype.h>
-
 int apr_canonical_error(apr_status_t err);
 
 static char *apr_os_strerror(char* buf, apr_size_t bufsize, int err)
diff -ur apr-1.6.3-o/misc/unix/rand.c apr-1.6.3/misc/unix/rand.c
--- apr-1.6.3-o/misc/unix/rand.c	2007-07-04 19:31:04.000000000 +0930
+++ apr-1.6.3/misc/unix/rand.c	2018-01-26 18:08:34.000000000 +1030
@@ -122,7 +122,7 @@
     
     close(fd);
 #elif defined(OS2)
-    static UCHAR randbyte();
+    UCHAR randbyte();
     unsigned int idx;
 
     for (idx=0; idx<length; idx++)
diff -ur apr-1.6.3-o/misc/unix/randbyte_os2.inc apr-1.6.3/misc/unix/randbyte_os2.inc
--- apr-1.6.3-o/misc/unix/randbyte_os2.inc	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/misc/unix/randbyte_os2.inc	2018-01-26 18:08:34.000000000 +1030
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#ifndef __KLIBC__ /* KLIBC has a random() function - use it */
 /* The high resolution timer API provides access to the hardware timer 
  * running at around 1.1MHz. The amount this changes in a time slice is
  * varies randomly due to system events, hardware interrupts etc
@@ -62,8 +63,10 @@
  * which is why it's run-time linked.
  */
 
+#ifndef __INNOTEK_LIBC__
 static APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1,
                                          ULONG ulParm2, ULONG ulParm3) = NULL;
+#endif
 static HMODULE hDoscalls = 0;
 #define   CMD_KI_RDCNT    (0x63)
 
@@ -85,6 +88,7 @@
     CPUUTIL util;
     int c;
 
+#ifndef __INNOTEK_LIBC__
     if (hDoscalls == 0) {
         char failed_module[20];
         ULONG rc;
@@ -111,13 +115,28 @@
             DosPerfSysCall = NULL;
         }
     }
-
+#endif
     return byte;
 }
 
 
 
-static UCHAR randbyte()
+UCHAR randbyte()
 {
     return randbyte_hrtimer() ^ randbyte_sysinfo() ^ randbyte_perf();
 }
+#else /* __KLIBC__ */
+UCHAR randbyte()
+{
+    int c;
+    UCHAR byte;
+    ULONG ulrandom;
+    ulrandom = random();
+     
+    for (c = 0; c < sizeof(ulrandom); c++) {
+        byte ^= ((UCHAR *)&ulrandom)[c];
+    }
+
+    return byte;
+}
+#endif
diff -ur apr-1.6.3-o/misc/unix/start.c apr-1.6.3/misc/unix/start.c
--- apr-1.6.3-o/misc/unix/start.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/misc/unix/start.c	2018-01-26 18:08:34.000000000 +1030
@@ -23,7 +23,6 @@
 #include "apr_arch_proc_mutex.h" /* for apr_proc_mutex_unix_setup_lock() */
 #include "apr_arch_internal_time.h"
 
-
 APR_DECLARE(apr_status_t) apr_app_initialize(int *argc, 
                                              const char * const * *argv, 
                                              const char * const * *env)
Only in apr-1.6.3: Makefile
diff -ur apr-1.6.3-o/network_io/os2/os2calls.c apr-1.6.3/network_io/os2/os2calls.c
--- apr-1.6.3-o/network_io/os2/os2calls.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/network_io/os2/os2calls.c	2018-01-26 18:08:34.000000000 +1030
@@ -44,6 +44,7 @@
 
 static HMODULE hSO32DLL;
 
+#ifdef TCPV40HDRS
 static int os2_fn_link()
 {
     DosEnterCritSec(); /* Stop two threads doing this at the same time */
@@ -90,7 +91,7 @@
             rc = DosQueryProcAddr(hSO32DLL, 0, "LISTEN", &apr_os2_listen);
 
         if (!rc)
-            rc = DosQueryProcAddr(hSO32DLL, 0, "RECV", &apr_os2_recv);
+            rc = DosQueryProcAddr(hSO32DLL, 0, "RECV", (PFN *) &apr_os2_recv);
 
         if (!rc)
             rc = DosQueryProcAddr(hSO32DLL, 0, "SEND", &apr_os2_send);
@@ -120,9 +121,86 @@
     DosExitCritSec();
     return APR_SUCCESS;
 }
+#else
+static HMODULE hTCPIP32;
 
+static int os2_fn_link()
+{
+    DosEnterCritSec(); /* Stop two threads doing this at the same time */
+
+    if (apr_os2_socket == os2_socket_init) {
+        ULONG rc;
+        char errorstr[200];
+
+        rc = DosLoadModule(errorstr, sizeof(errorstr), "TCPIP32", &hTCPIP32);
+
+        if (rc)
+            return APR_OS2_STATUS(rc);
+
+        rc = DosQueryProcAddr(hTCPIP32, 0, "SOCKET", &apr_os2_socket);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "SELECT", &apr_os2_select);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "SOCK_ERRNO", &apr_os2_sock_errno);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "ACCEPT", &apr_os2_accept);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "BIND", &apr_os2_bind);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "CONNECT", &apr_os2_connect);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "GETPEERNAME", &apr_os2_getpeername);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "GETSOCKNAME", &apr_os2_getsockname);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "GETSOCKOPT", &apr_os2_getsockopt);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "IOCTL", &apr_os2_ioctl);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "LISTEN", &apr_os2_listen);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "RECV", &apr_os2_recv);
 
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "SEND", &apr_os2_send);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "SETSOCKOPT", &apr_os2_setsockopt);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "SHUTDOWN", &apr_os2_shutdown);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "SOCLOSE", &apr_os2_soclose);
 
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "WRITEV", &apr_os2_writev);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "SENDTO", &apr_os2_sendto);
+
+        if (!rc)
+            rc = DosQueryProcAddr(hTCPIP32, 0, "RECVFROM", &apr_os2_recvfrom);
+
+        if (rc)
+            return APR_OS2_STATUS(rc);
+    }
+
+    DosExitCritSec();
+    return APR_SUCCESS;
+}
+#endif
 static int os2_socket_init(int domain, int type, int protocol)
 {
     int rc = os2_fn_link();
diff -ur apr-1.6.3-o/network_io/os2/sendrecv_udp.c apr-1.6.3/network_io/os2/sendrecv_udp.c
--- apr-1.6.3-o/network_io/os2/sendrecv_udp.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/network_io/os2/sendrecv_udp.c	2018-01-26 18:08:34.000000000 +1030
@@ -94,6 +94,10 @@
         (*len) = 0;
         return APR_FROM_OS_ERROR(serrno);
     }
+#ifdef __KLIBC__
+    apr_sockaddr_vars_set(from, from->sa.sin.sin_family, 
+                          ntohs(from->sa.sin.sin_port));
+#endif
 
     (*len) = rv;
 
diff -ur apr-1.6.3-o/network_io/os2/sendrecv.c apr-1.6.3/network_io/os2/sendrecv.c
--- apr-1.6.3-o/network_io/os2/sendrecv.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/network_io/os2/sendrecv.c	2018-01-26 18:08:34.000000000 +1030
@@ -20,6 +20,7 @@
 #include "apr_network_io.h"
 #include "apr_lib.h"
 #include <sys/time.h>
+#include <stdlib.h>
 
 APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf,
                                           apr_size_t *len)
@@ -27,9 +28,11 @@
     apr_ssize_t rv;
     int fds, err = 0;
 
+#ifndef __INNOTEK_LIBC__
     if (*len > 65536) {
         *len = 65536;
     }
+#endif 
 
     do {
         if (!sock->nonblock || err == SOCEWOULDBLOCK) {
@@ -114,11 +117,17 @@
     int fds, err = 0;
     int nv_tosend, total = 0;
 
+#ifndef __INNOTEK_LIBC__
     /* Make sure writev() only gets fed 64k at a time */
     for ( nv_tosend = 0; nv_tosend < nvec && total + vec[nv_tosend].iov_len < 65536; nv_tosend++ ) {
         total += vec[nv_tosend].iov_len;
     }
-
+#else
+    /* workaround for writev() not required with libc */
+    for ( nv_tosend = 0; nv_tosend < nvec; nv_tosend++ ) {
+        total += vec[nv_tosend].iov_len;
+    }
+#endif
     tmpvec = alloca(sizeof(struct iovec) * nv_tosend);
     memcpy(tmpvec, vec, sizeof(struct iovec) * nv_tosend);
 
@@ -143,7 +152,10 @@
 
         rv = writev(sock->socketdes, tmpvec, nv_tosend);
         err = rv < 0 ? sock_errno() : 0;
-    } while (err == SOCEINTR || err == SOCEWOULDBLOCK);
+        /* 2015-02-06 SHL Allow SOCENOBUFS and delay if out of resources */
+        if (err == SOCEWOULDBLOCK || err == SOCENOBUFS)
+          apr_sleep(100 * 1000);        /* 100 mSec */
+    } while (err == SOCEINTR || err == SOCEWOULDBLOCK || err == SOCENOBUFS);
 
     if (err) {
         *len = 0;
diff -ur apr-1.6.3-o/network_io/os2/sockaddr.c apr-1.6.3/network_io/os2/sockaddr.c
--- apr-1.6.3-o/network_io/os2/sockaddr.c	2004-11-25 09:21:50.000000000 +1030
+++ apr-1.6.3/network_io/os2/sockaddr.c	2018-01-26 18:08:34.000000000 +1030
@@ -1 +1,3 @@
+
 #include "../unix/sockaddr.c"
+#include "../unix/multicast.c"
diff -ur apr-1.6.3-o/network_io/os2/sockets.c apr-1.6.3/network_io/os2/sockets.c
--- apr-1.6.3-o/network_io/os2/sockets.c	2006-11-29 07:54:40.000000000 +1030
+++ apr-1.6.3/network_io/os2/sockets.c	2018-01-26 18:08:34.000000000 +1030
@@ -30,6 +30,10 @@
 #include <netdb.h>
 #include "apr_arch_os2calls.h"
 
+#ifdef __KLIBC__x
+static char generic_inaddr_any[16] = {0}; /* big enough for IPv4 or IPv6 */
+#endif
+
 static apr_status_t socket_cleanup(void *sock)
 {
     apr_socket_t *thesocket = sock;
@@ -38,6 +42,9 @@
         return APR_EINVALSOCK;
     }
 
+    /* Add this shutdown call. */
+    shutdown (thesocket->socketdes, 2);
+
     if (soclose(thesocket->socketdes) == 0) {
         thesocket->socketdes = -1;
         return APR_SUCCESS;
@@ -82,9 +89,6 @@
 APR_DECLARE(apr_status_t) apr_socket_create(apr_socket_t **new, int family, int type,
                                             int protocol, apr_pool_t *cont)
 {
-    int downgrade = (family == AF_UNSPEC);
-    apr_pollfd_t pfd;
-
     if (family == AF_UNSPEC) {
 #if APR_HAVE_IPV6
         family = AF_INET6;
@@ -96,12 +100,6 @@
     alloc_socket(new, cont);
 
     (*new)->socketdes = socket(family, type, protocol);
-#if APR_HAVE_IPV6
-    if ((*new)->socketdes < 0 && downgrade) {
-        family = AF_INET;
-        (*new)->socketdes = socket(family, type, protocol);
-    }
-#endif
 
     if ((*new)->socketdes < 0) {
         return APR_OS2_STATUS(sock_errno());
@@ -163,6 +161,7 @@
                                             apr_socket_t *sock,
                                             apr_pool_t *connection_context)
 {
+
     alloc_socket(new, connection_context);
     set_socket_vars(*new, sock->local_addr->sa.sin.sin_family, SOCK_STREAM, sock->protocol);
 
@@ -177,15 +176,60 @@
         return APR_OS2_STATUS(sock_errno());
     }
 
+#ifndef __KLIBC__x
     *(*new)->local_addr = *sock->local_addr;
     (*new)->local_addr->pool = connection_context;
     (*new)->remote_addr->port = ntohs((*new)->remote_addr->sa.sin.sin_port);
+#else
+    (*new)->remote_addr_unknown = 0;
 
+    *(*new)->local_addr = *sock->local_addr;
+
+    /* The above assignment just overwrote the pool entry. Setting the local_addr 
+       pool for the accepted socket back to what it should be.  Otherwise all 
+       allocations for this socket will come from a server pool that is not
+       freed until the process goes down.*/
+    (*new)->local_addr->pool = connection_context;
+#endif
     /* fix up any pointers which are no longer valid */
     if (sock->local_addr->sa.sin.sin_family == AF_INET) {
         (*new)->local_addr->ipaddr_ptr = &(*new)->local_addr->sa.sin.sin_addr;
     }
 
+#ifdef __KLIBC__x
+    (*new)->remote_addr->port = ntohs((*new)->remote_addr->sa.sin.sin_port);
+    if (sock->local_port_unknown) {
+        /* not likely for a listening socket, but theoretically possible :) */
+        (*new)->local_port_unknown = 1;
+    }
+
+#if APR_TCP_NODELAY_INHERITED
+    if (apr_is_option_set(sock, APR_TCP_NODELAY) == 1) {
+        apr_set_option(*new, APR_TCP_NODELAY, 1);
+    }
+#endif /* TCP_NODELAY_INHERITED */
+#if APR_O_NONBLOCK_INHERITED
+    if (apr_is_option_set(sock, APR_SO_NONBLOCK) == 1) {
+        apr_set_option(*new, APR_SO_NONBLOCK, 1);
+    }
+#endif /* APR_O_NONBLOCK_INHERITED */
+
+    if (sock->local_interface_unknown ||
+        !memcmp(sock->local_addr->ipaddr_ptr,
+                generic_inaddr_any,
+                sock->local_addr->ipaddr_len)) {
+        /* If the interface address inside the listening socket's local_addr wasn't 
+         * up-to-date, we don't know local interface of the connected socket either.
+         *
+         * If the listening socket was not bound to a specific interface, we
+         * don't know the local_addr of the connected socket.
+         */
+        (*new)->local_interface_unknown = 1;
+    }
+
+    (*new)->inherit = 0;
+
+#endif
     apr_pool_cleanup_register((*new)->pool, (void *)(*new), 
                         socket_cleanup, apr_pool_cleanup_null);
     return APR_SUCCESS;
@@ -194,6 +238,7 @@
 APR_DECLARE(apr_status_t) apr_socket_connect(apr_socket_t *sock,
                                              apr_sockaddr_t *sa)
 {
+#ifndef __KLIBC__x
     if ((connect(sock->socketdes, (struct sockaddr *)&sa->sa.sin, 
                  sa->salen) < 0) &&
         (sock_errno() != SOCEINPROGRESS)) {
@@ -206,6 +251,68 @@
         sock->remote_addr = sa;
         return APR_SUCCESS;
     }
+#else
+    int rc;        
+
+    do {
+        rc = connect(sock->socketdes,
+                     (const struct sockaddr *)&sa->sa.sin,
+                     sa->salen);
+    } while (rc == -1 && errno == EINTR);
+
+    /* we can see EINPROGRESS the first time connect is called on a non-blocking
+     * socket; if called again, we can see EALREADY
+     */
+    if ((rc == -1) && (errno == EINPROGRESS || errno == EALREADY)
+                   && (sock->timeout > 0)) {
+        rc = apr_wait_for_io_or_timeout(NULL, sock, 0);
+        if (rc != APR_SUCCESS) {
+            return rc;
+        }
+
+#ifdef SO_ERROR
+        {
+            int error;
+            apr_socklen_t len = sizeof(error);
+            if ((rc = getsockopt(sock->socketdes, SOL_SOCKET, SO_ERROR, 
+                                 (char *)&error, &len)) < 0) {
+                return errno;
+            }
+            if (error) {
+                return error;
+            }
+        }
+#endif /* SO_ERROR */
+    }
+
+    if (rc == -1 && errno != EISCONN) {
+        return errno;
+    }
+
+    if (memcmp(sa->ipaddr_ptr, generic_inaddr_any, sa->ipaddr_len)) {
+        /* A real remote address was passed in.  If the unspecified
+         * address was used, the actual remote addr will have to be
+         * determined using getpeername() if required. */
+        /* ### this should probably be a structure copy + fixup as per
+         * _accept()'s handling of local_addr */
+        sock->remote_addr = sa;
+        sock->remote_addr_unknown = 0;
+    }
+
+    if (sock->local_addr->port == 0) {
+        /* connect() got us an ephemeral port */
+        sock->local_port_unknown = 1;
+    }
+    if (!memcmp(sock->local_addr->ipaddr_ptr,
+                generic_inaddr_any,
+                sock->local_addr->ipaddr_len)) {
+        /* not bound to specific local interface; connect() had to assign
+         * one for the socket
+         */
+        sock->local_interface_unknown = 1;
+    }
+    return APR_SUCCESS;
+#endif
 }
 
 APR_DECLARE(apr_status_t) apr_socket_type_get(apr_socket_t *sock, int *type)
@@ -309,9 +416,38 @@
     return APR_SUCCESS;
 }
 
+
+/**
+ * Kill cleanup function registered by apr_socket_create
+ * @added 2014-12-27 SHL
+ */
+
+APR_DECLARE(void) apr_sock_cleanup_kill(apr_socket_t *apr_sock)
+{
+    apr_pool_cleanup_kill(apr_sock->pool, (void *)(apr_sock),
+                          socket_cleanup);
+}
+
 APR_POOL_IMPLEMENT_ACCESSOR(socket);
 
+#ifndef __KLIBC__
 APR_IMPLEMENT_INHERIT_SET(socket, inherit, pool, socket_cleanup)
 
 APR_IMPLEMENT_INHERIT_UNSET(socket, inherit, pool, socket_cleanup)
+#else
+/* Sockets cannot be inherited through the standard sockets
+ * inheritence.  WSADuplicateSocket must be used.
+ * This is not trivial to implement.
+ */
+
+APR_DECLARE(apr_status_t) apr_socket_inherit_set(apr_socket_t *socket)    
+{    
+    return APR_ENOTIMPL;
+}    
+
+APR_DECLARE(apr_status_t) apr_socket_inherit_unset(apr_socket_t *socket)    
+{    
+    return APR_ENOTIMPL;
+}    
+#endif
 
diff -ur apr-1.6.3-o/network_io/os2/sockopt.c apr-1.6.3/network_io/os2/sockopt.c
--- apr-1.6.3-o/network_io/os2/sockopt.c	2011-10-16 07:41:40.000000000 +1030
+++ apr-1.6.3/network_io/os2/sockopt.c	2018-01-26 18:08:34.000000000 +1030
@@ -24,9 +24,11 @@
 #include <sys/socket.h>
 #include <netinet/tcp.h>
 #include <netinet/in.h>
+#ifndef __INNOTEK_LIBC__
 #include <unistd.h>
+#endif
 #include <netdb.h>
-#include <sys/so_ioctl.h>
+#include <sys/ioctl.h>
 
 
 APR_DECLARE(apr_status_t) apr_socket_timeout_set(apr_socket_t *sock, 
@@ -107,10 +109,51 @@
 APR_DECLARE(apr_status_t) apr_socket_opt_get(apr_socket_t *sock, 
                                              apr_int32_t opt, apr_int32_t *on)
 {
-    switch(opt) {
-    default:
-        return APR_EINVAL;
+    int optval = 0;
+    int optlen = sizeof(optval);
+
+    struct linger  li;
+//    struct timeval ti;
+
+    if (opt & APR_SO_DEBUG) {
+        if (getsockopt(sock->socketdes, SOL_SOCKET, SO_DEBUG, (char *) &optval, &optlen) == -1) {
+            return APR_OS2_STATUS(sock_errno());
+        } else *on = (optval > 0);
+    }
+    if (opt & APR_SO_KEEPALIVE) {
+        if (getsockopt(sock->socketdes, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, &optlen) == -1) {
+            return APR_OS2_STATUS(sock_errno());
+        } else *on = (optval > 0);
+    }
+    if (opt & APR_SO_LINGER) {
+        if (getsockopt(sock->socketdes, SOL_SOCKET, SO_LINGER, (char *) &li, (int *)sizeof(struct linger)) == -1) {
+            return APR_OS2_STATUS(sock_errno());
+        } else *on = (li.l_onoff > 0);
+    }
+    if (opt & APR_SO_REUSEADDR) {
+        if (getsockopt(sock->socketdes, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, &optlen) == -1) {
+            return APR_OS2_STATUS(sock_errno());
+        } else *on = (optval > 0);
+    }
+    if (opt & APR_SO_SNDBUF) {
+        if (getsockopt(sock->socketdes, SOL_SOCKET, SO_SNDBUF, (char *) &on, &optlen) == -1) {
+            return APR_OS2_STATUS(sock_errno());
+        }
+    }
+    if (opt & APR_SO_RCVBUF) {
+        if (getsockopt(sock->socketdes, SOL_SOCKET, SO_RCVBUF, (char *) &on, &optlen) == -1) {
+            return APR_OS2_STATUS(sock_errno());
+        }
+    }
+    /* have to base this on receive timeout ??? */
+    if (opt & APR_SO_NONBLOCK) {
+        return APR_ENOTIMPL;
+    }
+    /* Windows only ? */
+    if (opt & APR_SO_DISCONNECTED) {
+        return APR_ENOTIMPL;
     }
+
     return APR_SUCCESS;
 }
 
Only in apr-1.6.3/passwd: apr_getpass.lo
Only in apr-1.6.3/passwd: apr_getpass.o
Only in apr-1.6.3: patch.log
diff -ur apr-1.6.3-o/poll/os2/poll.c apr-1.6.3/poll/os2/poll.c
--- apr-1.6.3-o/poll/os2/poll.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/poll/os2/poll.c	2018-01-26 18:30:30.000000000 +1030
@@ -17,6 +17,7 @@
 #include "apr.h"
 #include "apr_poll.h"
 #include "apr_arch_networkio.h"
+#include <stdlib.h>
 
 APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num,
                       apr_int32_t *nsds, apr_interval_time_t timeout)
@@ -103,3 +104,51 @@
 
     return APR_SUCCESS;
 }
+
+APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb,
+                                               apr_uint32_t size,
+                                               apr_pool_t *p,
+                                               apr_uint32_t flags,
+                                               apr_pollset_method_e method)
+{
+    return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb,
+                                            apr_uint32_t size,
+                                            apr_pool_t *p,
+                                            apr_uint32_t flags)
+{
+    return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
+                                         apr_pollfd_t *descriptor)
+{
+    return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
+                                            apr_pollfd_t *descriptor)
+{
+    return APR_ENOTIMPL;
+}
+
+
+APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb,
+                                          apr_interval_time_t timeout,
+                                          apr_pollcb_cb_t func,
+                                          void *baton)
+{
+    return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_pollcb_wakeup(apr_pollcb_t *pollcb)
+{
+    return APR_ENOTIMPL;
+}
+
+APR_DECLARE(const char *) apr_pollcb_method_name(apr_pollcb_t *pollcb)
+{
+    return APR_ENOTIMPL;
+}
Only in apr-1.6.3/poll/os2: pollset.c.orig
Only in apr-1.6.3/poll/os2: pollset.c.rej
Only in apr-1.6.3: sh-thd-1413481
Only in apr-1.6.3: sh-thd-1413482
Only in apr-1.6.3: sh-thd-1413487
Only in apr-1.6.3: sh-thd-1413488
Only in apr-1.6.3: sh-thd-1413489
Only in apr-1.6.3: sh-thd-1413490
Only in apr-1.6.3: sh-thd-1413491
Only in apr-1.6.3: sh-thd-1413493
Only in apr-1.6.3: sh-thd-1413495
Only in apr-1.6.3: sh-thd-1413496
Only in apr-1.6.3: sh-thd-1413497
Only in apr-1.6.3: sh-thd-1413499
Only in apr-1.6.3: sh-thd-1413503
Only in apr-1.6.3: sh-thd-1413504
Only in apr-1.6.3: sh-thd-1413505
Only in apr-1.6.3: sh-thd-1413506
Only in apr-1.6.3: sh-thd-1413507
Only in apr-1.6.3: sh-thd-1413508
Only in apr-1.6.3: sh-thd-1413509
Only in apr-1.6.3: sh-thd-1413510
Only in apr-1.6.3: sh-thd-1413511
Only in apr-1.6.3: sh-thd-1413515
Only in apr-1.6.3: sh-thd-1413516
Only in apr-1.6.3: sh-thd-1413518
Only in apr-1.6.3: sh-thd-1413520
Only in apr-1.6.3: sh-thd-1413521
Only in apr-1.6.3: sh-thd-1413523
Only in apr-1.6.3: sh-thd-1413524
Only in apr-1.6.3: sh-thd-1413526
Only in apr-1.6.3: sh-thd-1413527
Only in apr-1.6.3: sh-thd-1413528
Only in apr-1.6.3: sh-thd-1413531
Only in apr-1.6.3: sh-thd-1413534
Only in apr-1.6.3: sh-thd-1413535
Only in apr-1.6.3: sh-thd-1413536
Only in apr-1.6.3: sh-thd-1413537
Only in apr-1.6.3: sh-thd-1413539
Only in apr-1.6.3: sh-thd-1413540
Only in apr-1.6.3: sh-thd-1413541
Only in apr-1.6.3: sh-thd-1413542
Only in apr-1.6.3: sh-thd-1413544
Only in apr-1.6.3: sh-thd-1413545
Only in apr-1.6.3: sh-thd-1413546
Only in apr-1.6.3: sh-thd-1413547
Only in apr-1.6.3: sh-thd-1413548
Only in apr-1.6.3: sh-thd-1413549
Only in apr-1.6.3: sh-thd-1413552
Only in apr-1.6.3: sh-thd-1413557
Only in apr-1.6.3: sh-thd-1413559
Only in apr-1.6.3: sh-thd-1413561
Only in apr-1.6.3: sh-thd-1413562
Only in apr-1.6.3: sh-thd-1413563
Only in apr-1.6.3: sh-thd-1413564
Only in apr-1.6.3: sh-thd-1413565
Only in apr-1.6.3: sh-thd-1413566
Only in apr-1.6.3: sh-thd-1413568
Only in apr-1.6.3: sh-thd-1413570
Only in apr-1.6.3: sh-thd-1413571
Only in apr-1.6.3: sh-thd-1413572
Only in apr-1.6.3: sh-thd-1413573
Only in apr-1.6.3: sh-thd-1413575
Only in apr-1.6.3: sh-thd-1413577
Only in apr-1.6.3: sh-thd-1413578
Only in apr-1.6.3: sh-thd-1413579
Only in apr-1.6.3: sh-thd-1413580
Only in apr-1.6.3: sh-thd-1413581
Only in apr-1.6.3: sh-thd-1413582
Only in apr-1.6.3: sh-thd-1413583
Only in apr-1.6.3: sh-thd-1413585
Only in apr-1.6.3: sh-thd-1413586
Only in apr-1.6.3: sh-thd-1413587
Only in apr-1.6.3: sh-thd-1413588
Only in apr-1.6.3: sh-thd-1413589
Only in apr-1.6.3: sh-thd-1413590
Only in apr-1.6.3: sh-thd-1413593
Only in apr-1.6.3: sh-thd-1413594
Only in apr-1.6.3: sh-thd-1413595
Only in apr-1.6.3: sh-thd-1413598
Only in apr-1.6.3: sh-thd-1413599
Only in apr-1.6.3: sh-thd-1413601
Only in apr-1.6.3: sh-thd-1413603
Only in apr-1.6.3: sh-thd-1413604
Only in apr-1.6.3: sh-thd-1413605
Only in apr-1.6.3: sh-thd-1413606
Only in apr-1.6.3: sh-thd-1413608
Only in apr-1.6.3: sh-thd-1413610
Only in apr-1.6.3: sh-thd-1413611
Only in apr-1.6.3: sh-thd-1413613
Only in apr-1.6.3: sh-thd-1413614
Only in apr-1.6.3: sh-thd-1413615
Only in apr-1.6.3: sh-thd-1413616
Only in apr-1.6.3: sh-thd-1413617
Only in apr-1.6.3: sh-thd-1413619
Only in apr-1.6.3: sh-thd-1413620
Only in apr-1.6.3: sh-thd-1413621
Only in apr-1.6.3: sh-thd-1413622
Only in apr-1.6.3: sh-thd-1413623
Only in apr-1.6.3: sh-thd-1413625
Only in apr-1.6.3: sh-thd-1413626
Only in apr-1.6.3: sh-thd-1413628
Only in apr-1.6.3: sh-thd-1413629
Only in apr-1.6.3: sh-thd-1413632
Only in apr-1.6.3: sh-thd-1413637
Only in apr-1.6.3: sh-thd-1413638
Only in apr-1.6.3: sh-thd-1413639
Only in apr-1.6.3: sh-thd-1413640
Only in apr-1.6.3: sh-thd-1413641
Only in apr-1.6.3: sh-thd-1413642
Only in apr-1.6.3: sh-thd-1413643
Only in apr-1.6.3: sh-thd-1413645
Only in apr-1.6.3: sh-thd-1413646
Only in apr-1.6.3: sh-thd-1413647
Only in apr-1.6.3: sh-thd-1413649
Only in apr-1.6.3: sh-thd-1413650
Only in apr-1.6.3: sh-thd-1413651
Only in apr-1.6.3: sh-thd-1413653
Only in apr-1.6.3: sh-thd-1413654
Only in apr-1.6.3: sh-thd-1413655
Only in apr-1.6.3: sh-thd-1413657
Only in apr-1.6.3: sh-thd-1413658
Only in apr-1.6.3: sh-thd-1413659
Only in apr-1.6.3: sh-thd-1413661
Only in apr-1.6.3: sh-thd-1413662
Only in apr-1.6.3: sh-thd-1413664
Only in apr-1.6.3: sh-thd-1413665
Only in apr-1.6.3: sh-thd-1413667
Only in apr-1.6.3: sh-thd-1413668
Only in apr-1.6.3: sh-thd-1413669
Only in apr-1.6.3: sh-thd-1413670
Only in apr-1.6.3: sh-thd-1413672
Only in apr-1.6.3: sh-thd-1413673
Only in apr-1.6.3: sh-thd-1413675
Only in apr-1.6.3: sh-thd-1413676
Only in apr-1.6.3: sh-thd-1413678
Only in apr-1.6.3: sh-thd-1413679
Only in apr-1.6.3: sh-thd-1413680
Only in apr-1.6.3: sh-thd-1413681
Only in apr-1.6.3: sh-thd-1413682
Only in apr-1.6.3: sh-thd-1413683
Only in apr-1.6.3: sh-thd-1413685
Only in apr-1.6.3: sh-thd-1413686
Only in apr-1.6.3: sh-thd-1413688
Only in apr-1.6.3: sh-thd-1413690
Only in apr-1.6.3: sh-thd-1413691
Only in apr-1.6.3: sh-thd-1413692
Only in apr-1.6.3: sh-thd-1413693
Only in apr-1.6.3: sh-thd-1413694
Only in apr-1.6.3: sh-thd-1413695
Only in apr-1.6.3: sh-thd-1413697
Only in apr-1.6.3: sh-thd-1413698
Only in apr-1.6.3: sh-thd-1413700
Only in apr-1.6.3: sh-thd-1413701
Only in apr-1.6.3: sh-thd-1413702
Only in apr-1.6.3: sh-thd-1413703
Only in apr-1.6.3: sh-thd-1413704
Only in apr-1.6.3: sh-thd-1413706
Only in apr-1.6.3: sh-thd-1413708
Only in apr-1.6.3: sh-thd-1413709
Only in apr-1.6.3: sh-thd-1413712
Only in apr-1.6.3: sh-thd-1413713
Only in apr-1.6.3: sh-thd-1413715
Only in apr-1.6.3: sh-thd-1413716
Only in apr-1.6.3: sh-thd-1413718
Only in apr-1.6.3: sh-thd-1413720
Only in apr-1.6.3: sh-thd-1413721
Only in apr-1.6.3: sh-thd-1413726
Only in apr-1.6.3: sh-thd-1413727
Only in apr-1.6.3: sh-thd-1413728
Only in apr-1.6.3: sh-thd-1413731
Only in apr-1.6.3: sh-thd-1413732
Only in apr-1.6.3: sh-thd-1413733
Only in apr-1.6.3: sh-thd-1413734
Only in apr-1.6.3: sh-thd-1413735
Only in apr-1.6.3: sh-thd-1413736
Only in apr-1.6.3: sh-thd-1413737
Only in apr-1.6.3: sh-thd-1413740
Only in apr-1.6.3: sh-thd-1516929
Only in apr-1.6.3: sh-thd-1516930
Only in apr-1.6.3: sh-thd-1516931
Only in apr-1.6.3: sh-thd-1516932
Only in apr-1.6.3: sh-thd-1516933
Only in apr-1.6.3: sh-thd-1516934
Only in apr-1.6.3: sh-thd-1516935
Only in apr-1.6.3: sh-thd-1516936
Only in apr-1.6.3: sh-thd-1516937
Only in apr-1.6.3: sh-thd-1516938
Only in apr-1.6.3: sh-thd-1516939
Only in apr-1.6.3: sh-thd-1516940
Only in apr-1.6.3: sh-thd-1516941
Only in apr-1.6.3: sh-thd-1516942
Only in apr-1.6.3: sh-thd-1516943
Only in apr-1.6.3: sh-thd-1516944
Only in apr-1.6.3: sh-thd-1516945
Only in apr-1.6.3: sh-thd-1516946
Only in apr-1.6.3: sh-thd-1516947
Only in apr-1.6.3: sh-thd-1516948
Only in apr-1.6.3: sh-thd-1516949
Only in apr-1.6.3: sh-thd-1516950
Only in apr-1.6.3: sh-thd-1516951
Only in apr-1.6.3: sh-thd-1516952
Only in apr-1.6.3: sh-thd-1516953
Only in apr-1.6.3: sh-thd-1516954
Only in apr-1.6.3: sh-thd-1516955
Only in apr-1.6.3: sh-thd-1516956
Only in apr-1.6.3: sh-thd-1516957
Only in apr-1.6.3: sh-thd-1516958
Only in apr-1.6.3: sh-thd-1516959
Only in apr-1.6.3: sh-thd-1516960
Only in apr-1.6.3: sh-thd-1516961
Only in apr-1.6.3: sh-thd-2266234
Only in apr-1.6.3: sh-thd-2266235
Only in apr-1.6.3: sh-thd-2266236
Only in apr-1.6.3: sh-thd-2266237
Only in apr-1.6.3: sh-thd-2266238
Only in apr-1.6.3: sh-thd-2266239
Only in apr-1.6.3: sh-thd-2266240
Only in apr-1.6.3: sh-thd-2266241
Only in apr-1.6.3: sh-thd-2266242
Only in apr-1.6.3: sh-thd-2266243
Only in apr-1.6.3: sh-thd-2266244
Only in apr-1.6.3: sh-thd-2266245
Only in apr-1.6.3: sh-thd-2266246
Only in apr-1.6.3: sh-thd-2266247
Only in apr-1.6.3: sh-thd-2266248
Only in apr-1.6.3: sh-thd-2266249
Only in apr-1.6.3: sh-thd-2266250
Only in apr-1.6.3: sh-thd-2266251
Only in apr-1.6.3: sh-thd-2266252
Only in apr-1.6.3: sh-thd-2266253
Only in apr-1.6.3: sh-thd-2266254
Only in apr-1.6.3: sh-thd-2266255
Only in apr-1.6.3: sh-thd-2266256
Only in apr-1.6.3: sh-thd-2266257
Only in apr-1.6.3: sh-thd-2266258
Only in apr-1.6.3: sh-thd-2266259
Only in apr-1.6.3: sh-thd-2266260
Only in apr-1.6.3: sh-thd-2266261
Only in apr-1.6.3: sh-thd-2266262
Only in apr-1.6.3: sh-thd-2266263
Only in apr-1.6.3: sh-thd-2266264
Only in apr-1.6.3: sh-thd-2266265
Only in apr-1.6.3: sh-thd-2266266
Only in apr-1.6.3: sh-thd-2266267
Only in apr-1.6.3: sh-thd-2266268
Only in apr-1.6.3: sh-thd-2266269
Only in apr-1.6.3: sh-thd-2266270
Only in apr-1.6.3: sh-thd-2266271
Only in apr-1.6.3: sh-thd-2266272
Only in apr-1.6.3: sh-thd-2266273
Only in apr-1.6.3: sh-thd-2266274
Only in apr-1.6.3: sh-thd-2266275
Only in apr-1.6.3: sh-thd-2266276
Only in apr-1.6.3: sh-thd-2266277
Only in apr-1.6.3: sh-thd-2266278
Only in apr-1.6.3: sh-thd-2266279
Only in apr-1.6.3: sh-thd-2266280
Only in apr-1.6.3: sh-thd-2266281
Only in apr-1.6.3: sh-thd-2266282
Only in apr-1.6.3: sh-thd-2266283
Only in apr-1.6.3: sh-thd-2266284
Only in apr-1.6.3: sh-thd-2266285
Only in apr-1.6.3: sh-thd-2266286
Only in apr-1.6.3: sh-thd-2266287
Only in apr-1.6.3: sh-thd-2266288
Only in apr-1.6.3: sh-thd-2266289
Only in apr-1.6.3: sh-thd-2266290
Only in apr-1.6.3: sh-thd-2266291
Only in apr-1.6.3: sh-thd-2266292
Only in apr-1.6.3: sh-thd-2266293
Only in apr-1.6.3: sh-thd-2266294
Only in apr-1.6.3: sh-thd-2266295
Only in apr-1.6.3: sh-thd-2266296
Only in apr-1.6.3: sh-thd-2266297
Only in apr-1.6.3: sh-thd-2266298
Only in apr-1.6.3: sh-thd-2266299
Only in apr-1.6.3: sh-thd-2266301
Only in apr-1.6.3: sh-thd-2266302
Only in apr-1.6.3: sh-thd-2266303
Only in apr-1.6.3: sh-thd-2266304
Only in apr-1.6.3: sh-thd-2266305
Only in apr-1.6.3: sh-thd-2266306
Only in apr-1.6.3: sh-thd-2266307
Only in apr-1.6.3: sh-thd-2266308
Only in apr-1.6.3: sh-thd-2266309
Only in apr-1.6.3: sh-thd-2266310
Only in apr-1.6.3: sh-thd-2266311
Only in apr-1.6.3: sh-thd-2266312
Only in apr-1.6.3: sh-thd-2266313
Only in apr-1.6.3: sh-thd-2266314
Only in apr-1.6.3: sh-thd-2266315
Only in apr-1.6.3: sh-thd-2266316
Only in apr-1.6.3: sh-thd-2266317
Only in apr-1.6.3: sh-thd-2266318
Only in apr-1.6.3: sh-thd-2266319
Only in apr-1.6.3: sh-thd-2266320
Only in apr-1.6.3: sh-thd-2266321
Only in apr-1.6.3: sh-thd-2266322
Only in apr-1.6.3: sh-thd-2266323
Only in apr-1.6.3: sh-thd-2266324
Only in apr-1.6.3: sh-thd-2266325
Only in apr-1.6.3: sh-thd-2266326
Only in apr-1.6.3: sh-thd-2266327
Only in apr-1.6.3: sh-thd-2266328
Only in apr-1.6.3: sh-thd-2266329
Only in apr-1.6.3: sh-thd-2266330
Only in apr-1.6.3: sh-thd-2266331
Only in apr-1.6.3: sh-thd-2266332
Only in apr-1.6.3: sh-thd-2266333
Only in apr-1.6.3: sh-thd-2266334
Only in apr-1.6.3: sh-thd-2266335
Only in apr-1.6.3: sh-thd-2266336
Only in apr-1.6.3: sh-thd-2266338
Only in apr-1.6.3: sh-thd-2266339
Only in apr-1.6.3: sh-thd-2266340
Only in apr-1.6.3: sh-thd-2266341
Only in apr-1.6.3: sh-thd-2266342
Only in apr-1.6.3: sh-thd-2266344
Only in apr-1.6.3: sh-thd-2266345
Only in apr-1.6.3: sh-thd-2266346
Only in apr-1.6.3: sh-thd-2266347
Only in apr-1.6.3: sh-thd-2266348
Only in apr-1.6.3: sh-thd-2266349
Only in apr-1.6.3: sh-thd-2266350
Only in apr-1.6.3: sh-thd-2266351
Only in apr-1.6.3: sh-thd-2266352
Only in apr-1.6.3: sh-thd-2266353
Only in apr-1.6.3: sh-thd-2266354
Only in apr-1.6.3: sh-thd-2266355
Only in apr-1.6.3: sh-thd-2266356
Only in apr-1.6.3: sh-thd-2266357
Only in apr-1.6.3: sh-thd-2266359
Only in apr-1.6.3: sh-thd-2266360
Only in apr-1.6.3: sh-thd-2266361
Only in apr-1.6.3: sh-thd-2266363
Only in apr-1.6.3: sh-thd-2266364
Only in apr-1.6.3: sh-thd-2266365
Only in apr-1.6.3: sh-thd-3216086
Only in apr-1.6.3: sh-thd-3216104
Only in apr-1.6.3: sh-thd-3216106
Only in apr-1.6.3: sh-thd-3216113
Only in apr-1.6.3: sh-thd-3216125
Only in apr-1.6.3: sh-thd-3216345
Only in apr-1.6.3: sh-thd-3216504
Only in apr-1.6.3: sh-thd-3216518
Only in apr-1.6.3: sh-thd-3216599
Only in apr-1.6.3: sh-thd-3216622
Only in apr-1.6.3: sh-thd-3216822
Only in apr-1.6.3: sh-thd-3216868
Only in apr-1.6.3: sh-thd-4005494
Only in apr-1.6.3: sh-thd-4005495
Only in apr-1.6.3: sh-thd-4005496
Only in apr-1.6.3: sh-thd-4005497
Only in apr-1.6.3: sh-thd-4005498
Only in apr-1.6.3: sh-thd-4005499
Only in apr-1.6.3: sh-thd-4005500
Only in apr-1.6.3: sh-thd-4005501
Only in apr-1.6.3: sh-thd-4005502
Only in apr-1.6.3: sh-thd-4005503
Only in apr-1.6.3: sh-thd-4005504
Only in apr-1.6.3: sh-thd-4005505
Only in apr-1.6.3: sh-thd-4005506
Only in apr-1.6.3: sh-thd-4005507
Only in apr-1.6.3: sh-thd-4005508
Only in apr-1.6.3: sh-thd-4005509
Only in apr-1.6.3: sh-thd-4005510
Only in apr-1.6.3: sh-thd-4005511
Only in apr-1.6.3: sh-thd-4005512
Only in apr-1.6.3: sh-thd-4005513
Only in apr-1.6.3: sh-thd-4005514
Only in apr-1.6.3: sh-thd-4005515
Only in apr-1.6.3: sh-thd-4005516
Only in apr-1.6.3: sh-thd-4005517
Only in apr-1.6.3: sh-thd-4005518
Only in apr-1.6.3: sh-thd-4005519
Only in apr-1.6.3: sh-thd-4005520
Only in apr-1.6.3: sh-thd-4005521
Only in apr-1.6.3: sh-thd-4005522
Only in apr-1.6.3: sh-thd-4005523
Only in apr-1.6.3: sh-thd-4005524
Only in apr-1.6.3: sh-thd-4005525
Only in apr-1.6.3: sh-thd-4005526
Only in apr-1.6.3: sh-thd-4005527
Only in apr-1.6.3: sh-thd-4005528
Only in apr-1.6.3: sh-thd-4005529
Only in apr-1.6.3: sh-thd-4005530
Only in apr-1.6.3: sh-thd-4005531
Only in apr-1.6.3: sh-thd-4005532
Only in apr-1.6.3: sh-thd-4005533
Only in apr-1.6.3: sh-thd-4005534
Only in apr-1.6.3: sh-thd-4005535
Only in apr-1.6.3: sh-thd-4005536
Only in apr-1.6.3: sh-thd-4005537
Only in apr-1.6.3: sh-thd-4005538
Only in apr-1.6.3: sh-thd-4005539
Only in apr-1.6.3: sh-thd-4005540
Only in apr-1.6.3: sh-thd-4005541
Only in apr-1.6.3: sh-thd-4005542
Only in apr-1.6.3: sh-thd-4005543
Only in apr-1.6.3: sh-thd-4005544
Only in apr-1.6.3: sh-thd-4005545
Only in apr-1.6.3: sh-thd-4005546
Only in apr-1.6.3: sh-thd-4005547
Only in apr-1.6.3: sh-thd-4005548
Only in apr-1.6.3: sh-thd-4005549
Only in apr-1.6.3: sh-thd-4005550
Only in apr-1.6.3: sh-thd-4005551
Only in apr-1.6.3: sh-thd-4005552
Only in apr-1.6.3: sh-thd-4005553
Only in apr-1.6.3: sh-thd-4005554
Only in apr-1.6.3: sh-thd-4005555
Only in apr-1.6.3: sh-thd-4005556
Only in apr-1.6.3: sh-thd-4005557
Only in apr-1.6.3: sh-thd-4005558
Only in apr-1.6.3: sh-thd-4005559
Only in apr-1.6.3: sh-thd-4005560
Only in apr-1.6.3: sh-thd-4075295
Only in apr-1.6.3: sh-thd-4075297
Only in apr-1.6.3: sh-thd-4075304
Only in apr-1.6.3: sh-thd-4075311
Only in apr-1.6.3: sh-thd-4075315
Only in apr-1.6.3: sh-thd-4075318
Only in apr-1.6.3: sh-thd-4075321
Only in apr-1.6.3: sh-thd-4075327
Only in apr-1.6.3: sh-thd-4075334
Only in apr-1.6.3: sh-thd-4075336
Only in apr-1.6.3: sh-thd-4075339
Only in apr-1.6.3: sh-thd-4075342
Only in apr-1.6.3: sh-thd-4075344
Only in apr-1.6.3: sh-thd-4075348
Only in apr-1.6.3: sh-thd-4075358
Only in apr-1.6.3: sh-thd-4075361
Only in apr-1.6.3: sh-thd-4075373
Only in apr-1.6.3: sh-thd-4075378
Only in apr-1.6.3: sh-thd-4075380
Only in apr-1.6.3: sh-thd-4075385
Only in apr-1.6.3: sh-thd-4075387
Only in apr-1.6.3: sh-thd-4075396
Only in apr-1.6.3: sh-thd-4075400
Only in apr-1.6.3: sh-thd-4075404
Only in apr-1.6.3: sh-thd-4075409
Only in apr-1.6.3: sh-thd-4075410
Only in apr-1.6.3: sh-thd-4075411
Only in apr-1.6.3: sh-thd-4075414
Only in apr-1.6.3: sh-thd-4075416
Only in apr-1.6.3: sh-thd-4075419
Only in apr-1.6.3: sh-thd-4075421
Only in apr-1.6.3: sh-thd-4075426
Only in apr-1.6.3: sh-thd-4075432
Only in apr-1.6.3: sh-thd-4075433
Only in apr-1.6.3: sh-thd-4075434
Only in apr-1.6.3: sh-thd-4075436
Only in apr-1.6.3: sh-thd-4075440
Only in apr-1.6.3: sh-thd-4075452
Only in apr-1.6.3: sh-thd-4075462
Only in apr-1.6.3: sh-thd-4075467
Only in apr-1.6.3: sh-thd-4075470
Only in apr-1.6.3: sh-thd-4075476
Only in apr-1.6.3: sh-thd-4075479
Only in apr-1.6.3: sh-thd-4075481
Only in apr-1.6.3: sh-thd-4075487
Only in apr-1.6.3: sh-thd-4075489
Only in apr-1.6.3: sh-thd-4075493
Only in apr-1.6.3: sh-thd-4075495
Only in apr-1.6.3: sh-thd-4075500
Only in apr-1.6.3: sh-thd-4075501
Only in apr-1.6.3: sh-thd-4075503
Only in apr-1.6.3: sh-thd-4075526
Only in apr-1.6.3: sh-thd-4075527
Only in apr-1.6.3: sh-thd-4075529
Only in apr-1.6.3: sh-thd-4075551
Only in apr-1.6.3: sh-thd-4075552
Only in apr-1.6.3: sh-thd-4075561
Only in apr-1.6.3: sh-thd-4075564
Only in apr-1.6.3: sh-thd-4075566
Only in apr-1.6.3: sh-thd-4075567
Only in apr-1.6.3: sh-thd-4075573
Only in apr-1.6.3: sh-thd-4075577
Only in apr-1.6.3: sh-thd-4075580
Only in apr-1.6.3: sh-thd-4075593
Only in apr-1.6.3: sh-thd-4075596
Only in apr-1.6.3: sh-thd-4075604
Only in apr-1.6.3: sh-thd-4075606
Only in apr-1.6.3: sh-thd-4075609
Only in apr-1.6.3: sh-thd-4075620
Only in apr-1.6.3: sh-thd-4075621
Only in apr-1.6.3: sh-thd-4075624
Only in apr-1.6.3: sh-thd-4075635
Only in apr-1.6.3: sh-thd-4075639
Only in apr-1.6.3: sh-thd-4075640
Only in apr-1.6.3: sh-thd-4075650
Only in apr-1.6.3: sh-thd-4075654
Only in apr-1.6.3: sh-thd-4075656
Only in apr-1.6.3: sh-thd-4075657
Only in apr-1.6.3: sh-thd-4075659
Only in apr-1.6.3: sh-thd-4075668
Only in apr-1.6.3: sh-thd-4075672
Only in apr-1.6.3: sh-thd-4075684
Only in apr-1.6.3: sh-thd-4075686
Only in apr-1.6.3: sh-thd-4075695
Only in apr-1.6.3: sh-thd-4075697
Only in apr-1.6.3: sh-thd-4075711
Only in apr-1.6.3: sh-thd-4075712
Only in apr-1.6.3: sh-thd-4075716
Only in apr-1.6.3: sh-thd-4075723
Only in apr-1.6.3: sh-thd-4075727
Only in apr-1.6.3: sh-thd-4075729
Only in apr-1.6.3: sh-thd-4075730
Only in apr-1.6.3: sh-thd-4075731
Only in apr-1.6.3: sh-thd-4075745
Only in apr-1.6.3: sh-thd-4075749
Only in apr-1.6.3: sh-thd-4075753
Only in apr-1.6.3: sh-thd-4075760
Only in apr-1.6.3: sh-thd-4075762
Only in apr-1.6.3: sh-thd-4075763
Only in apr-1.6.3: sh-thd-4075765
Only in apr-1.6.3: sh-thd-4075766
Only in apr-1.6.3: sh-thd-4075768
Only in apr-1.6.3: sh-thd-4075769
Only in apr-1.6.3: sh-thd-4075771
Only in apr-1.6.3: sh-thd-4075772
Only in apr-1.6.3: sh-thd-4075774
Only in apr-1.6.3: sh-thd-4075776
Only in apr-1.6.3: sh-thd-4075779
Only in apr-1.6.3: sh-thd-4075784
Only in apr-1.6.3: sh-thd-4075788
Only in apr-1.6.3: sh-thd-4075796
Only in apr-1.6.3: sh-thd-4075797
Only in apr-1.6.3: sh-thd-4075798
Only in apr-1.6.3: sh-thd-4075799
Only in apr-1.6.3: sh-thd-4075809
diff -ur apr-1.6.3-o/shmem/os2/shm.c apr-1.6.3/shmem/os2/shm.c
--- apr-1.6.3-o/shmem/os2/shm.c	2014-04-28 22:45:02.000000000 +0930
+++ apr-1.6.3/shmem/os2/shm.c	2018-01-26 18:08:34.000000000 +1030
@@ -46,7 +46,12 @@
         flags |= OBJ_GETTABLE;
     }
 
-    rc = DosAllocSharedMem(&(newm->memblock), name, reqsize, flags);
+    /* First try to allocate shared memory in HMA */
+    rc = DosAllocSharedMem(&(newm->memblock), name, reqsize, flags | OBJ_ANY);
+
+    if (rc) {
+        rc = DosAllocSharedMem(&(newm->memblock), name, reqsize, flags);
+    }
 
     if (rc) {
         return APR_OS2_STATUS(rc);
@@ -67,7 +72,15 @@
 
 APR_DECLARE(apr_status_t) apr_shm_destroy(apr_shm_t *m)
 {
-    DosFreeMem(m->memblock);
+    int rc;
+
+    rc = DosFreeMem(m->memblock);
+
+    // MKG: added might not be good
+    if (rc) {
+        return APR_OS2_STATUS(rc);
+    }
+
     return APR_SUCCESS;
 }
 
@@ -92,9 +105,16 @@
     ULONG flags = PAG_READ|PAG_WRITE;
 
     newm->pool = pool;
+
+    //MKG: should be able to get unnamed memory ????
+    if (filename) {
+
     name = apr_pstrcat(pool, "\\SHAREMEM\\", filename, NULL);
 
     rc = DosGetNamedSharedMem(&(newm->memblock), name, flags);
+    } else {
+        rc = DosGetSharedMem(&(newm->memblock), flags);
+    }
 
     if (rc) {
         return APR_FROM_OS_ERROR(rc);
Only in apr-1.6.3/shmem/os2: shm.c.orig
Only in apr-1.6.3/strings: apr_cpystrn.lo
Only in apr-1.6.3/strings: apr_cpystrn.o
Only in apr-1.6.3/strings: apr_cstr.lo
Only in apr-1.6.3/strings: apr_cstr.o
Only in apr-1.6.3/strings: apr_fnmatch.lo
Only in apr-1.6.3/strings: apr_fnmatch.o
Only in apr-1.6.3/strings: apr_snprintf.lo
Only in apr-1.6.3/strings: apr_snprintf.o
Only in apr-1.6.3/strings: apr_strings.lo
Only in apr-1.6.3/strings: apr_strings.o
Only in apr-1.6.3/strings: apr_strnatcmp.lo
Only in apr-1.6.3/strings: apr_strnatcmp.o
Only in apr-1.6.3/strings: apr_strtok.lo
Only in apr-1.6.3/strings: apr_strtok.o
diff -ur apr-1.6.3-o/support/unix/waitio.c apr-1.6.3/support/unix/waitio.c
--- apr-1.6.3-o/support/unix/waitio.c	2013-10-04 00:00:16.000000000 +0930
+++ apr-1.6.3/support/unix/waitio.c	2018-01-26 18:08:34.000000000 +1030
@@ -22,7 +22,7 @@
 
 /* The only case where we don't use wait_for_io_or_timeout is on
  * pre-BONE BeOS, so this check should be sufficient and simpler */
-#if !defined(BEOS_R5) && !defined(OS2) && APR_FILES_AS_SOCKETS
+#if (!defined(BEOS_R5) && APR_FILES_AS_SOCKETS) || defined(__KLIBC__)
 #define USE_WAIT_FOR_IO
 #endif
 
Only in apr-1.6.3/tables: apr_hash.lo
Only in apr-1.6.3/tables: apr_hash.o
Only in apr-1.6.3/tables: apr_skiplist.lo
Only in apr-1.6.3/tables: apr_skiplist.o
Only in apr-1.6.3/tables: apr_tables.lo
Only in apr-1.6.3/tables: apr_tables.o
diff -ur apr-1.6.3-o/test/abts.c apr-1.6.3/test/abts.c
--- apr-1.6.3-o/test/abts.c	2013-11-13 00:27:38.000000000 +1030
+++ apr-1.6.3/test/abts.c	2018-01-26 18:08:34.000000000 +1030
@@ -17,6 +17,8 @@
 #include "abts.h"
 #include "abts_tests.h"
 #include "testutil.h"
+#define INCL_LOADEXCEPTQ
+#include "exceptq.h"
 
 #define ABTS_STAT_SIZE 6
 static char status[ABTS_STAT_SIZE] = {'|', '/', '-', '|', '\\', '-'};
@@ -382,11 +384,13 @@
 }
 
 int main(int argc, const char *const argv[]) {
+    EXCEPTIONREGISTRATIONRECORD exRegRec;
     int i;
     int rv;
     int list_provided = 0;
     abts_suite *suite = NULL;
    
+    LoadExceptq(&exRegRec, "I", "testall");
     initialize();
 
     quiet = !isatty(STDOUT_FILENO);
@@ -430,6 +434,7 @@
     }
 
     rv = report(suite);
+    UninstallExceptq(&exRegRec);
     return rv;
 }
        
Only in apr-1.6.3/test: build
Only in apr-1.6.3/test: echod.map
Only in apr-1.6.3/test: globalmutexchild.map
Only in apr-1.6.3/test/internal: Makefile
Only in apr-1.6.3/test: Makefile
Only in apr-1.6.3/test: occhild.map
diff -ur apr-1.6.3-o/test/proc_child.c apr-1.6.3/test/proc_child.c
--- apr-1.6.3-o/test/proc_child.c	2007-10-15 05:54:12.000000000 +1030
+++ apr-1.6.3/test/proc_child.c	2018-01-26 18:08:34.000000000 +1030
@@ -7,11 +7,17 @@
 #include <io.h>
 #endif
 #include <stdlib.h>
+#ifdef __INNOTEK_LIBC__
+#include <fcntl.h>
+#endif
 
 int main(void)
 {
     char buf[256];
     int bytes;
+#if defined(__WATCOMC__)||defined(__INNOTEK_LIBC__)
+    setmode(STDIN_FILENO, O_BINARY);
+#endif
     
     bytes = (int)read(STDIN_FILENO, buf, 256);
     if (bytes > 0)
Only in apr-1.6.3/test: proc_child.map
Only in apr-1.6.3/test: readchild.map
Only in apr-1.6.3/test: sendfile.map
Only in apr-1.6.3/test: sockchild.map
Only in apr-1.6.3/test: sockperf.map
Only in apr-1.6.3/test: testall.map
diff -ur apr-1.6.3-o/test/testcond.c apr-1.6.3/test/testcond.c
--- apr-1.6.3-o/test/testcond.c	2007-11-18 11:05:56.000000000 +1030
+++ apr-1.6.3/test/testcond.c	2018-01-26 18:08:34.000000000 +1030
@@ -652,9 +652,10 @@
 #endif
     suite = ADD_SUITE(suite)
 
-#if !APR_HAS_THREADS
+#if !APR_HAS_THREADS 
     abts_run_test(suite, threads_not_impl, NULL);
 #else
+#ifndef __OS2__
     abts_run_test(suite, lost_signal, NULL);
     abts_run_test(suite, dynamic_binding, NULL);
     abts_run_test(suite, broadcast_threads, NULL);
@@ -665,6 +666,7 @@
     abts_run_test(suite, pipe_producer_consumer, NULL);
     abts_run_test(suite, ping_pong, NULL);
 #endif
+#endif
 
     return suite;
 }
diff -ur apr-1.6.3-o/test/testdir.c apr-1.6.3/test/testdir.c
--- apr-1.6.3-o/test/testdir.c	2014-01-21 21:54:46.000000000 +1030
+++ apr-1.6.3/test/testdir.c	2018-01-26 18:08:34.000000000 +1030
@@ -31,6 +31,7 @@
     apr_finfo_t finfo;
 
     rv = apr_dir_make("data/testdir", APR_UREAD | APR_UWRITE | APR_UEXECUTE, p);
+
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
     rv = apr_stat(&finfo, "data/testdir", APR_FINFO_TYPE, p);
diff -ur apr-1.6.3-o/test/testfile.c apr-1.6.3/test/testfile.c
--- apr-1.6.3-o/test/testfile.c	2017-07-01 06:42:30.000000000 +0930
+++ apr-1.6.3/test/testfile.c	2018-01-26 18:08:34.000000000 +1030
@@ -248,6 +248,7 @@
     APR_ASSERT_SUCCESS(tc, "Open test file " FILENAME, rv);
 
     rv = apr_file_read(filetest, str, &nbytes);
+
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
     ABTS_SIZE_EQUAL(tc, strlen(TESTSTR), nbytes);
     ABTS_STR_EQUAL(tc, TESTSTR, str);
@@ -1263,7 +1264,6 @@
     abts_run_test(suite, test_fail_read_flush, NULL);
     abts_run_test(suite, test_buffer_set_get, NULL);
     abts_run_test(suite, test_xthread, NULL);
-
     return suite;
 }
 
Only in apr-1.6.3/test: testfile.c.orig
diff -ur apr-1.6.3-o/test/testfileinfo.c apr-1.6.3/test/testfileinfo.c
--- apr-1.6.3-o/test/testfileinfo.c	2010-03-08 01:24:06.000000000 +1030
+++ apr-1.6.3/test/testfileinfo.c	2018-01-26 18:08:34.000000000 +1030
@@ -256,7 +256,9 @@
     abts_run_test(suite, test_stat, NULL);
     abts_run_test(suite, test_stat_eq_finfo, NULL);
     abts_run_test(suite, test_buffered_write_size, NULL);
+#ifndef OS2
     abts_run_test(suite, test_mtime_set, NULL);
+#endif
 
     return suite;
 }
diff -ur apr-1.6.3-o/test/testlock.c apr-1.6.3/test/testlock.c
--- apr-1.6.3-o/test/testlock.c	2017-05-25 00:51:42.000000000 +0930
+++ apr-1.6.3/test/testlock.c	2018-01-26 18:08:34.000000000 +1030
@@ -213,6 +213,7 @@
     apr_thread_rwlock_destroy(rwlock);
 }
 
+
 static void test_cond(abts_case *tc, void *data)
 {
     apr_thread_t *p1, *p2, *p3, *p4, *c1;
@@ -324,9 +325,11 @@
 #else
     abts_run_test(suite, test_thread_mutex, NULL);
     abts_run_test(suite, test_thread_rwlock, NULL);
+#ifndef OS2 /* apr_thread_cond_* not implements on os2 */
     abts_run_test(suite, test_cond, NULL);
     abts_run_test(suite, test_timeoutcond, NULL);
 #endif
+#endif
 
     return suite;
 }
Only in apr-1.6.3/test: testlockperf.map
Only in apr-1.6.3/test: testmutexscope.map
diff -ur apr-1.6.3-o/test/testnames.c apr-1.6.3/test/testnames.c
--- apr-1.6.3-o/test/testnames.c	2015-06-18 18:12:20.000000000 +0930
+++ apr-1.6.3/test/testnames.c	2018-01-26 18:08:34.000000000 +1030
@@ -31,6 +31,8 @@
 #define ABS_ROOT "C:/"
 #elif defined(NETWARE)
 #define ABS_ROOT "SYS:/"
+#elif defined(__OS2__)
+#define ABS_ROOT "C:/"
 #else
 #define ABS_ROOT "/"
 #endif
@@ -92,6 +94,7 @@
      * the case of the test directory:
      */
     rv = apr_filepath_merge(&dstpath, "", "../test", APR_FILEPATH_TRUENAME, p);
+fprintf(stderr,"dstpath3 = %s, rv = %d\n",dstpath,rv);
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
     ABTS_STR_EQUAL(tc, "../test", dstpath);
 }
@@ -146,7 +149,6 @@
     rv = apr_filepath_merge(&dstpath, "foo/bar", "../baz", 
                             APR_FILEPATH_NOTRELATIVE, p);
     apr_strerror(rv, errmsg, sizeof(errmsg));
-
     ABTS_PTR_EQUAL(tc, NULL, dstpath);
     ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_ERELATIVE(rv));
     ABTS_STR_EQUAL(tc, "The given path is relative", errmsg);
@@ -161,7 +163,6 @@
     rv = apr_filepath_merge(&dstpath, ABS_ROOT"foo/bar", "../baz", 
                             APR_FILEPATH_NOTABSOLUTE, p);
     apr_strerror(rv, errmsg, sizeof(errmsg));
-
     ABTS_PTR_EQUAL(tc, NULL, dstpath);
     ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_EABSOLUTE(rv));
     ABTS_STR_EQUAL(tc, "The given path is absolute", errmsg);
diff -ur apr-1.6.3-o/test/testpipe.c apr-1.6.3/test/testpipe.c
--- apr-1.6.3-o/test/testpipe.c	2016-03-25 11:58:12.000000000 +1030
+++ apr-1.6.3/test/testpipe.c	2018-01-26 18:08:34.000000000 +1030
@@ -190,6 +190,7 @@
 {
     suite = ADD_SUITE(suite)
 
+#if 1
     abts_run_test(suite, create_pipe, NULL);
     abts_run_test(suite, close_pipe, NULL);
     abts_run_test(suite, set_timeout, NULL);
@@ -197,9 +198,11 @@
     abts_run_test(suite, read_write, NULL);
     abts_run_test(suite, close_pipe, NULL);
     abts_run_test(suite, read_write_notimeout, NULL);
+#endif
     abts_run_test(suite, test_pipe_writefull, NULL);
+#if 1
     abts_run_test(suite, close_pipe, NULL);
-
+#endif
     return suite;
 }
 
diff -ur apr-1.6.3-o/test/testprocmutex.c apr-1.6.3/test/testprocmutex.c
--- apr-1.6.3-o/test/testprocmutex.c	2017-05-25 00:51:42.000000000 +0930
+++ apr-1.6.3/test/testprocmutex.c	2018-01-26 18:08:34.000000000 +1030
@@ -115,6 +115,7 @@
     int n;
  
     rv = apr_proc_mutex_create(&proc_lock, lockname, mech, p);
+
     APR_ASSERT_SUCCESS(tc, "create the mutex", rv);
     if (rv != APR_SUCCESS)
         return;
@@ -122,8 +123,10 @@
     for (n = 0; n < CHILDREN; n++)
         make_child(tc, 0, &child[n], p);
 
+
     for (n = 0; n < CHILDREN; n++)
         await_child(tc, child[n]);
+
     
     ABTS_ASSERT(tc, "Locks don't appear to work", *x == MAX_COUNTER);
 
diff -ur apr-1.6.3-o/test/testshm.c apr-1.6.3/test/testshm.c
--- apr-1.6.3-o/test/testshm.c	2014-04-28 22:45:02.000000000 +0930
+++ apr-1.6.3/test/testshm.c	2018-01-26 18:08:34.000000000 +1030
@@ -126,7 +126,6 @@
 
     boxes = apr_shm_baseaddr_get(shm);
     ABTS_PTR_NOTNULL(tc, boxes);
-
     rv = apr_proc_fork(&proc, p);
     if (rv == APR_INCHILD) { /* child */
         int num = msgwait(5, 0, N_BOXES);
diff -ur apr-1.6.3-o/test/testshm.h apr-1.6.3/test/testshm.h
--- apr-1.6.3-o/test/testshm.h	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/test/testshm.h	2018-01-26 18:08:34.000000000 +1030
@@ -24,8 +24,14 @@
 mbox *boxes;
 
 #define N_BOXES 10
+#ifndef __OS2__
 #define SHARED_SIZE (apr_size_t)(N_BOXES * sizeof(mbox))
 #define SHARED_FILENAME "data/apr.testshm.shm"
+#else
+#define SHARED_SIZE (apr_size_t)(N_BOXES * 4096)
+#define SHARED_FILENAME "data\\apr.testshm.shm"
+#endif
+
 #define N_MESSAGES 100
 #define MSG "Sending a message"
 
Only in apr-1.6.3/test: testshmconsumer.map
Only in apr-1.6.3/test: testshmproducer.map
diff -ur apr-1.6.3-o/test/testsockopt.c apr-1.6.3/test/testsockopt.c
--- apr-1.6.3-o/test/testsockopt.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/test/testsockopt.c	2018-01-26 18:08:34.000000000 +1030
@@ -38,7 +38,6 @@
 
     rv = apr_socket_opt_set(sock, APR_SO_KEEPALIVE, 1);
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
-
     rv = apr_socket_opt_get(sock, APR_SO_KEEPALIVE, &ck);
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
     ABTS_INT_EQUAL(tc, 1, ck);
Only in apr-1.6.3/test: tryread.map
diff -ur apr-1.6.3-o/threadproc/os2/proc.c apr-1.6.3/threadproc/os2/proc.c
--- apr-1.6.3-o/threadproc/os2/proc.c	2014-04-28 21:38:38.000000000 +0930
+++ apr-1.6.3/threadproc/os2/proc.c	2018-01-26 18:08:34.000000000 +1030
@@ -41,22 +41,13 @@
 
 APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new, apr_pool_t *pool)
 {
-    (*new) = (apr_procattr_t *)apr_palloc(pool, 
-              sizeof(apr_procattr_t));
+    (*new) = (apr_procattr_t *)apr_pcalloc(pool, sizeof(apr_procattr_t));
 
     if ((*new) == NULL) {
         return APR_ENOMEM;
     }
     (*new)->pool = pool;
-    (*new)->parent_in = NULL;
-    (*new)->child_in = NULL;
-    (*new)->parent_out = NULL;
-    (*new)->child_out = NULL;
-    (*new)->parent_err = NULL;
-    (*new)->child_err = NULL;
-    (*new)->currdir = NULL; 
     (*new)->cmdtype = APR_PROGRAM;
-    (*new)->detached = FALSE;
     return APR_SUCCESS;
 }
 
@@ -110,13 +101,14 @@
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_procattr_child_in_set(apr_procattr_t *attr, apr_file_t *child_in,
-                                   apr_file_t *parent_in)
+APR_DECLARE(apr_status_t) apr_procattr_child_in_set(apr_procattr_t *attr,
+                                                    apr_file_t *child_in,
+                                                    apr_file_t *parent_in)
 {
-    apr_status_t rv;
+    apr_status_t rv = APR_SUCCESS;
 
     if (attr->child_in == NULL && attr->parent_in == NULL
-            && child_in == NULL && parent_in == NULL)
+           && child_in == NULL && parent_in == NULL)
         if ((rv = apr_file_pipe_create(&attr->child_in, &attr->parent_in,
                                        attr->pool)) == APR_SUCCESS)
             rv = apr_file_inherit_unset(attr->parent_in);
@@ -133,16 +125,20 @@
     }
 
     if (parent_in != NULL && rv == APR_SUCCESS) {
-        rv = apr_file_dup(&attr->parent_in, parent_in, attr->pool);
+        if (attr->parent_in)
+            rv = apr_file_dup2(attr->parent_in, parent_in, attr->pool);
+        else
+            rv = apr_file_dup(&attr->parent_in, parent_in, attr->pool);
     }
 
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_procattr_child_out_set(apr_procattr_t *attr, apr_file_t *child_out,
+APR_DECLARE(apr_status_t) apr_procattr_child_out_set(apr_procattr_t *attr,
+                                                     apr_file_t *child_out,
                                                      apr_file_t *parent_out)
 {
-    apr_status_t rv;
+    apr_status_t rv = APR_SUCCESS;
 
     if (attr->child_out == NULL && attr->parent_out == NULL
            && child_out == NULL && parent_out == NULL)
@@ -160,23 +156,27 @@
                 rv = apr_file_inherit_set(attr->child_out);
         }
     }
-  
+
     if (parent_out != NULL && rv == APR_SUCCESS) {
-        rv = apr_file_dup(&attr->parent_out, parent_out, attr->pool);
+        if (attr->parent_out)
+            rv = apr_file_dup2(attr->parent_out, parent_out, attr->pool);
+        else
+            rv = apr_file_dup(&attr->parent_out, parent_out, attr->pool);
     }
 
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_procattr_child_err_set(apr_procattr_t *attr, apr_file_t *child_err,
+APR_DECLARE(apr_status_t) apr_procattr_child_err_set(apr_procattr_t *attr,
+                                                     apr_file_t *child_err,
                                                      apr_file_t *parent_err)
 {
-    apr_status_t rv;
+    apr_status_t rv = APR_SUCCESS;
 
     if (attr->child_err == NULL && attr->parent_err == NULL
            && child_err == NULL && parent_err == NULL)
         if ((rv = apr_file_pipe_create(&attr->parent_err, &attr->child_err,
-                                       attr->pool)) == APR_SUCCESS)
+                                      attr->pool)) == APR_SUCCESS)
             rv = apr_file_inherit_unset(attr->parent_err);
 
     if (child_err != NULL && rv == APR_SUCCESS) {
@@ -189,20 +189,24 @@
                 rv = apr_file_inherit_set(attr->child_err);
         }
     }
-  
     if (parent_err != NULL && rv == APR_SUCCESS) {
-        rv = apr_file_dup(&attr->parent_err, parent_err, attr->pool);
+        if (attr->parent_err)
+            rv = apr_file_dup2(attr->parent_err, parent_err, attr->pool);
+        else
+            rv = apr_file_dup(&attr->parent_err, parent_err, attr->pool);
     }
 
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr, const char *dir)
+APR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr,
+                                               const char *dir)
 {
     attr->currdir = apr_pstrdup(attr->pool, dir);
     if (attr->currdir) {
         return APR_SUCCESS;
     }
+
     return APR_ENOMEM;
 }
 
@@ -222,21 +226,26 @@
 APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *pool)
 {
     int pid;
-    
+
     if ((pid = fork()) < 0) {
         return errno;
     }
     else if (pid == 0) {
         proc->pid = pid;
-        proc->in = NULL; 
-        proc->out = NULL; 
-        proc->err = NULL; 
+        proc->in = NULL;
+        proc->out = NULL;
+        proc->err = NULL;
+
+        apr_random_after_fork(proc);
+
         return APR_INCHILD;
     }
+
     proc->pid = pid;
-    proc->in = NULL; 
-    proc->out = NULL; 
-    proc->err = NULL; 
+    proc->in = NULL;
+    proc->out = NULL;
+    proc->err = NULL;
+
     return APR_INPARENT;
 }
 
@@ -273,7 +282,6 @@
 APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
                                                        apr_child_errfn_t *errfn)
 {
-    /* won't ever be called on this platform, so don't save the function pointer */
     return APR_SUCCESS;
 }
 
@@ -282,7 +290,6 @@
 APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
                                                        apr_int32_t chk)
 {
-    /* won't ever be used on this platform, so don't save the flag */
     return APR_SUCCESS;
 }
 
@@ -537,9 +544,8 @@
         DosExitCritSec();
 
     return status;
-}
-
 
+}
 
 static void proces_result_codes(RESULTCODES codes, 
                                 int *exitcode, 
@@ -587,7 +593,6 @@
             break;
         }
     }
-
     if (exitcode) {
         *exitcode = result;
     }
@@ -599,6 +604,7 @@
 
 
 
+#if 0
 APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc,
                                                   int *exitcode,
                                                   apr_exit_why_e *exitwhy,
@@ -624,6 +630,7 @@
 
 
 
+#if 1
 APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
                                         int *exitcode, apr_exit_why_e *exitwhy,
                                         apr_wait_how_e waithow)
@@ -642,8 +649,150 @@
 
     return APR_OS2_STATUS(rc);
 } 
+#else
+APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
+                                        int *exitcode, apr_exit_why_e *exitwhy,
+                                        apr_wait_how_e waithow)
+{
+    RESULTCODES codes;
+    ULONG rc;
+    PID pid;
+    rc = DosWaitChild(DCWA_PROCESS, waithow == APR_WAIT ? DCWW_WAIT : DCWW_NOWAIT, &codes, &pid, proc->pid);
+//fprintf(stderr,"rc of DosWaitChild= %d\n",rc);
+    if (rc == 0) {
+        proces_result_codes(codes, exitcode, exitwhy);
+        return APR_CHILD_DONE;
+    } else if (rc == ERROR_CHILD_NOT_COMPLETE) {
+        return APR_CHILD_NOTDONE;
+    } 
 
+    if (rc==128){
+      pid_t pstatus;
+      int waitpid_options = WUNTRACED;
+      int exit_int;
+      int ignore;
+      apr_exit_why_e ignorewhy;
+
+      if (exitcode == NULL) {
+          exitcode = &ignore;
+      }
+
+      if (exitwhy == NULL) {
+          exitwhy = &ignorewhy;
+      }
+
+      if (waithow != APR_WAIT) {
+          waitpid_options |= WNOHANG;
+      }
+
+      do {
+          pstatus = waitpid(proc->pid, &exit_int, waitpid_options);
+      } while (pstatus < 0 && errno == EINTR);
+
+      if (pstatus > 0) {
+          proc->pid = pstatus;
+
+          if (WIFEXITED(exit_int)) {
+              *exitwhy = APR_PROC_EXIT;
+              *exitcode = WEXITSTATUS(exit_int);
+//fprintf(stderr,"exitwhy = %d, exitcode = %d\n",APR_PROC_EXIT, WEXITSTATUS(exit_int));
+          }
+          else if (WIFSIGNALED(exit_int)) {
+              *exitwhy = APR_PROC_SIGNAL;
+#ifdef WCOREDUMP
+              if (WCOREDUMP(exit_int)) {
+                  *exitwhy |= APR_PROC_SIGNAL_CORE;
+              }
+#endif
+
+              *exitcode = WTERMSIG(exit_int);
+          }
+          else {
+              /* unexpected condition */
+              return APR_EGENERAL;
+          }
+
+          return APR_CHILD_DONE;
+      }
+      else if (pstatus == 0) {
+          return APR_CHILD_NOTDONE;
+      }
 
+      return errno;
+
+    }
+    return APR_OS2_STATUS(rc);
+} 
+#endif
+#else
+APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc,
+                                                  int *exitcode,
+                                                  apr_exit_why_e *exitwhy,
+                                                  apr_wait_how_e waithow,
+                                                  apr_pool_t *p)
+{
+    proc->pid = -1;
+    return apr_proc_wait(proc, exitcode, exitwhy, waithow);
+}
+
+APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
+                                        int *exitcode, apr_exit_why_e *exitwhy,
+                                        apr_wait_how_e waithow)
+{
+    pid_t pstatus;
+    int waitpid_options = WUNTRACED;
+    int exit_int;
+    int ignore;
+    apr_exit_why_e ignorewhy;
+
+    if (exitcode == NULL) {
+        exitcode = &ignore;
+    }
+
+    if (exitwhy == NULL) {
+        exitwhy = &ignorewhy;
+    }
+
+    if (waithow != APR_WAIT) {
+        waitpid_options |= WNOHANG;
+    }
+
+    do {
+        pstatus = waitpid(proc->pid, &exit_int, waitpid_options);
+    } while (pstatus < 0 && errno == EINTR);
+
+    if (pstatus > 0) {
+        proc->pid = pstatus;
+
+        if (WIFEXITED(exit_int)) {
+            *exitwhy = APR_PROC_EXIT;
+            *exitcode = WEXITSTATUS(exit_int);
+        }
+        else if (WIFSIGNALED(exit_int)) {
+            *exitwhy = APR_PROC_SIGNAL;
+
+#ifdef WCOREDUMP
+            if (WCOREDUMP(exit_int)) {
+                *exitwhy |= APR_PROC_SIGNAL_CORE;
+            }
+#endif
+
+            *exitcode = WTERMSIG(exit_int);
+        }
+        else {
+            /* unexpected condition */
+            return APR_EGENERAL;
+        }
+
+        return APR_CHILD_DONE;
+    }
+    else if (pstatus == 0) {
+        return APR_CHILD_NOTDONE;
+    }
+
+    return errno;
+}
+#endif
 
 APR_DECLARE(apr_status_t) apr_proc_detach(int daemonize)
 {
@@ -670,3 +819,11 @@
 {
     return APR_ENOTIMPL;
 }
+
+APR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr,
+                                                 apr_int32_t what,
+                                                 struct rlimit *limit)
+{
+    return APR_ENOTIMPL;
+}
+
Only in apr-1.6.3/threadproc/os2: proc.c.orig
diff -ur apr-1.6.3-o/threadproc/os2/thread.c apr-1.6.3/threadproc/os2/thread.c
--- apr-1.6.3-o/threadproc/os2/thread.c	2007-10-14 01:51:40.000000000 +1030
+++ apr-1.6.3/threadproc/os2/thread.c	2018-01-26 18:08:34.000000000 +1030
@@ -22,8 +22,11 @@
 #include "apr_lib.h"
 #include "apr_portable.h"
 #include "apr_arch_file_io.h"
+//#define INCL_LIBLOADEXCEPTQ
+//#include "exceptq.h"
 #include <stdlib.h>
 
+
 APR_DECLARE(apr_status_t) apr_threadattr_create(apr_threadattr_t **new, apr_pool_t *pool)
 {
     (*new) = (apr_threadattr_t *)apr_palloc(pool, sizeof(apr_threadattr_t));
@@ -68,8 +71,13 @@
 
 static void apr_thread_begin(void *arg)
 {
+//  EXCEPTIONREGISTRATIONRECORD exRegRec;
   apr_thread_t *thread = (apr_thread_t *)arg;
+  // install exception handler (dynamically loaded)
+//  LibLoadExceptq(&exRegRec);
   thread->exitval = thread->func(thread, thread->data);
+  /* remove exception handler */
+  apr_thread_exit(thread, thread->exitval);      // In case caller does not call apr_thread_exit
 }
 
 
@@ -131,7 +139,29 @@
 
 APR_DECLARE(apr_status_t) apr_thread_exit(apr_thread_t *thd, apr_status_t retval)
 {
+    PTIB ptib;
+    PPIB ppib;
+//    EXCEPTIONREGISTRATIONRECORD *pexRegRec;     // 2013-03-17 SHL
     thd->exitval = retval;
+    // 2013-03-17 SHL
+    DosGetInfoBlocks(&ptib, &ppib);
+#if 0
+    pexRegRec = ptib->tib_pexchain;
+    /* Verify that we have what looks like a valid registration record pointer
+       It's a really bad coding error for this not to be the case
+       but some code within the thread might goof might install a
+       handler and forget to uninstall it
+       FIXME to report this condition somewhere
+       Maybe we should just force a trap
+    */
+    if (pexRegRec != END_OF_CHAIN &&
+        (PVOID)pexRegRec > (PVOID)&ptib &&
+        (PVOID)pexRegRec < ptib->tib_pstacklimit)
+    {
+      /* remove exception handler */
+      UninstallExceptq(pexRegRec);      // 2013-03-17 SHL
+    }
+#endif
     _endthread();
     return -1; /* If we get here something's wrong */
 }
diff -ur apr-1.6.3-o/threadproc/unix/signals.c apr-1.6.3/threadproc/unix/signals.c
--- apr-1.6.3-o/threadproc/unix/signals.c	2008-02-01 19:26:54.000000000 +1030
+++ apr-1.6.3/threadproc/unix/signals.c	2018-01-26 18:08:34.000000000 +1030
@@ -44,7 +44,6 @@
                                                      XCPT_SIGNAL_BREAK));
     }
 #endif /* OS2 */
-
     if (kill(proc->pid, signum) == -1) {
         return errno;
     }
@@ -416,7 +415,7 @@
     sigfillset(&sig_mask);
     remove_sync_sigs(&sig_mask);
 
-#if defined(SIGPROCMASK_SETS_THREAD_MASK) || ! APR_HAS_THREADS
+#if defined(SIGPROCMASK_SETS_THREAD_MASK) || ! APR_HAS_THREADS || defined(OS2)
     if ((rv = sigprocmask(SIG_SETMASK, &sig_mask, NULL)) != 0) {
         rv = errno;
     }
@@ -442,7 +441,7 @@
 
     sigaddset(&sig_mask, signum);
 
-#if defined(SIGPROCMASK_SETS_THREAD_MASK) || ! APR_HAS_THREADS
+#if defined(SIGPROCMASK_SETS_THREAD_MASK) || ! APR_HAS_THREADS || defined(OS2)
     if ((rv = sigprocmask(SIG_BLOCK, &sig_mask, NULL)) != 0) {
         rv = errno;
     }
@@ -469,7 +468,7 @@
 
     sigaddset(&sig_mask, signum);
 
-#if defined(SIGPROCMASK_SETS_THREAD_MASK) || ! APR_HAS_THREADS
+#if defined(SIGPROCMASK_SETS_THREAD_MASK) || ! APR_HAS_THREADS || defined(OS2)
     if ((rv = sigprocmask(SIG_UNBLOCK, &sig_mask, NULL)) != 0) {
         rv = errno;
     }
diff -ur apr-1.6.3-o/time/unix/time.c apr-1.6.3/time/unix/time.c
--- apr-1.6.3-o/time/unix/time.c	2017-09-11 08:00:34.000000000 +0930
+++ apr-1.6.3/time/unix/time.c	2018-01-26 18:08:34.000000000 +1030
@@ -126,7 +126,7 @@
 APR_DECLARE(apr_status_t) apr_time_exp_lt(apr_time_exp_t *result,
                                                 apr_time_t input)
 {
-#if defined(__EMX__)
+#if defined(__EMX__) && !defined(__KLIBC__)
     /* EMX gcc (OS/2) has a timezone global we can use */
     return apr_time_exp_tz(result, input, -timezone);
 #else
@@ -250,7 +250,7 @@
 #endif
 }
 
-#ifdef OS2
+#if defined(OS2) 
 APR_DECLARE(apr_status_t) apr_os2_time_to_apr_time(apr_time_t *result,
                                                    FDATE os2date,
                                                    FTIME os2time)
Only in apr-1.6.3/time/unix: time.c.orig
Only in apr-1.6.3/tools: gen_test_char.exe
Only in apr-1.6.3/tools: gen_test_char.lo
Only in apr-1.6.3/tools: gen_test_char.map
Only in apr-1.6.3/tools: gen_test_char.o
diff -ur apr-1.6.3-o/user/unix/userinfo.c apr-1.6.3/user/unix/userinfo.c
--- apr-1.6.3-o/user/unix/userinfo.c	2006-08-03 20:25:30.000000000 +0930
+++ apr-1.6.3/user/unix/userinfo.c	2018-01-26 18:08:34.000000000 +1030
@@ -77,7 +77,7 @@
     if ((rv = getpwnam_safe(username, &pw, pwbuf)) != APR_SUCCESS)
         return rv;
 
-#ifdef OS2
+#if (defined(OS2)&&!defined(__INNOTEK_LIBC__))
     /* Need to manually add user name for OS/2 */
     *dirname = apr_pstrcat(p, pw.pw_dir, pw.pw_name, NULL);
 #else
apr-1.6.3.diff (122,307 bytes)   

Steven Levine

2019-11-01 01:47

manager   ~0003365

This diff should apply to the curreent 2.4.41 patched sources.

It restores/provides graceful shutdown capability to MaxConnectionsPerChild (the new name for MaxRequestsPerChild. If the graceful shutdown fails, the code falls back to the existing hard shutdown logic.

The current timout before falling back to a hard shutdown is about 3 seconds. We might want to extend this somewhat.
graceful-mpmt_os2_child.c.diff (1,226 bytes)   
diff --git a/server/mpm/mpmt_os2/mpmt_os2_child.c b/server/mpm/mpmt_os2/mpmt_os2_child.c
index 48550d4..6c52183 100644
--- a/server/mpm/mpmt_os2/mpmt_os2_child.c
+++ b/server/mpm/mpmt_os2/mpmt_os2_child.c
@@ -300,7 +300,7 @@ void ap_mpm_child_main(apr_pool_t *pconf)
         }
 
         if (ap_max_requests_per_child != 0 && requests_this_child >= ap_max_requests_per_child){
-	    is_graceful = 0;
+            is_graceful = 1;
             break;
         }
     } while (!shutdown_pending && ap_my_generation == ap_scoreboard_image->global->running_generation);
@@ -312,6 +312,7 @@ void ap_mpm_child_main(apr_pool_t *pconf)
 
     if (is_graceful) {
         char someleft;
+        int retries = 0;
 
         /* tell our worker threads to exit */
         for (c=0; c<HARD_THREAD_LIMIT; c++) {
@@ -346,8 +347,14 @@ void ap_mpm_child_main(apr_pool_t *pconf)
                     break;
                 }
             }
+            if (++retries >= 3) {
+              is_graceful = 0;          /* Time to force the issue */
+              break;
+            }
         } while (someleft);
-    } else {
+    }
+
+    if (!is_graceful) {
         DosPurgeQueue(workq);
 
         for (c=0; c<HARD_THREAD_LIMIT; c++) {
graceful-mpmt_os2_child.c.diff (1,226 bytes)   

psmedley

2019-11-01 02:04

administrator   ~0003367

Last edited: 2019-11-01 02:11

this diff applied cleanly. Building now, link is http://smedley.id.au/tmp/httpd-2.4.41-os2-debug-20191101.zip

Steven Levine

2019-11-05 00:58

manager   ~0003371

I am getting a 404 on the link.

Sorry for the slow response, I was away at Pala, CA over the weekend. One of my nieces got married. One more left to go, but she is probably going to off the market for a while. She just started on her med-PhD at Harvard.

BTW, Mantis has a misfeature where if you edit a comment, I don't get any email about the change so I did not know about the link until I checked today.

psmedley

2019-11-05 07:57

administrator   ~0003372

HI Steven, My bad - I typed the command to build the zip, copied the filename, but never pressed enter to complete the command :(

I hadn't realised mantis didn't notify about an edited comment - I'll try and bear that in mind in the future!

Hope you enjoyed the wedding!

Steven Levine

2020-05-26 19:19

manager   ~0003470

Reminder sent to: psmedley

Is the ticket ready to resolve? TTBOMK, your current build integrate all my patches, including the graceful shudown support.

Steven Levine

2020-06-23 18:16

manager   ~0003472

The patch appears to work as advertised and the related tickets are all closed, so closing this too.

Issue History

Date Modified Username Field Change
2014-12-22 23:20 Steven Levine New Issue
2014-12-22 23:20 Steven Levine Relationship added related to 0000190
2014-12-22 23:21 Steven Levine Relationship added related to 0000637
2014-12-23 03:06 LewisR Note Added: 0002953
2014-12-24 18:28 Steven Levine Note Added: 0002954
2014-12-24 19:13 LewisR Note Added: 0002955
2014-12-25 00:32 LewisR Note Added: 0002956
2014-12-25 00:33 LewisR Note Edited: 0002956
2014-12-26 05:27 Steven Levine Note Added: 0002957
2014-12-26 17:37 Steven Levine Note Edited: 0002957
2014-12-26 17:38 Steven Levine Note Added: 0002958
2014-12-27 06:44 Steven Levine File Added: apr_portable.h.diff
2014-12-27 06:44 Steven Levine File Added: sockets.c.diff
2014-12-27 06:45 Steven Levine File Added: mpmt_os2.c.diff
2014-12-27 06:56 Steven Levine Note Added: 0002961
2014-12-27 07:11 Steven Levine Note Added: 0002962
2014-12-27 08:13 psmedley Note Added: 0002963
2014-12-27 08:16 psmedley Note Edited: 0002963
2014-12-27 08:26 psmedley Note Edited: 0002963
2014-12-27 19:10 Steven Levine File Deleted: apr_portable.h.diff
2014-12-27 19:10 Steven Levine File Deleted: sockets.c.diff
2014-12-27 19:10 Steven Levine File Deleted: mpmt_os2.c.diff
2014-12-27 19:11 Steven Levine File Added: apr_portable.h.diff
2014-12-27 19:11 Steven Levine File Added: sockets.c.diff
2014-12-27 19:12 Steven Levine File Added: mpmt_os2.c.diff
2014-12-27 19:22 Steven Levine Note Added: 0002964
2014-12-27 20:08 psmedley Note Added: 0002965
2014-12-27 20:31 psmedley Note Added: 0002966
2014-12-27 20:37 LewisR Note Added: 0002967
2014-12-27 20:50 LewisR Note Added: 0002968
2014-12-27 20:54 LewisR Note Added: 0002969
2014-12-27 21:06 LewisR Note Added: 0002970
2014-12-27 21:17 Steven Levine Note Added: 0002971
2014-12-27 21:19 LewisR Note Added: 0002972
2014-12-29 01:57 LewisR Note Edited: 0002972
2014-12-29 02:03 LewisR Note Added: 0002973
2014-12-29 02:47 psmedley Note Added: 0002974
2014-12-29 02:59 LewisR Note Added: 0002975
2014-12-29 03:02 LewisR Note Edited: 0002975
2015-01-10 18:23 Steven Levine File Added: apr-1.5.1.git-20150110-1002-shl.diff
2015-01-10 18:24 Steven Levine File Added: httpd-2.2.29.git-20150110-1012-shl.diff
2015-01-10 18:25 Steven Levine File Added: SplitPatch.pl
2015-01-10 18:29 Steven Levine Note Added: 0003007
2015-01-24 01:34 Steven Levine Note Added: 0003017
2015-01-24 01:34 Steven Levine Status new => resolved
2015-01-24 01:34 Steven Levine Fixed in Version => v2.2.32
2015-01-24 01:34 Steven Levine Resolution open => fixed
2015-01-24 01:34 Steven Levine Assigned To => Steven Levine
2015-02-04 01:32 Steven Levine Note Added: 0003021
2015-02-04 01:32 Steven Levine Status resolved => assigned
2015-02-04 01:32 Steven Levine File Added: mpmt_os2_child.c.diff
2015-02-04 01:33 Steven Levine File Added: mpmt_os2_child.c
2015-02-05 06:53 Steven Levine File Deleted: mpmt_os2_child.c
2015-02-05 06:54 Steven Levine File Added: mpmt_os2_child.c-20150204-2251.diff
2015-02-05 06:54 Steven Levine File Added: mpmt_os2_child.c
2015-02-05 06:58 Steven Levine File Added: mpmt_os2_child.c-20150203-1730.diff
2015-02-05 06:58 Steven Levine File Deleted: mpmt_os2_child.c.diff
2015-02-05 07:00 Steven Levine File Added: mpmt_os2.c-20141227-1030.diff
2015-02-05 07:01 Steven Levine File Deleted: mpmt_os2.c.diff
2015-02-05 07:03 Steven Levine File Added: mpmt_os2.c
2015-02-05 07:04 Steven Levine File Added: mpmt_os2.c-20150203-1701.diff
2015-02-07 02:44 Steven Levine File Deleted: mpmt_os2_child.c-20150203-1730.diff
2015-02-07 02:45 Steven Levine File Deleted: mpmt_os2.c-20141227-1030.diff
2015-02-07 02:45 Steven Levine File Deleted: mpmt_os2_child.c
2015-02-07 02:45 Steven Levine File Deleted: mpmt_os2_child.c-20150204-2251.diff
2015-02-07 02:47 Steven Levine File Added: sendrecv.c
2015-02-07 02:47 Steven Levine File Added: apr_errno.h
2015-02-07 02:48 Steven Levine File Added: mpmt_os2_child.c-20150206-1839.diff
2015-02-07 02:49 Steven Levine File Added: apr_errno.h-20150206-1838.diff
2015-02-07 02:50 Steven Levine File Added: sendrecv.c-20150206-1849.diff
2015-02-07 02:51 Steven Levine File Added: mpmt_os2_child.c
2018-10-17 02:12 psmedley Note Added: 0003209
2018-10-17 08:46 psmedley Note Edited: 0003209
2018-10-17 08:47 psmedley File Added: php-5.4.45.diff
2018-10-17 08:47 psmedley File Added: httpd-2.4.35.diff
2018-10-17 08:47 psmedley File Added: apr-1.6.3.diff
2018-10-17 08:47 psmedley Note Added: 0003210
2019-11-01 01:47 Steven Levine File Added: graceful-mpmt_os2_child.c.diff
2019-11-01 01:47 Steven Levine Note Added: 0003365
2019-11-01 02:04 psmedley Note Added: 0003367
2019-11-01 02:11 psmedley Note Edited: 0003367
2019-11-05 00:58 Steven Levine Note Added: 0003371
2019-11-05 07:57 psmedley Note Added: 0003372
2020-05-26 19:19 Steven Levine Note Added: 0003470
2020-06-23 18:16 Steven Levine Status assigned => resolved
2020-06-23 18:16 Steven Levine Fixed in Version v2.2.32 => 2.4.x
2020-06-23 18:16 Steven Levine Note Added: 0003472
2020-08-24 03:01 psmedley Status resolved => closed