diff options
Diffstat (limited to 'server')
| -rw-r--r-- | server/Makefile.in | 2 | ||||
| -rw-r--r-- | server/NWGNUmakefile | 12 | ||||
| -rw-r--r-- | server/core.c | 44 | ||||
| -rw-r--r-- | server/gen_test_char.dep | 5 | ||||
| -rw-r--r-- | server/gen_test_char.mak | 234 | ||||
| -rw-r--r-- | server/mpm/config.m4 | 4 | ||||
| -rw-r--r-- | server/mpm/prefork/prefork.c | 9 | ||||
| -rw-r--r-- | server/mpm/winnt/Makefile.in | 5 | ||||
| -rw-r--r-- | server/mpm/winnt/child.c | 58 | ||||
| -rw-r--r-- | server/mpm/winnt/config.m4 | 3 | ||||
| -rw-r--r-- | server/mpm/winnt/mpm_winnt.c | 115 | ||||
| -rw-r--r-- | server/mpm/winnt/mpm_winnt.h | 6 | ||||
| -rw-r--r-- | server/mpm/winnt/nt_eventlog.c | 8 | ||||
| -rw-r--r-- | server/mpm/winnt/service.c | 47 | ||||
| -rw-r--r-- | server/mpm_common.c | 2 | ||||
| -rw-r--r-- | server/protocol.c | 33 | ||||
| -rw-r--r-- | server/request.c | 2 | ||||
| -rw-r--r-- | server/util.c | 11 | ||||
| -rw-r--r-- | server/util_script.c | 8 |
19 files changed, 445 insertions, 163 deletions
diff --git a/server/Makefile.in b/server/Makefile.in index 89498dd4..db2caa0d 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -21,7 +21,7 @@ TARGETS = delete-exports $(LTLIBRARY_NAME) $(CORE_IMPLIB_FILE) export_vars.h htt include $(top_builddir)/build/rules.mk include $(top_srcdir)/build/library.mk -gen_test_char_OBJECTS = gen_test_char.lo util_debug.lo +gen_test_char_OBJECTS = gen_test_char.lo gen_test_char: $(gen_test_char_OBJECTS) $(LINK) $(EXTRA_LDFLAGS) $(gen_test_char_OBJECTS) $(EXTRA_LIBS) diff --git a/server/NWGNUmakefile b/server/NWGNUmakefile index 512adfdc..16ce9734 100644 --- a/server/NWGNUmakefile +++ b/server/NWGNUmakefile @@ -11,7 +11,7 @@ SUBDIRS = \ # paths to tools # -include $(AP_WORK)\build\NWGNUhead.inc +include $(AP_WORK)/build/NWGNUhead.inc # # build this level's files @@ -112,7 +112,7 @@ NLM_THREAD_NAME = genchars # # If this is specified, it will override VERSION value in -# $(AP_WORK)\build\NWGNUenvironment.inc +# $(AP_WORK)/build/NWGNUenvironment.inc # NLM_VERSION = @@ -124,12 +124,12 @@ NLM_STACK_SIZE = 8192 # # If this is specified it will be used by the link '-entry' directive # -NLM_ENTRY_SYM =_LibCPrelude +NLM_ENTRY_SYM = # # If this is specified it will be used by the link '-exit' directive # -NLM_EXIT_SYM =_LibCPostlude +NLM_EXIT_SYM = # # If this is specified it will be used by the link '-check' directive @@ -178,7 +178,7 @@ FILES_nlm_objs = \ # These will be added as a library command in the link.opt file. # FILES_nlm_libs = \ - libcpre.o \ + $(PRELUDE) \ $(EOLIST) # @@ -247,5 +247,5 @@ install :: nlms FORCE # in this makefile # -include $(AP_WORK)\build\NWGNUtail.inc +include $(APBUILD)/NWGNUtail.inc diff --git a/server/core.c b/server/core.c index 76aae1a3..ea01ca92 100644 --- a/server/core.c +++ b/server/core.c @@ -66,6 +66,9 @@ #define AP_MAX_INCLUDE_DEPTH (128) #endif +/* valid in core-conf, but not in runtime r->used_path_info */ +#define AP_ACCEPT_PATHINFO_UNSET 3 + APR_HOOK_STRUCT( APR_HOOK_LINK(get_mgmt_items) ) @@ -114,7 +117,7 @@ static void *create_core_dir_config(apr_pool_t *a, char *dir) conf->override_opts = OPT_UNSET | OPT_ALL | OPT_SYM_OWNER | OPT_MULTI; conf->content_md5 = 2; - conf->accept_path_info = 3; + conf->accept_path_info = AP_ACCEPT_PATHINFO_UNSET; conf->use_canonical_name = USE_CANONICAL_NAME_UNSET; conf->use_canonical_phys_port = USE_CANONICAL_PHYS_PORT_UNSET; @@ -161,6 +164,7 @@ static void *create_core_dir_config(apr_pool_t *a, char *dir) conf->enable_mmap = ENABLE_MMAP_UNSET; conf->enable_sendfile = ENABLE_SENDFILE_UNSET; conf->allow_encoded_slashes = 0; + conf->decode_encoded_slashes = 0; return (void *)conf; } @@ -447,6 +451,7 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv) } conf->allow_encoded_slashes = new->allow_encoded_slashes; + conf->decode_encoded_slashes = new->decode_encoded_slashes; return (void*)conf; } @@ -2432,7 +2437,7 @@ static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg) return NULL; } -static const char *set_allow2f(cmd_parms *cmd, void *d_, int arg) +static const char *set_allow2f(cmd_parms *cmd, void *d_, const char *arg) { core_dir_config *d = d_; const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); @@ -2441,7 +2446,20 @@ static const char *set_allow2f(cmd_parms *cmd, void *d_, int arg) return err; } - d->allow_encoded_slashes = arg != 0; + if (0 == strcasecmp(arg, "on")) { + d->allow_encoded_slashes = 1; + d->decode_encoded_slashes = 1; + } else if (0 == strcasecmp(arg, "off")) { + d->allow_encoded_slashes = 0; + d->decode_encoded_slashes = 0; + } else if (0 == strcasecmp(arg, "nodecode")) { + d->allow_encoded_slashes = 1; + d->decode_encoded_slashes = 0; + } else { + return apr_pstrcat(cmd->pool, + cmd->cmd->name, " must be On, Off, or NoDecode", + NULL); + } return NULL; } @@ -3434,7 +3452,7 @@ AP_INIT_TAKE1("SetInputFilter", ap_set_string_slot, AP_INIT_ITERATE2("AddOutputFilterByType", add_ct_output_filters, (void *)APR_OFFSETOF(core_dir_config, ct_output_filters), OR_FILEINFO, "output filter name followed by one or more content-types"), -AP_INIT_FLAG("AllowEncodedSlashes", set_allow2f, NULL, RSRC_CONF, +AP_INIT_TAKE1("AllowEncodedSlashes", set_allow2f, NULL, RSRC_CONF, "Allow URLs containing '/' encoded as '%2F'"), /* @@ -3480,6 +3498,10 @@ AP_INIT_TAKE1("EnableExceptionHook", ap_mpm_set_exception_hook, NULL, RSRC_CONF, #endif AP_INIT_TAKE1("TraceEnable", set_trace_enable, NULL, RSRC_CONF, "'on' (default), 'off' or 'extended' to trace request body content"), +#ifdef SUEXEC_BIN +AP_INIT_FLAG("Suexec", unixd_set_suexec, NULL, RSRC_CONF, + "Enable or disable suEXEC support"), +#endif { NULL } }; @@ -3596,15 +3618,17 @@ static int core_override_type(request_rec *r) /* Deal with the poor soul who is trying to force path_info to be * accepted within the core_handler, where they will let the subreq * address its contents. This is toggled by the user in the very - * beginning of the fixup phase, so modules should override the user's + * beginning of the fixup phase (here!), so modules should override the user's * discretion in their own module fixup phase. It is tristate, if - * the user doesn't specify, the result is 2 (which the module may - * interpret to its own customary behavior.) It won't be touched - * if the value is no longer undefined (2), so any module changing - * the value prior to the fixup phase OVERRIDES the user's choice. + * the user doesn't specify, the result is AP_REQ_DEFAULT_PATH_INFO. + * (which the module may interpret to its own customary behavior.) + * It won't be touched if the value is no longer AP_ACCEPT_PATHINFO_UNSET, + * so any module changing the value prior to the fixup phase + * OVERRIDES the user's choice. */ if ((r->used_path_info == AP_REQ_DEFAULT_PATH_INFO) - && (conf->accept_path_info != 3)) { + && (conf->accept_path_info != AP_ACCEPT_PATHINFO_UNSET)) { + /* No module knew better, and the user coded AcceptPathInfo */ r->used_path_info = conf->accept_path_info; } diff --git a/server/gen_test_char.dep b/server/gen_test_char.dep new file mode 100644 index 00000000..c749241e --- /dev/null +++ b/server/gen_test_char.dep @@ -0,0 +1,5 @@ +# Microsoft Developer Studio Generated Dependency File, included by gen_test_char.mak + +.\gen_test_char.c : \ + "..\srclib\apr\include\apr_lib.h"\ + diff --git a/server/gen_test_char.mak b/server/gen_test_char.mak new file mode 100644 index 00000000..d6e7bfb1 --- /dev/null +++ b/server/gen_test_char.mak @@ -0,0 +1,234 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on gen_test_char.dsp +!IF "$(CFG)" == "" +CFG=gen_test_char - Win32 Debug +!MESSAGE No configuration specified. Defaulting to gen_test_char - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "gen_test_char - Win32 Release" && "$(CFG)" != "gen_test_char - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gen_test_char.mak" CFG="gen_test_char - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gen_test_char - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "gen_test_char - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "gen_test_char - Win32 Release" + +OUTDIR=. +INTDIR=.\Release +# Begin Custom Macros +OutDir=. +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\gen_test_char.exe" + +!ELSE + +ALL : "libapr - Win32 Release" "$(OUTDIR)\gen_test_char.exe" + +!ENDIF + +!IF "$(RECURSE)" == "1" +CLEAN :"libapr - Win32 ReleaseCLEAN" +!ELSE +CLEAN : +!ENDIF + -@erase "$(INTDIR)\gen_test_char.idb" + -@erase "$(INTDIR)\gen_test_char.obj" + -@erase "$(OUTDIR)\gen_test_char.exe" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MD /W3 /O2 /I "..\include" /I "..\srclib\apr\include" /I "..\srclib\apr-util\include" /I "..\os\win32" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\gen_test_char" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\gen_test_char.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\Release\gen_test_char.pdb" /out:"$(OUTDIR)\gen_test_char.exe" /opt:ref +LINK32_OBJS= \ + "$(INTDIR)\gen_test_char.obj" \ + "..\srclib\apr\Release\libapr-1.lib" + +"$(OUTDIR)\gen_test_char.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "gen_test_char - Win32 Debug" + +OUTDIR=. +INTDIR=.\Debug +# Begin Custom Macros +OutDir=. +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\gen_test_char.exe" + +!ELSE + +ALL : "libapr - Win32 Debug" "$(OUTDIR)\gen_test_char.exe" + +!ENDIF + +!IF "$(RECURSE)" == "1" +CLEAN :"libapr - Win32 DebugCLEAN" +!ELSE +CLEAN : +!ENDIF + -@erase "$(INTDIR)\gen_test_char.idb" + -@erase "$(INTDIR)\gen_test_char.obj" + -@erase "$(OUTDIR)\Debug\gen_test_char.pdb" + -@erase "$(OUTDIR)\gen_test_char.exe" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "..\include" /I "..\srclib\apr\include" /I "..\srclib\apr-util\include" /I "..\os\win32" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\gen_test_char" /FD /EHsc /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\gen_test_char.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\Debug\gen_test_char.pdb" /debug /out:"$(OUTDIR)\gen_test_char.exe" +LINK32_OBJS= \ + "$(INTDIR)\gen_test_char.obj" \ + "..\srclib\apr\Debug\libapr-1.lib" + +"$(OUTDIR)\gen_test_char.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("gen_test_char.dep") +!INCLUDE "gen_test_char.dep" +!ELSE +!MESSAGE Warning: cannot find "gen_test_char.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "gen_test_char - Win32 Release" || "$(CFG)" == "gen_test_char - Win32 Debug" + +!IF "$(CFG)" == "gen_test_char - Win32 Release" + +"libapr - Win32 Release" : + cd ".\..\srclib\apr" + $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" + cd "..\..\server" + +"libapr - Win32 ReleaseCLEAN" : + cd ".\..\srclib\apr" + $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN + cd "..\..\server" + +!ELSEIF "$(CFG)" == "gen_test_char - Win32 Debug" + +"libapr - Win32 Debug" : + cd ".\..\srclib\apr" + $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" + cd "..\..\server" + +"libapr - Win32 DebugCLEAN" : + cd ".\..\srclib\apr" + $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN + cd "..\..\server" + +!ENDIF + +SOURCE=.\gen_test_char.c + +"$(INTDIR)\gen_test_char.obj" : $(SOURCE) "$(INTDIR)" + + + +!ENDIF + diff --git a/server/mpm/config.m4 b/server/mpm/config.m4 index 6ea447d1..b0907769 100644 --- a/server/mpm/config.m4 +++ b/server/mpm/config.m4 @@ -1,7 +1,7 @@ AC_MSG_CHECKING(which MPM to use) AC_ARG_WITH(mpm, APACHE_HELP_STRING(--with-mpm=MPM,Choose the process model for Apache to use. - MPM={beos|event|worker|prefork|mpmt_os2}),[ + MPM={beos|event|worker|prefork|mpmt_os2|winnt}),[ APACHE_MPM=$withval ],[ if test "x$APACHE_MPM" = "x"; then @@ -14,7 +14,7 @@ apache_cv_mpm=$APACHE_MPM ap_mpm_is_threaded () { - if test "$apache_cv_mpm" = "worker" -o "$apache_cv_mpm" = "event" ; then + if test "$apache_cv_mpm" = "worker" -o "$apache_cv_mpm" = "event" -o "$apache_cv_mpm" = "winnt" ; then return 0 else return 1 diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index f5a72057..108f961a 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -330,6 +330,7 @@ static void just_die(int sig) static void stop_listening(int sig) { + mpm_state = AP_MPMQ_STOPPING; ap_close_listeners(); /* For a graceful stop, we want the child to exit when done */ @@ -350,6 +351,7 @@ static void sig_term(int sig) */ return; } + mpm_state = AP_MPMQ_STOPPING; shutdown_pending = 1; is_graceful = (sig == AP_SIG_GRACEFUL_STOP); } @@ -363,6 +365,7 @@ static void restart(int sig) /* Probably not an error - don't bother reporting it */ return; } + mpm_state = AP_MPMQ_STOPPING; restart_pending = 1; is_graceful = (sig == AP_SIG_GRACEFUL); } @@ -458,8 +461,10 @@ static int num_listensocks = 0; int ap_graceful_stop_signalled(void) { - /* not ever called anymore... */ - return 0; + /* Return true if the server is stopping for whatever reason; the + * function is used to initiate a fast exit from the connection + * processing loop. */ + return mpm_state == AP_MPMQ_STOPPING; } diff --git a/server/mpm/winnt/Makefile.in b/server/mpm/winnt/Makefile.in new file mode 100644 index 00000000..38957c87 --- /dev/null +++ b/server/mpm/winnt/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libwinnt.la +LTLIBRARY_SOURCES = mpm_winnt.c child.c nt_eventlog.c service.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/server/mpm/winnt/child.c b/server/mpm/winnt/child.c index d918e47a..82cec95f 100644 --- a/server/mpm/winnt/child.c +++ b/server/mpm/winnt/child.c @@ -39,6 +39,12 @@ #include <malloc.h> #include "apr_atomic.h" +#include <process.h> + +#ifdef __MINGW32__ +#include <mswsock.h> +#endif + /* shared with mpm_winnt.c */ extern DWORD my_pid; @@ -63,8 +69,8 @@ static apr_thread_mutex_t *child_lock; static apr_thread_mutex_t *qlock; static PCOMP_CONTEXT qhead = NULL; static PCOMP_CONTEXT qtail = NULL; -static int num_completion_contexts = 0; -static int max_num_completion_contexts = 0; +static apr_uint32_t num_completion_contexts = 0; +static apr_uint32_t max_num_completion_contexts = 0; static HANDLE ThreadDispatchIOCP = NULL; static HANDLE qwait_event = NULL; @@ -350,7 +356,7 @@ static unsigned int __stdcall win9x_accept(void * dummy) apr_os_sock_get(&nsd, lr->sd); FD_SET(nsd, &listenfds); ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "Child %d: Listening on port %d.", my_pid, lr->bind_addr->port); + "Child %lu: Listening on port %d.", my_pid, lr->bind_addr->port); } } @@ -510,7 +516,7 @@ static unsigned int __stdcall winnt_accept(void *lr_) #endif ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, - "Child %d: Starting thread to listen on port %d.", my_pid, lr->bind_addr->port); + "Child %lu: Starting thread to listen on port %d.", my_pid, lr->bind_addr->port); while (!shutdown_in_progress) { if (!context) { context = mpm_get_completion_context(); @@ -578,7 +584,7 @@ static unsigned int __stdcall winnt_accept(void *lr_) context->accept_socket = INVALID_SOCKET; if (err_count > MAX_ACCEPTEX_ERR_COUNT) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, - "Child %d: Encountered too many errors accepting client connections. " + "Child %lu: Encountered too many errors accepting client connections. " "Possible causes: dynamic address renewal, or incompatible VPN or firewall software. " "Try using the Win32DisableAcceptEx directive.", my_pid); err_count = 0; @@ -590,7 +596,7 @@ static unsigned int __stdcall winnt_accept(void *lr_) ++err_count; if (err_count > MAX_ACCEPTEX_ERR_COUNT) { ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, - "Child %d: Encountered too many errors accepting client connections. " + "Child %lu: Encountered too many errors accepting client connections. " "Possible causes: Unknown. " "Try using the Win32DisableAcceptEx directive.", my_pid); err_count = 0; @@ -676,7 +682,7 @@ static unsigned int __stdcall winnt_accept(void *lr_) SetEvent(exit_event); } ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, ap_server_conf, - "Child %d: Accept thread exiting.", my_pid); + "Child %lu: Accept thread exiting.", my_pid); return 0; } @@ -705,7 +711,7 @@ static PCOMP_CONTEXT winnt_get_connection(PCOMP_CONTEXT context) if (!rc) { rc = apr_get_os_error(); ap_log_error(APLOG_MARK,APLOG_DEBUG, rc, ap_server_conf, - "Child %d: GetQueuedComplationStatus returned %d", my_pid, rc); + "Child %lu: GetQueuedComplationStatus returned %d", my_pid, rc); continue; } @@ -822,9 +828,9 @@ static void cleanup_thread(HANDLE *handles, int *thread_cnt, int thread_to_clean * monitors the child process for maintenance and shutdown * events. */ -static void create_listener_thread() +static void create_listener_thread(void) { - int tid; + unsigned tid; int num_listeners = 0; if (!use_acceptex) { _beginthreadex(NULL, 0, win9x_accept, @@ -870,7 +876,7 @@ void child_main(apr_pool_t *pconf) int watch_thread; int time_remains; int cld; - int tid; + unsigned tid; int rv; int i; @@ -884,7 +890,7 @@ void child_main(apr_pool_t *pconf) max_requests_per_child_event = CreateEvent(NULL, TRUE, FALSE, NULL); if (!max_requests_per_child_event) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Failed to create a max_requests event.", my_pid); + "Child %lu: Failed to create a max_requests event.", my_pid); exit(APEXIT_CHILDINIT); } child_events[0] = exit_event; @@ -902,11 +908,11 @@ void child_main(apr_pool_t *pconf) status = apr_proc_mutex_lock(start_mutex); if (status != APR_SUCCESS) { ap_log_error(APLOG_MARK,APLOG_ERR, status, ap_server_conf, - "Child %d: Failed to acquire the start_mutex. Process will exit.", my_pid); + "Child %lu: Failed to acquire the start_mutex. Process will exit.", my_pid); exit(APEXIT_CHILDINIT); } ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Acquired the start mutex.", my_pid); + "Child %lu: Acquired the start mutex.", my_pid); /* * Create the worker thread dispatch IOCompletionPort @@ -922,7 +928,7 @@ void child_main(apr_pool_t *pconf) qwait_event = CreateEvent(NULL, TRUE, FALSE, NULL); if (!qwait_event) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Failed to create a qwait event.", my_pid); + "Child %lu: Failed to create a qwait event.", my_pid); exit(APEXIT_CHILDINIT); } } @@ -931,7 +937,7 @@ void child_main(apr_pool_t *pconf) * Create the pool of worker threads */ ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Starting %d worker threads.", my_pid, ap_threads_per_child); + "Child %lu: Starting %d worker threads.", my_pid, ap_threads_per_child); child_handles = (HANDLE) apr_pcalloc(pchild, ap_threads_per_child * sizeof(HANDLE)); apr_thread_mutex_create(&child_lock, APR_THREAD_MUTEX_DEFAULT, pchild); @@ -947,7 +953,7 @@ void child_main(apr_pool_t *pconf) worker_main, (void *) i, 0, &tid); if (child_handles[i] == 0) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: _beginthreadex failed. Unable to create all worker threads. " + "Child %lu: _beginthreadex failed. Unable to create all worker threads. " "Created %d of the %d threads requested with the ThreadsPerChild configuration directive.", my_pid, threads_created, ap_threads_per_child); ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); @@ -1019,13 +1025,13 @@ void child_main(apr_pool_t *pconf) if (rv == WAIT_FAILED) { /* Something serious is wrong */ ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: WAIT_FAILED -- shutting down server", my_pid); + "Child %lu: WAIT_FAILED -- shutting down server", my_pid); break; } else if (cld == 0) { /* Exit event was signaled */ ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Exit event signaled. Child process is ending.", my_pid); + "Child %lu: Exit event signaled. Child process is ending.", my_pid); break; } else { @@ -1033,7 +1039,7 @@ void child_main(apr_pool_t *pconf) * Signal the parent to restart */ ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Process exiting because it reached " + "Child %lu: Process exiting because it reached " "MaxRequestsPerChild. Signaling the parent to " "restart a new child process.", my_pid); ap_signal_parent(SIGNAL_PARENT_RESTART); @@ -1078,11 +1084,11 @@ void child_main(apr_pool_t *pconf) rv = apr_proc_mutex_unlock(start_mutex); if (rv == APR_SUCCESS) { ap_log_error(APLOG_MARK,APLOG_NOTICE, rv, ap_server_conf, - "Child %d: Released the start mutex", my_pid); + "Child %lu: Released the start mutex", my_pid); } else { ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, - "Child %d: Failure releasing the start mutex", my_pid); + "Child %lu: Failure releasing the start mutex", my_pid); } /* Shutdown the worker threads */ @@ -1095,7 +1101,7 @@ void child_main(apr_pool_t *pconf) /* Post worker threads blocked on the ThreadDispatch IOCompletion port */ while (g_blocked_threads > 0) { ap_log_error(APLOG_MARK,APLOG_INFO, APR_SUCCESS, ap_server_conf, - "Child %d: %d threads blocked on the completion port", my_pid, g_blocked_threads); + "Child %lu: %d threads blocked on the completion port", my_pid, g_blocked_threads); for (i=g_blocked_threads; i > 0; i--) { PostQueuedCompletionStatus(ThreadDispatchIOCP, 0, IOCP_SHUTDOWN, NULL); } @@ -1135,7 +1141,7 @@ void child_main(apr_pool_t *pconf) if ((time_remains % 30000) == 0) { ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Waiting %d more seconds " + "Child %lu: Waiting %d more seconds " "for %d worker threads to finish.", my_pid, time_remains / 1000, threads_created); } @@ -1179,7 +1185,7 @@ void child_main(apr_pool_t *pconf) /* Kill remaining threads off the hard way */ if (threads_created) { ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Terminating %d threads that failed to exit.", + "Child %lu: Terminating %d threads that failed to exit.", my_pid, threads_created); } for (i = 0; i < threads_created; i++) { @@ -1194,7 +1200,7 @@ void child_main(apr_pool_t *pconf) } } ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: All worker threads have exited.", my_pid); + "Child %lu: All worker threads have exited.", my_pid); CloseHandle(allowed_globals.jobsemaphore); apr_thread_mutex_destroy(allowed_globals.jobmutex); diff --git a/server/mpm/winnt/config.m4 b/server/mpm/winnt/config.m4 new file mode 100644 index 00000000..93209588 --- /dev/null +++ b/server/mpm/winnt/config.m4 @@ -0,0 +1,3 @@ +if test "$MPM_NAME" = "winnt" ; then
+ APACHE_FAST_OUTPUT(server/mpm/$MPM_NAME/Makefile)
+fi
diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index 52c4ff9c..d9513175 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -39,6 +39,15 @@ #include <malloc.h> #include "apr_atomic.h" +/* Because ap_setup_listeners() is skipped in the child, any merging + * of [::]:80 and 0.0.0.0:80 for AP_ENABLE_V4_MAPPED in the parent + * won't have taken place in the child, so the child will expect to + * read two sockets for "Listen 80" but the parent will send only + * one. + */ +#ifdef AP_ENABLE_V4_MAPPED +#error The WinNT MPM does not currently support AP_ENABLE_V4_MAPPED +#endif /* scoreboard.c does the heavy lifting; all we do is create the child * score by moving a handle down the pipe into the child's stdin. @@ -50,7 +59,7 @@ server_rec *ap_server_conf; static HANDLE shutdown_event; /* used to signal the parent to shutdown */ static HANDLE restart_event; /* used to signal the parent to restart */ -static char ap_coredump_dir[MAX_STRING_LEN]; +char ap_coredump_dir[MAX_STRING_LEN]; static int one_process = 0; static char const* signal_arg = NULL; @@ -93,30 +102,11 @@ extern HANDLE exit_event; */ static HANDLE pipe; -/* Stub functions until this MPM supports the connection status API */ - -AP_DECLARE(void) ap_update_connection_status(long conn_id, const char *key, \ - const char *value) -{ - /* NOP */ -} - -AP_DECLARE(void) ap_reset_connection_status(long conn_id) -{ - /* NOP */ -} - -AP_DECLARE(apr_array_header_t *) ap_get_status_table(apr_pool_t *p) -{ - /* NOP */ - return NULL; -} - /* * Command processors */ -static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, char *arg) +static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, const char *arg) { const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err != NULL) { @@ -182,7 +172,7 @@ static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *ar } return NULL; } -static const char *set_disable_acceptex(cmd_parms *cmd, void *dummy, char *arg) +static const char *set_disable_acceptex(cmd_parms *cmd, void *dummy) { const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err != NULL) { @@ -331,9 +321,9 @@ AP_DECLARE(void) ap_signal_parent(ap_signal_parent_e type) * start mutex [signal from the parent to begin accept()] * scoreboard shm handle [to recreate the ap_scoreboard] */ -void get_handles_from_parent(server_rec *s, HANDLE *child_exit_event, - apr_proc_mutex_t **child_start_mutex, - apr_shm_t **scoreboard_shm) +static void get_handles_from_parent(server_rec *s, HANDLE *child_exit_event, + apr_proc_mutex_t **child_start_mutex, + apr_shm_t **scoreboard_shm) { HANDLE hScore; HANDLE ready_event; @@ -349,7 +339,7 @@ void get_handles_from_parent(server_rec *s, HANDLE *child_exit_event, &BytesRead, (LPOVERLAPPED) NULL) || (BytesRead != sizeof(HANDLE))) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Unable to retrieve the ready event from the parent", my_pid); + "Child %lu: Unable to retrieve the ready event from the parent", my_pid); exit(APEXIT_CHILDINIT); } @@ -360,7 +350,7 @@ void get_handles_from_parent(server_rec *s, HANDLE *child_exit_event, &BytesRead, (LPOVERLAPPED) NULL) || (BytesRead != sizeof(HANDLE))) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Unable to retrieve the exit event from the parent", my_pid); + "Child %lu: Unable to retrieve the exit event from the parent", my_pid); exit(APEXIT_CHILDINIT); } @@ -368,14 +358,14 @@ void get_handles_from_parent(server_rec *s, HANDLE *child_exit_event, &BytesRead, (LPOVERLAPPED) NULL) || (BytesRead != sizeof(os_start))) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Unable to retrieve the start_mutex from the parent", my_pid); + "Child %lu: Unable to retrieve the start_mutex from the parent", my_pid); exit(APEXIT_CHILDINIT); } *child_start_mutex = NULL; if ((rv = apr_os_proc_mutex_put(child_start_mutex, &os_start, s->process->pool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Child %d: Unable to access the start_mutex from the parent", my_pid); + "Child %lu: Unable to access the start_mutex from the parent", my_pid); exit(APEXIT_CHILDINIT); } @@ -383,21 +373,21 @@ void get_handles_from_parent(server_rec *s, HANDLE *child_exit_event, &BytesRead, (LPOVERLAPPED) NULL) || (BytesRead != sizeof(hScore))) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, - "Child %d: Unable to retrieve the scoreboard from the parent", my_pid); + "Child %lu: Unable to retrieve the scoreboard from the parent", my_pid); exit(APEXIT_CHILDINIT); } *scoreboard_shm = NULL; if ((rv = apr_os_shm_put(scoreboard_shm, &hScore, s->process->pool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Child %d: Unable to access the scoreboard from the parent", my_pid); + "Child %lu: Unable to access the scoreboard from the parent", my_pid); exit(APEXIT_CHILDINIT); } rv = ap_reopen_scoreboard(s->process->pool, scoreboard_shm, 1); if (rv || !(sb_shared = apr_shm_baseaddr_get(*scoreboard_shm))) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, - "Child %d: Unable to reopen the scoreboard from the parent", my_pid); + "Child %lu: Unable to reopen the scoreboard from the parent", my_pid); exit(APEXIT_CHILDINIT); } /* We must 'initialize' the scoreboard to relink all the @@ -406,7 +396,7 @@ void get_handles_from_parent(server_rec *s, HANDLE *child_exit_event, ap_init_scoreboard(sb_shared); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Child %d: Retrieved our scoreboard from the parent.", my_pid); + "Child %lu: Retrieved our scoreboard from the parent.", my_pid); } @@ -496,7 +486,7 @@ static int send_handles_to_child(apr_pool_t *p, * exclusively in the child process, receives them from the parent and * makes them availeble in the child. */ -void get_listeners_from_parent(server_rec *s) +static void get_listeners_from_parent(server_rec *s) { WSAPROTOCOL_INFO WSAProtocolInfo; ap_listen_rec *lr; @@ -530,7 +520,7 @@ void get_listeners_from_parent(server_rec *s) &WSAProtocolInfo, 0, 0); if (nsd == INVALID_SOCKET) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_netos_error(), ap_server_conf, - "Child %d: setup_inherited_listeners(), WSASocket failed to open the inherited socket.", my_pid); + "Child %lu: setup_inherited_listeners(), WSASocket failed to open the inherited socket.", my_pid); exit(APEXIT_CHILDINIT); } @@ -562,7 +552,7 @@ void get_listeners_from_parent(server_rec *s) } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Child %d: retrieved %d listeners from parent", my_pid, lcnt); + "Child %lu: retrieved %d listeners from parent", my_pid, lcnt); } @@ -582,14 +572,14 @@ static int send_listeners_to_child(apr_pool_t *p, DWORD dwProcessId, for (lr = ap_listeners; lr; lr = lr->next, ++lcnt) { apr_os_sock_t nsd; lpWSAProtocolInfo = apr_pcalloc(p, sizeof(WSAPROTOCOL_INFO)); - apr_os_sock_get(&nsd,lr->sd); + apr_os_sock_get(&nsd, lr->sd); ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, ap_server_conf, - "Parent: Duplicating socket %d and sending it to child process %d", + "Parent: Duplicating socket %d and sending it to child process %lu", nsd, dwProcessId); if (WSADuplicateSocket(nsd, dwProcessId, lpWSAProtocolInfo) == SOCKET_ERROR) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_netos_error(), ap_server_conf, - "Parent: WSADuplicateSocket failed for socket %d. Check the FAQ.", lr->sd ); + "Parent: WSADuplicateSocket failed for socket %d. Check the FAQ.", nsd); return -1; } @@ -597,13 +587,13 @@ static int send_listeners_to_child(apr_pool_t *p, DWORD dwProcessId, sizeof(WSAPROTOCOL_INFO), &BytesWritten)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, - "Parent: Unable to write duplicated socket %d to the child.", lr->sd ); + "Parent: Unable to write duplicated socket %d to the child.", nsd); return -1; } } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, - "Parent: Sent %d listeners to child %d", lcnt, dwProcessId); + "Parent: Sent %d listeners to child %lu", lcnt, dwProcessId); return 0; } @@ -722,11 +712,12 @@ static int create_process(apr_pool_t *p, HANDLE *child_proc, HANDLE *child_exit_ } env = apr_palloc(ptemp, (envc + 2) * sizeof (char*)); memcpy(env, _environ, envc * sizeof (char*)); - apr_snprintf(pidbuf, sizeof(pidbuf), "AP_PARENT_PID=%i", parent_pid); + apr_snprintf(pidbuf, sizeof(pidbuf), "AP_PARENT_PID=%lu", parent_pid); env[envc] = pidbuf; env[envc + 1] = NULL; - rv = apr_proc_create(&new_child, cmd, args, env, attr, ptemp); + rv = apr_proc_create(&new_child, cmd, (const char * const *)args, + (const char * const *)env, attr, ptemp); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, "Parent: Failed to create the child process."); @@ -845,13 +836,14 @@ static int create_process(apr_pool_t *p, HANDLE *child_proc, HANDLE *child_exit_ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_event) { int rv, cld; + int child_created; int restart_pending; int shutdown_pending; HANDLE child_exit_event; HANDLE event_handles[NUM_WAIT_HANDLES]; DWORD child_pid; - restart_pending = shutdown_pending = 0; + child_created = restart_pending = shutdown_pending = 0; event_handles[SHUTDOWN_HANDLE] = shutdown_event; event_handles[RESTART_HANDLE] = restart_event; @@ -866,6 +858,9 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even shutdown_pending = 1; goto die_now; } + + child_created = 1; + if (!strcasecmp(signal_arg, "runservice")) { mpm_service_started(); } @@ -915,7 +910,7 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even } if (SetEvent(child_exit_event) == 0) { ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, - "Parent: SetEvent for child process %d failed.", + "Parent: SetEvent for child process %pp failed.", event_handles[CHILD_HANDLE]); } /* Don't wait to verify that the child process really exits, @@ -935,14 +930,14 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even || exitcode == APEXIT_CHILDINIT || exitcode == APEXIT_INIT) { ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, - "Parent: child process exited with status %u -- Aborting.", exitcode); + "Parent: child process exited with status %lu -- Aborting.", exitcode); shutdown_pending = 1; } else { int i; restart_pending = 1; ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Parent: child process exited with status %u -- Restarting.", exitcode); + "Parent: child process exited with status %lu -- Restarting.", exitcode); for (i = 0; i < ap_threads_per_child; i++) { ap_update_child_status_from_indexes(0, i, SERVER_DEAD, NULL); } @@ -960,6 +955,10 @@ die_now: int timeout = 30000; /* Timeout is milliseconds */ winnt_mpm_state = AP_MPMQ_STOPPING; + if (!child_created) { + return 0; /* Tell the caller we do not want to restart */ + } + /* This shutdown is only marginally graceful. We will give the * child a bit of time to exit gracefully. If the time expires, * the child will be wacked. @@ -970,7 +969,8 @@ die_now: /* Signal the child processes to exit */ if (SetEvent(child_exit_event) == 0) { ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_os_error(), ap_server_conf, - "Parent: SetEvent for child process %d failed", event_handles[CHILD_HANDLE]); + "Parent: SetEvent for child process %pp failed", + event_handles[CHILD_HANDLE]); } if (event_handles[CHILD_HANDLE]) { rv = WaitForSingleObject(event_handles[CHILD_HANDLE], timeout); @@ -982,7 +982,8 @@ die_now: } else { ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Parent: Forcing termination of child process %d ", event_handles[CHILD_HANDLE]); + "Parent: Forcing termination of child process %pp", + event_handles[CHILD_HANDLE]); TerminateProcess(event_handles[CHILD_HANDLE], 1); CloseHandle(event_handles[CHILD_HANDLE]); event_handles[CHILD_HANDLE] = NULL; @@ -1057,9 +1058,9 @@ static apr_status_t service_set = SERVICE_UNSET; static apr_status_t service_to_start_success; static int inst_argc; static const char * const *inst_argv; -static char *service_name = NULL; +static const char *service_name = NULL; -void winnt_rewrite_args(process_rec *process) +static void winnt_rewrite_args(process_rec *process) { /* Handle the following SCM aspects in this phase: * @@ -1199,7 +1200,7 @@ void winnt_rewrite_args(process_rec *process) optbuf[0] = '-'; optbuf[2] = '\0'; - apr_getopt_init(&opt, process->pool, process->argc, (char**) process->argv); + apr_getopt_init(&opt, process->pool, process->argc, process->argv); opt->errfn = NULL; while ((rv = apr_getopt(opt, "wn:k:" AP_SERVER_BASEARGS, optbuf + 1, &optarg)) == APR_SUCCESS) { @@ -1523,7 +1524,7 @@ static int winnt_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pt * across a restart */ PSECURITY_ATTRIBUTES sa = GetNullACL(); /* returns NULL if invalid (Win95?) */ - setup_signal_names(apr_psprintf(pconf,"ap%d", parent_pid)); + setup_signal_names(apr_psprintf(pconf,"ap%lu", parent_pid)); ap_log_pid(pconf, ap_pid_fname); @@ -1635,7 +1636,7 @@ static void winnt_child_init(apr_pool_t *pchild, struct server_rec *s) { apr_status_t rv; - setup_signal_names(apr_psprintf(pchild,"ap%d", parent_pid)); + setup_signal_names(apr_psprintf(pchild,"ap%lu", parent_pid)); /* This is a child process, not in single process mode */ if (!one_process) { @@ -1657,7 +1658,7 @@ static void winnt_child_init(apr_pool_t *pchild, struct server_rec *s) APR_LOCK_DEFAULT, s->process->pool); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, - "%s child %d: Unable to init the start_mutex.", + "%s child %lu: Unable to init the start_mutex.", service_name, my_pid); exit(APEXIT_CHILDINIT); } @@ -1700,12 +1701,12 @@ AP_DECLARE(int) ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s ) /* The child process or in one_process (debug) mode */ ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Child process is running", my_pid); + "Child %lu: Child process is running", my_pid); child_main(pconf); ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, - "Child %d: Child process is exiting", my_pid); + "Child %lu: Child process is exiting", my_pid); return 1; } else diff --git a/server/mpm/winnt/mpm_winnt.h b/server/mpm/winnt/mpm_winnt.h index dfe0e518..e21a6f43 100644 --- a/server/mpm/winnt/mpm_winnt.h +++ b/server/mpm/winnt/mpm_winnt.h @@ -62,7 +62,7 @@ void mpm_start_child_console_handler(void); /* From nt_eventlog.c: */ -void mpm_nt_eventlog_stderr_open(char *display_name, apr_pool_t *p); +void mpm_nt_eventlog_stderr_open(const char *display_name, apr_pool_t *p); void mpm_nt_eventlog_stderr_flush(void); /* From winnt.c: */ @@ -126,5 +126,9 @@ PCOMP_CONTEXT mpm_get_completion_context(void); void mpm_recycle_completion_context(PCOMP_CONTEXT pCompContext); apr_status_t mpm_post_completion_context(PCOMP_CONTEXT pCompContext, io_state_e state); void hold_console_open_on_error(void); + +/* From child.c: */ +void child_main(apr_pool_t *pconf); + #endif /* APACHE_MPM_WINNT_H */ /** @} */ diff --git a/server/mpm/winnt/nt_eventlog.c b/server/mpm/winnt/nt_eventlog.c index baa1a88b..d8d758bb 100644 --- a/server/mpm/winnt/nt_eventlog.c +++ b/server/mpm/winnt/nt_eventlog.c @@ -24,7 +24,7 @@ #include "apr_portable.h" #include "ap_regkey.h" -static char *display_name = NULL; +static const char *display_name = NULL; static HANDLE stderr_thread = NULL; static HANDLE stderr_ready; @@ -101,7 +101,7 @@ static DWORD WINAPI service_stderr_thread(LPVOID hPipe) if ((errres = GetLastError()) != ERROR_BROKEN_PIPE) { apr_snprintf(errbuf, sizeof(errbuf), - "Win32 error %d reading stderr pipe stream\r\n", + "Win32 error %lu reading stderr pipe stream\r\n", GetLastError()); ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0, @@ -131,13 +131,11 @@ void mpm_nt_eventlog_stderr_flush(void) } -void mpm_nt_eventlog_stderr_open(char *argv0, apr_pool_t *p) +void mpm_nt_eventlog_stderr_open(const char *argv0, apr_pool_t *p) { SECURITY_ATTRIBUTES sa; - HANDLE hProc = GetCurrentProcess(); HANDLE hPipeRead = NULL; HANDLE hPipeWrite = NULL; - HANDLE hDup = NULL; DWORD threadid; apr_file_t *eventlog_file; apr_file_t *stderr_file; diff --git a/server/mpm/winnt/service.c b/server/mpm/winnt/service.c index 6c5d87b4..aa5291d2 100644 --- a/server/mpm/winnt/service.c +++ b/server/mpm/winnt/service.c @@ -34,6 +34,7 @@ #endif #undef _WINUSER_ #include <winuser.h> +#include <time.h> static char *mpm_service_name = NULL; static char *mpm_display_name = NULL; @@ -52,42 +53,6 @@ static struct static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint); -#define PRODREGKEY "SOFTWARE\\" AP_SERVER_BASEVENDOR "\\" \ - AP_SERVER_BASEPRODUCT "\\" AP_SERVER_BASEREVISION - -/* - * Get the server root from the registry into 'dir' which is - * size bytes long. Returns 0 if the server root was found - * or if the serverroot key does not exist (in which case - * dir will contain an empty string), or -1 if there was - * an error getting the key. - */ -apr_status_t ap_registry_get_server_root(apr_pool_t *p, char **buf) -{ - apr_status_t rv; - ap_regkey_t *key; - - if ((rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, PRODREGKEY, - APR_READ, p)) == APR_SUCCESS) { - rv = ap_regkey_value_get(buf, key, "ServerRoot", p); - ap_regkey_close(key); - if (rv == APR_SUCCESS) - return rv; - } - - if ((rv = ap_regkey_open(&key, AP_REGKEY_CURRENT_USER, PRODREGKEY, - APR_READ, p)) == APR_SUCCESS) { - rv = ap_regkey_value_get(buf, key, "ServerRoot", p); - ap_regkey_close(key); - if (rv == APR_SUCCESS) - return rv; - } - - *buf = NULL; - return rv; -} - - /* The service configuration's is stored under the following trees: * * HKLM\System\CurrentControlSet\Services\[service name] @@ -157,7 +122,8 @@ void hold_console_open_on_error(void) return; } remains = ((start + 30) - time(NULL)); - sprintf (count, "%d...", remains); + sprintf(count, "%d...", + (int)remains); /* 30 or less, so can't overflow int */ if (!SetConsoleCursorPosition(hConErr, coninfo.dwCursorPosition)) return; if (!WriteConsole(hConErr, count, (DWORD)strlen(count), &result, NULL) @@ -427,7 +393,6 @@ static void set_service_description(void) { const char *full_description; SC_HANDLE schSCManager; - BOOL ret = 0; /* Nothing to do if we are a console */ @@ -565,7 +530,7 @@ static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv) } -DWORD WINAPI service_nt_dispatch_thread(LPVOID nada) +static DWORD WINAPI service_nt_dispatch_thread(LPVOID nada) { apr_status_t rv = APR_SUCCESS; @@ -675,7 +640,7 @@ apr_status_t mpm_merge_service_args(apr_pool_t *p, } -void service_stopped(void) +static void service_stopped(void) { /* Still have a thread & window to clean up, so signal now */ if (globdat.service_thread) @@ -1075,7 +1040,7 @@ apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc, if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { - char **start_argv; + CHAR **start_argv; SC_HANDLE schService; SC_HANDLE schSCManager; diff --git a/server/mpm_common.c b/server/mpm_common.c index 1c50d45b..754fc643 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -561,7 +561,7 @@ int initgroups(const char *name, gid_t basegid) return setgroups(index, groups); #endif /* def QNX */ } -#endif /* def NEED_INITGROUPS */ +#endif /* def HAVE_INITGROUPS */ #ifdef AP_MPM_USES_POD diff --git a/server/protocol.c b/server/protocol.c index 570ec2e0..55468fc1 100644 --- a/server/protocol.c +++ b/server/protocol.c @@ -608,6 +608,9 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb) r->proto_num = HTTP_VERSION(1,0); r->protocol = apr_pstrdup(r->pool, "HTTP/1.0"); } + else if (APR_STATUS_IS_TIMEUP(rv)) { + r->status = HTTP_REQUEST_TIME_OUT; + } return 0; } } while ((len <= 0) && (++num_blank_lines < max_blank_lines)); @@ -691,7 +694,12 @@ AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb &len, r, 0, bb); if (rv != APR_SUCCESS) { - r->status = HTTP_BAD_REQUEST; + if (APR_STATUS_IS_TIMEUP(rv)) { + r->status = HTTP_REQUEST_TIME_OUT; + } + else { + r->status = HTTP_BAD_REQUEST; + } /* ap_rgetline returns APR_ENOSPC if it fills up the buffer before * finding the end-of-line. This is only going to happen if it @@ -877,7 +885,7 @@ request_rec *ap_read_request(conn_rec *conn) r->read_length = 0; r->read_body = REQUEST_NO_BODY; - r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */ + r->status = HTTP_OK; /* Until further notice */ r->the_request = NULL; /* Begin by presuming any module can make its own path_info assumptions, @@ -898,6 +906,14 @@ request_rec *ap_read_request(conn_rec *conn) apr_brigade_destroy(tmp_bb); return r; } + else if (r->status == HTTP_REQUEST_TIME_OUT) { + ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); + if (!r->connection->keepalives) { + ap_run_log_transaction(r); + } + apr_brigade_destroy(tmp_bb); + return r; + } apr_brigade_destroy(tmp_bb); return NULL; @@ -916,7 +932,7 @@ request_rec *ap_read_request(conn_rec *conn) if (!r->assbackwards) { ap_get_mime_headers_core(r, tmp_bb); - if (r->status != HTTP_REQUEST_TIME_OUT) { + if (r->status != HTTP_OK) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "request failed: error reading the headers"); ap_send_error_response(r, 0); @@ -957,8 +973,6 @@ request_rec *ap_read_request(conn_rec *conn) apr_brigade_destroy(tmp_bb); - r->status = HTTP_OK; /* Until further notice. */ - /* update what we think the virtual host is based on the headers we've * now read. may update status. */ @@ -1641,6 +1655,7 @@ AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers) { hdr_ptr x; char *status_line = NULL; + request_rec *rr; if (r->proto_num < 1001) { /* don't send interim response to HTTP/1.0 Client */ @@ -1652,6 +1667,14 @@ AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers) return; } + /* if we send an interim response, we're no longer in a state of + * expecting one. Also, this could feasibly be in a subrequest, + * so we need to propagate the fact that we responded. + */ + for (rr = r; rr != NULL; rr = rr->main) { + rr->expecting_100 = 0; + } + status_line = apr_pstrcat(r->pool, AP_SERVER_PROTOCOL, " ", r->status_line, CRLF, NULL); ap_xlate_proto_to_ascii(status_line, strlen(status_line)); diff --git a/server/request.c b/server/request.c index 1801cf7b..f076e637 100644 --- a/server/request.c +++ b/server/request.c @@ -109,7 +109,7 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) core_dir_config *d; d = ap_get_module_config(r->per_dir_config, &core_module); if (d->allow_encoded_slashes) { - access_status = ap_unescape_url_keep2f(r->parsed_uri.path); + access_status = ap_unescape_url_keep2f_ex(r->parsed_uri.path, d->decode_encoded_slashes); } else { access_status = ap_unescape_url(r->parsed_uri.path); diff --git a/server/util.c b/server/util.c index ac429c78..d0b90c6a 100644 --- a/server/util.c +++ b/server/util.c @@ -1589,7 +1589,7 @@ AP_DECLARE(int) ap_unescape_url(char *url) return OK; } -AP_DECLARE(int) ap_unescape_url_keep2f(char *url) +AP_DECLARE(int) ap_unescape_url_keep2f_ex(char *url, int decode_2f) { register int badesc, badpath; char *x, *y; @@ -1617,6 +1617,10 @@ AP_DECLARE(int) ap_unescape_url_keep2f(char *url) if (decoded == '\0') { badpath = 1; } + else if (IS_SLASH(decoded) && !decode_2f) { + /* do not decode, just let it go by as-is */ + *x = *y; + } else { *x = decoded; y += 2; @@ -1636,6 +1640,11 @@ AP_DECLARE(int) ap_unescape_url_keep2f(char *url) } } +AP_DECLARE(int) ap_unescape_url_keep2f(char *url) +{ + return ap_unescape_url_keep2f_ex(url, 1); +} + AP_DECLARE(char *) ap_construct_server(apr_pool_t *p, const char *hostname, apr_port_t port, const request_rec *r) { diff --git a/server/util_script.c b/server/util_script.c index 6d6f3f4a..1300951b 100644 --- a/server/util_script.c +++ b/server/util_script.c @@ -187,16 +187,16 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r) apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_path)); #ifdef WIN32 - if (env_temp = getenv("SystemRoot")) { + if ((env_temp = getenv("SystemRoot")) != NULL) { apr_table_addn(e, "SystemRoot", env_temp); } - if (env_temp = getenv("COMSPEC")) { + if ((env_temp = getenv("COMSPEC")) != NULL) { apr_table_addn(e, "COMSPEC", env_temp); } - if (env_temp = getenv("PATHEXT")) { + if ((env_temp = getenv("PATHEXT")) != NULL) { apr_table_addn(e, "PATHEXT", env_temp); } - if (env_temp = getenv("WINDIR")) { + if ((env_temp = getenv("WINDIR")) != NULL) { apr_table_addn(e, "WINDIR", env_temp); } #endif |
