From: William A. Rowe Jr Date: Wed, 17 May 2000 00:35:21 +0000 (+0000) Subject: Radical overhaul of the Apache-2.0/Win32 mpm <-> service schema. X-Git-Tag: APACHE_2_0_ALPHA_4~134 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9bfb956e51add33872f42fc86ba6258e2cbfe143;p=thirdparty%2Fapache%2Fhttpd.git Radical overhaul of the Apache-2.0/Win32 mpm <-> service schema. 1) Services and Registry are not part of the core Apache operations, so registry.c and service.c are moved into Apache.exe - assuring the service control layers of NT and 95 are truly isolated. 2) Isolation can't be complete, we need to know when the mpm is fully initialized. A new pointer to a no-arg function returning void is provided for this purpose, ap_mpm_init_complete. It is only called if overridden with a non-NULL value prior to invoking apache_main. 3) Control+C, Control+Break are handled on both WinNT and Win9x. 4) The window close, logoff and shutdown events are handled on WinNT. 5) The beginnings of a Win95 service startup are provided, -k startservice but this is horribly incomplete since Win95 will NOT report shutdown. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@85235 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/Apache.dsp b/Apache.dsp index d115a354066..1e7180ce8b5 100644 --- a/Apache.dsp +++ b/Apache.dsp @@ -90,10 +90,26 @@ LINK32=link.exe SOURCE=.\os\win32\main_win32.c # End Source File +# Begin Source File + +SOURCE=.\os\win32\registry.c +# End Source File +# Begin Source File + +SOURCE=.\os\win32\service.c +# End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\os\win32\registry.h +# End Source File +# Begin Source File + +SOURCE=.\os\win32\service.h +# End Source File # End Group # Begin Group "Resource Files" @@ -105,6 +121,13 @@ SOURCE=.\os\win32\apache.ico # Begin Source File SOURCE=.\os\win32\apache.rc + +!IF "$(CFG)" == "Apache - Win32 Release" + +!ELSEIF "$(CFG)" == "Apache - Win32 Debug" + +!ENDIF + # End Source File # End Group # End Target diff --git a/ApacheCore.def b/ApacheCore.def index 627160c00b4..68836fc32de 100644 --- a/ApacheCore.def +++ b/ApacheCore.def @@ -369,18 +369,18 @@ EXPORTS regerror @364 ap_send_error_response @365 ap_start_shutdown @366 - send_signal_to_service @367 +; send_signal_to_service @367 ap_read_config @368 ap_server_pre_read_config @369 ap_server_post_read_config @370 ap_setup_prelinked_modules @371 - RemoveService @372 - InstallService @373 - isValidService @374 - service_main @375 - isProcessService @376 - ap_registry_get_server_root @377 - ap_registry_get_service_conf @378 +; RemoveService @372 +; InstallService @373 +; isValidService @374 +; service_main @375 +; isProcessService @376 +; ap_registry_get_server_root @377 +; ap_registry_get_service_conf @378 ap_hook_pre_connection @379 ap_hook_post_read_request @380 ap_hook_log_transaction @381 @@ -399,3 +399,4 @@ EXPORTS ap_run_http_method @394 ap_bread_core @395 ap_bwrite_core @396 + ap_mpm_init_complete @397 diff --git a/ApacheCore.dsp b/ApacheCore.dsp index 64bdba3e9b1..1cd8efabedf 100644 --- a/ApacheCore.dsp +++ b/ApacheCore.dsp @@ -227,18 +227,10 @@ SOURCE=.\os\win32\modules.c # End Source File # Begin Source File -SOURCE=.\os\win32\registry.c -# End Source File -# Begin Source File - SOURCE=.\main\rfc1413.c # End Source File # Begin Source File -SOURCE=.\os\win32\service.c -# End Source File -# Begin Source File - SOURCE=.\main\util.c # End Source File # Begin Source File @@ -363,18 +355,10 @@ SOURCE=.\os\win32\os.h # End Source File # Begin Source File -SOURCE=.\os\win32\registry.h -# End Source File -# Begin Source File - SOURCE=.\include\rfc1413.h # End Source File # Begin Source File -SOURCE=.\os\win32\service.h -# End Source File -# Begin Source File - SOURCE=.\include\util_cfgtree.h # End Source File # Begin Source File diff --git a/httpd.dsp b/httpd.dsp index 64bdba3e9b1..1cd8efabedf 100644 --- a/httpd.dsp +++ b/httpd.dsp @@ -227,18 +227,10 @@ SOURCE=.\os\win32\modules.c # End Source File # Begin Source File -SOURCE=.\os\win32\registry.c -# End Source File -# Begin Source File - SOURCE=.\main\rfc1413.c # End Source File # Begin Source File -SOURCE=.\os\win32\service.c -# End Source File -# Begin Source File - SOURCE=.\main\util.c # End Source File # Begin Source File @@ -363,18 +355,10 @@ SOURCE=.\os\win32\os.h # End Source File # Begin Source File -SOURCE=.\os\win32\registry.h -# End Source File -# Begin Source File - SOURCE=.\include\rfc1413.h # End Source File # Begin Source File -SOURCE=.\os\win32\service.h -# End Source File -# Begin Source File - SOURCE=.\include\util_cfgtree.h # End Source File # Begin Source File diff --git a/include/http_config.h b/include/http_config.h index 30a80cc0e2b..f3fcdd25ee2 100644 --- a/include/http_config.h +++ b/include/http_config.h @@ -382,6 +382,7 @@ void ap_show_modules(void); server_rec *ap_read_config(process_rec *process, ap_pool_t *temp_pool, const char *config_name); void ap_post_config_hook(ap_pool_t *pconf, ap_pool_t *plog, ap_pool_t *ptemp, server_rec *s); void ap_child_init_hook(ap_pool_t *pchild, server_rec *s); +void ap_run_pre_config(ap_pool_t *p, ap_pool_t *plog, ap_pool_t *ptemp); void ap_register_hooks(module *m); void ap_hook_deregister_all(void); diff --git a/libhttpd.def b/libhttpd.def index 627160c00b4..68836fc32de 100644 --- a/libhttpd.def +++ b/libhttpd.def @@ -369,18 +369,18 @@ EXPORTS regerror @364 ap_send_error_response @365 ap_start_shutdown @366 - send_signal_to_service @367 +; send_signal_to_service @367 ap_read_config @368 ap_server_pre_read_config @369 ap_server_post_read_config @370 ap_setup_prelinked_modules @371 - RemoveService @372 - InstallService @373 - isValidService @374 - service_main @375 - isProcessService @376 - ap_registry_get_server_root @377 - ap_registry_get_service_conf @378 +; RemoveService @372 +; InstallService @373 +; isValidService @374 +; service_main @375 +; isProcessService @376 +; ap_registry_get_server_root @377 +; ap_registry_get_service_conf @378 ap_hook_pre_connection @379 ap_hook_post_read_request @380 ap_hook_log_transaction @381 @@ -399,3 +399,4 @@ EXPORTS ap_run_http_method @394 ap_bread_core @395 ap_bwrite_core @396 + ap_mpm_init_complete @397 diff --git a/os/win32/os.h b/os/win32/os.h index bee53b9171c..7c246d6392c 100644 --- a/os/win32/os.h +++ b/os/win32/os.h @@ -109,7 +109,7 @@ #define USE_MMAP_SCOREBOARD #define HAVE_CANONICAL_FILENAME #define HAVE_DRIVE_LETTERS -#define HAVE_SENDFILE +#define HAVE_SENDFILE_UNKNOWN typedef int uid_t; typedef int gid_t; diff --git a/server/main.c b/server/main.c index 1e87e79cad4..ed6a8b8f395 100644 --- a/server/main.c +++ b/server/main.c @@ -280,9 +280,9 @@ static void usage(process_rec *process) ap_pool_t *g_pHookPool; #ifdef WIN32 -API_EXPORT_NONSTD(int) apache_main(int argc, char *argv[]) +API_EXPORT(int) apache_main(int argc, char *argv[]) #else -API_EXPORT_NONSTD(int) main(int argc, char *argv[]) +API_EXPORT(int) main(int argc, char *argv[]) #endif { int c; diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index 09a5c79c84e..0be5f8b2668 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -68,7 +68,7 @@ #include "ap_config.h" #include "ap_listen.h" #include "mpm_default.h" -#include "service.h" +//#include "service.h" #include "iol_socket.h" #include "winnt.h" @@ -107,6 +107,8 @@ HANDLE maintenance_event; ap_lock_t *start_mutex; int my_pid; int parent_pid; +typedef void (CALLBACK *ap_completion_t)(); +API_VAR_EXPORT ap_completion_t ap_mpm_init_complete = NULL; static ap_status_t socket_cleanup(void *sock) { @@ -1555,7 +1557,7 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even /* Create child process * Should only be one in this version of Apache for WIN32 */ - service_set_status(SERVICE_START_PENDING); + //service_set_status(SERVICE_START_PENDING); while (remaining_children_to_start--) { if (create_process(pconf, process_handles, process_kill_events, ¤t_live_processes) < 0) { @@ -1565,7 +1567,7 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even goto die_now; } } - service_set_status(SERVICE_RUNNING); + //service_set_status(SERVICE_RUNNING); restart_pending = shutdown_pending = 0; @@ -1738,7 +1740,7 @@ static void winnt_post_config(ap_pool_t *pconf, ap_pool_t *plog, ap_pool_t *ptem } ap_log_pid(pconf, ap_pid_fname); - service_set_status(SERVICE_START_PENDING); + //service_set_status(SERVICE_START_PENDING); /* Create shutdown event, apPID_shutdown, where PID is the parent * Apache process ID. Shutdown is signaled by 'apache -k shutdown'. @@ -1763,7 +1765,10 @@ static void winnt_post_config(ap_pool_t *pconf, ap_pool_t *plog, ap_pool_t *ptem exit(1); } CleanNullACL((void *)sa); - + + if (ap_mpm_init_complete) + ap_mpm_init_complete(); + /* Create the start mutex, apPID, where PID is the parent Apache process ID. * Ths start mutex is used during a restart to prevent more than one * child process from entering the accept loop at once. @@ -1808,7 +1813,7 @@ API_EXPORT(int) ap_mpm_run(ap_pool_t *_pconf, ap_pool_t *plog, server_rec *s ) CloseHandle(restart_event); CloseHandle(shutdown_event); - service_set_status(SERVICE_STOPPED); + //service_set_status(SERVICE_STOPPED); return 1; } diff --git a/server/mpm/winnt/service.c b/server/mpm/winnt/service.c index c99b4abe62e..e60b8a01695 100644 --- a/server/mpm/winnt/service.c +++ b/server/mpm/winnt/service.c @@ -71,6 +71,9 @@ #include "registry.h" #include "ap_mpm.h" +typedef void (CALLBACK *ap_completion_t)(); +API_VAR_IMPORT ap_completion_t ap_mpm_init_complete; + static struct { int (*main_fn)(int, char **); @@ -90,6 +93,53 @@ static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint); static int ap_start_service(SC_HANDLE); static int ap_stop_service(SC_HANDLE); +static void CALLBACK report_service95_running() +{ + FreeConsole(); + + /* We do this only once, ever */ + ap_mpm_init_complete = NULL; +} + +int service95_main(int (*main_fn)(int, char **), int argc, char **argv ) +{ + HINSTANCE hkernel; + DWORD (WINAPI *RegisterServiceProcess)(DWORD, DWORD); + + /* Obtain a handle to the kernel library */ + hkernel = LoadLibrary("KERNEL32.DLL"); + if (!hkernel) + return -1; + + /* Find the RegisterServiceProcess function */ + RegisterServiceProcess = (DWORD (WINAPI *)(DWORD, DWORD)) + GetProcAddress(hkernel, "RegisterServiceProcess"); + if (RegisterServiceProcess == NULL) + return -1; + + /* Register this process as a service */ + if (!RegisterServiceProcess((DWORD)NULL, 1)) + return -1; + + /* Eliminate the console for the remainer of the service session */ + ap_mpm_init_complete = report_service95_running; + + /* Run the service */ + globdat.exit_status = main_fn(argc, argv); + + /* When the service quits, remove it from the + system service table */ + RegisterServiceProcess((DWORD)NULL, 0); + + /* Free the kernel library */ + // Worthless, methinks, since it won't be reclaimed + // FreeLibrary(hkernel); + + /* We have to quit right here to avoid an invalid page fault */ + // But, this is worth experimenting with! + return (globdat.exit_status); +} + int service_main(int (*main_fn)(int, char **), int argc, char **argv ) { SERVICE_TABLE_ENTRY dispatchTable[] = @@ -125,6 +175,17 @@ void service_cd() chdir(buf); } +static void CALLBACK report_service_started() +{ + ReportStatusToSCMgr( + SERVICE_RUNNING, // service state + NO_ERROR, // exit code + 0); // wait hint + + /* This is only reported once, ever! */ + ap_mpm_init_complete = NULL; +} + void __stdcall service_main_fn(DWORD argc, LPTSTR *argv) { int i, new_argc; @@ -157,6 +218,8 @@ void __stdcall service_main_fn(DWORD argc, LPTSTR *argv) NO_ERROR, // exit code 3000); // wait hint + ap_mpm_init_complete = report_service_started; + service_cd(); /* Fetch server_conf from the registry