You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by wr...@locus.apache.org on 2000/05/19 07:01:55 UTC
cvs commit: apache-2.0/src/modules/mpm/winnt winnt.c winnt.h
wrowe 00/05/18 22:01:54
Modified: src/os/win32 main_win32.c registry.c service.c service.h
src/include ap_listen.h http_main.h
src/lib/apr/include apr.hw
src/lib/apr/threadproc/win32 proc.c
src/modules/mpm/winnt winnt.c winnt.h
Added: src/os/win32 main_win32.h
Log:
Fixes to allow Apache to run as a Win95 service... highlights
main_win32.h : Moved delarations to a header, by request
ap_listen.h : References types declared in http_config.h
http_main.h : Add the Win32 flavor entry point declaration
apr.hw : Cleanup the redundancy department of redundancy
win32/proc.c : Double null termination was required here
Everything else should be obvious and isolated to Win32.
Build files will be committed seperately.
Revision Changes Path
1.16 +89 -24 apache-2.0/src/os/win32/main_win32.c
Index: main_win32.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/os/win32/main_win32.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- main_win32.c 2000/05/17 00:35:20 1.15
+++ main_win32.c 2000/05/19 05:01:49 1.16
@@ -65,7 +65,12 @@
* link an executable without at least one object file. This
* satistifies that requirement.
*/
+
+#ifdef WIN32
+
#define CORE_PRIVATE
+
+#include "main_win32.h"
#include "httpd.h"
#include "http_main.h"
#include "http_config.h"
@@ -74,12 +79,11 @@
#include "http_log.h"
#include "registry.h"
#include "ap_config.h"
+#include "..\..\modules\mpm\winnt\winnt.h"
-API_EXPORT(int) apache_main(int argc, char *argv[]);
-#define DEFAULTSERVICENAME "Apache"
+static OSVERSIONINFO osver;
-typedef void (CALLBACK *ap_completion_t)();
-API_VAR_IMPORT ap_completion_t ap_mpm_init_complete;
+#define DEFAULTSERVICENAME "Apache"
static const char* read_config_cmd(char *filename, char *cmd, ap_pool_t *p)
{
@@ -110,6 +114,7 @@
}
return s;
}
+
static void signal_parent(const char* file, const char* signal,
ap_pool_t *p)
{
@@ -199,12 +204,60 @@
return FALSE;
}
+static BOOL CALLBACK child_control_handler(DWORD ctrl_type)
+{
+ switch (ctrl_type)
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ fprintf(stderr, "Apache server interrupted...\n");
+ /* for Interrupt signals, ignore them.
+ * The system will also signal the parent process,
+ * which will terminate Apache.
+ */
+ return TRUE;
+
+ case CTRL_CLOSE_EVENT:
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ /* for Shutdown signals, ignore them, but... .
+ * The system will also signal the parent process,
+ * which will terminate Apache, so we need to wait.
+ */
+ Sleep(30000);
+ return TRUE;
+ }
+
+ /* We should never get here, but this is (mostly) harmless */
+ return FALSE;
+}
+
void CALLBACK console_started_hook()
{
- SetConsoleCtrlHandler(console_control_handler, TRUE);
+ if (getenv("AP_PARENT_PID"))
+ SetConsoleCtrlHandler(child_control_handler, TRUE);
+ else
+ SetConsoleCtrlHandler(console_control_handler, TRUE);
+}
- /* We do this only once, ever! */
- ap_mpm_init_complete = NULL;
+void cwd_truepath()
+{
+ /* change to the drive with the executable */
+ char buf[MAX_PATH], *term;
+ GetModuleFileName(NULL, buf, MAX_PATH);
+ term = strrchr(buf, '\\');
+ if (!term)
+ term = strrchr(buf, '/');
+ if (!term)
+ term = strrchr(buf, ':');
+ if (term) {
+ *term = '\0';
+ chdir(buf);
+ if (buf[1] == ':') {
+ buf[2] = 0;
+ chdir(buf);
+ }
+ }
}
int main(int argc, char *argv[])
@@ -212,22 +265,23 @@
ap_pool_t *pwincmd;
int c, rv;
char *ch;
- char *service_name = NULL; //DEFAULTSERVICENAME;
+ char *service_name = NULL;
char *signal = NULL;
char *server_root = NULL;
char *server_confname = SERVER_CONFIG_FILE;
char *temp_server_confname = NULL;
char cwd[MAX_STRING_LEN];
char **new;
-
- BOOLEAN install = FALSE;
- BOOLEAN uninstall = FALSE;
-
+ BOOL install = FALSE;
+ BOOL uninstall = FALSE;
ap_status_t status;
ap_array_header_t *cmdtbl;
int new_argc = 0;
+ cwd_truepath();
+
status = ap_initialize();
+
if (status != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, status, NULL,
"ap_initialize() failure");
@@ -241,6 +295,9 @@
cleanup_and_exit();
}
+ osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osver);
+
/* Set up default server_root */
if (!GetCurrentDirectory(sizeof(cwd),cwd)) {
ap_log_error(APLOG_MARK,APLOG_ERR, GetLastError(), NULL, "GetCurrentDirectory() failure");
@@ -260,7 +317,7 @@
* HKLM\System\CurrentControlSet\Services\[Svc name]\Parameters\ConfPath
*/
if (isProcessService()) {
- service_main(apache_main, argc, argv);
+ servicent_main(apache_main, argc, argv);
cleanup_and_exit();
}
@@ -278,7 +335,7 @@
break;
case 'n':
service_name = ap_pstrdup(pwincmd, ap_optarg);
- if (isValidService(ap_optarg)) {
+ if (isValidService(pwincmd, ap_optarg)) {
ap_registry_get_service_conf(pwincmd, &server_confname, ap_optarg);
}
break;
@@ -302,6 +359,12 @@
}
}
+ /* Set optreset and optind to allow ap_getopt to work correctly
+ * when called from http_main.c
+ */
+ ap_optreset = 1;
+ ap_optind = 1;
+
/* Determine server_confname.
* server_confname is found in this order:
* (1) -f or -n
@@ -343,20 +406,23 @@
if (install) {
if (!service_name)
service_name = DEFAULTSERVICENAME;
- InstallService(service_name, server_confname);
+ InstallServiceNT(service_name, server_confname);
cleanup_and_exit();
}
/* Handle -u (uninstall service) */
if (uninstall) {
if (!service_name)
service_name = DEFAULTSERVICENAME;
- RemoveService(service_name);
+ RemoveServiceNT(service_name);
cleanup_and_exit();
}
/* Handle -k startservice */
if (signal && !strcasecmp(signal, "startservice")) {
- service95_main(apache_main, argc, argv);
+ if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+ service9x_main(apache_main, argc, argv);
+ else
+ servicent_main(apache_main, argc, argv);
cleanup_and_exit();
}
@@ -394,18 +460,17 @@
*new = server_root;
new_argc += 4;
- /* Set optreset and optind to allow ap_getopt to work correctly
- * when called from http_main.c
- */
- ap_optreset = 1;
- ap_optind = 1;
-
/* Proxy to delay console_control_handler hook until all is running */
ap_mpm_init_complete = console_started_hook;
rv = apache_main(new_argc, (char**) cmdtbl->elts);
- SetConsoleCtrlHandler(console_control_handler, FALSE);
+ if (getenv("AP_PARENT_PID"))
+ SetConsoleCtrlHandler(child_control_handler, FALSE);
+ else
+ SetConsoleCtrlHandler(console_control_handler, FALSE);
return (rv);
}
+
+#endif /* WIN32 */
1.19 +2 -30 apache-2.0/src/os/win32/registry.c
Index: registry.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/os/win32/registry.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- registry.c 2000/05/01 14:40:03 1.18
+++ registry.c 2000/05/19 05:01:49 1.19
@@ -101,6 +101,7 @@
#define SERVICEKEYPRE "System\\CurrentControlSet\\Services\\"
#define SERVICEKEYPOST "\\Parameters"
+#define SERVICELAUNCH9X "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices\\"
/*
* The Windows API registry key functions don't set the last error
* value (the windows equivalent of errno). So we need to set it
@@ -253,19 +254,6 @@
* dir will contain an empty string), or -1 if there was
* an error getting the key.
*/
-#if 0
-int ap_registry_get_server_root(ap_pool_t *p, char *dir, int size)
-{
- int rv;
-
- rv = ap_registry_get_key_int(p, REGKEY, "ServerRoot", dir, size, NULL);
- if (rv < 0) {
- dir[0] = '\0';
- }
-
- return (rv < -1) ? -1 : 0;
-}
-#else
int ap_registry_get_server_root(ap_pool_t *p, char **buf)
{
int rv;
@@ -277,7 +265,7 @@
return (rv < -1) ? -1 : 0;
}
-#endif
+
char *ap_get_service_key(char *display_name)
{
size_t keylen = strlen(display_name);
@@ -290,21 +278,7 @@
return(key);
}
-#if 0
-int ap_registry_get_service_conf(ap_pool_t *p, char *dir, int size, char *display_name)
-{
- int rv;
- char *key = ap_get_service_key(display_name);
-
- rv = ap_registry_get_key_int(p, key, "ConfPath", dir, size, NULL);
- if (rv < 0) {
- dir[0] = '\0';
- }
- free(key);
- return (rv < -1) ? -1 : 0;
-}
-#else
int ap_registry_get_service_conf(ap_pool_t *p, char **buf, char *service_name)
{
int rv;
@@ -318,7 +292,6 @@
free(key);
return (rv < -1) ? -1 : 0;
}
-#endif
/**********************************************************************
* The rest of this file deals with storing keys or values in the registry
@@ -552,4 +525,3 @@
return rv < 0 ? -1 : 0;
}
-
1.11 +139 -55 apache-2.0/src/os/win32/service.c
Index: service.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/os/win32/service.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- service.c 2000/05/17 00:35:21 1.10
+++ service.c 2000/05/19 05:01:49 1.11
@@ -58,21 +58,20 @@
#ifdef WIN32
-#include "os.h"
-#include <stdlib.h>
-#include <direct.h>
-
#define CORE_PRIVATE
+
+#include "main_win32.h"
#include "httpd.h"
#include "http_conf_globals.h"
#include "http_log.h"
-#include "http_main.h"
#include "service.h"
#include "registry.h"
#include "ap_mpm.h"
+#include "..\..\modules\mpm\winnt\winnt.h"
typedef void (CALLBACK *ap_completion_t)();
API_VAR_IMPORT ap_completion_t ap_mpm_init_complete;
+API_VAR_IMPORT char *ap_server_argv0;
static struct
{
@@ -85,6 +84,8 @@
SERVICE_STATUS ssStatus;
FILE *logFile;
char *service_dir;
+ HANDLE threadService;
+ HANDLE threadMonitor;
} globdat;
static void WINAPI service_main_fn(DWORD, LPTSTR *);
@@ -93,54 +94,137 @@
static int ap_start_service(SC_HANDLE);
static int ap_stop_service(SC_HANDLE);
-static void CALLBACK report_service95_running()
+static LRESULT CALLBACK MonitorWin9xWndProc(HWND hWnd, UINT msg,
+ WPARAM wParam, LPARAM lParam)
{
- FreeConsole();
+/* This is the WndProc procedure for our invisible window.
+ * When the user shuts down the system, this window is sent
+ * a signal WM_ENDSESSION. We clean up by signaling Apache
+ * to shut down, and idle until Apache's primary thread quits.
+ */
+ if ((msg == WM_ENDSESSION) && (lParam != ENDSESSION_LOGOFF))
+ {
+ ap_start_shutdown();
+ if (wParam)
+ WaitForSingleObject(globdat.threadService, 30000);
+ return 0;
+ }
+ return (DefWindowProc(hWnd, msg, wParam, lParam));
+}
- /* We do this only once, ever */
- ap_mpm_init_complete = NULL;
+static DWORD WINAPI MonitorWin9xEvents(LPVOID initEvent)
+{
+/* When running on Windows 9x, the ConsoleCtrlHandler is _NOT_
+ * called when the system is shutdown. So create an invisible
+ * window to watch for the WM_ENDSESSION message, and watch for
+ * the WM_CLOSE message to shut the window down.
+ */
+ WNDCLASS wc;
+ HWND hwndMain;
+
+ wc.style = CS_GLOBALCLASS;
+ wc.lpfnWndProc = MonitorWin9xWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = NULL;
+ wc.hIcon = NULL;
+ wc.hCursor = NULL;
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = "ApacheWin9xService";
+
+ if (RegisterClass(&wc))
+ {
+ /* Create an invisible window */
+ hwndMain = CreateWindow("ApacheWin9xService", "Apache",
+ WS_OVERLAPPEDWINDOW & ~WS_VISIBLE,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ NULL, NULL, NULL, NULL);
+ if (hwndMain)
+ {
+ MSG msg;
+ /* If we succeed, eliminate the console window.
+ * Signal the parent we are all set up, and
+ * watch the message queue while the window lives.
+ */
+ FreeConsole();
+ SetEvent((HANDLE) initEvent);
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ if (msg.message == WM_CLOSE)
+ DestroyWindow(hwndMain);
+ else {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ globdat.threadMonitor = 0;
+ return(0);
+ }
+ }
+ /* We failed or are soon to die...
+ * we won't need this much longer
+ */
+ SetEvent((HANDLE) initEvent);
+ globdat.threadMonitor = 0;
+ return(0);
}
-int service95_main(int (*main_fn)(int, char **), int argc, char **argv )
+static void CALLBACK report_service9x_running()
{
- HINSTANCE hkernel;
+}
+
+int service9x_main(int (*main_fn)(int, char **), int argc, char **argv )
+{
DWORD (WINAPI *RegisterServiceProcess)(DWORD, DWORD);
+ HINSTANCE hkernel;
+ DWORD threadId;
+
+ globdat.threadService = GetCurrentThread();
/* 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;
+ if (hkernel) {
+ /* Find the RegisterServiceProcess function */
+ RegisterServiceProcess = (DWORD (WINAPI *)(DWORD, DWORD))
+ GetProcAddress(hkernel, "RegisterServiceProcess");
+ if (RegisterServiceProcess) {
+ if (RegisterServiceProcess((DWORD)NULL, 1)) {
+ HANDLE installed = CreateEvent(NULL, FALSE, FALSE, NULL);
+ globdat.threadMonitor = CreateThread(NULL, 0,
+ MonitorWin9xEvents,
+ (LPVOID) installed,
+ 0, &threadId);
+ WaitForSingleObject(installed, 30000);
+ CloseHandle(installed);
+ }
+ }
+ }
/* Run the service */
globdat.exit_status = main_fn(argc, argv);
+ /* Still have a thread & window to clean up, so signal now */
+ if (globdat.threadMonitor)
+ {
+ PostThreadMessage(threadId, WM_CLOSE, 0, 0);
+ WaitForSingleObject(globdat.threadMonitor, 30000);
+ }
+
/* When the service quits, remove it from the
system service table */
- RegisterServiceProcess((DWORD)NULL, 0);
+ if (RegisterServiceProcess)
+ RegisterServiceProcess((DWORD)NULL, 0);
/* Free the kernel library */
- // Worthless, methinks, since it won't be reclaimed
- // FreeLibrary(hkernel);
+ if (hkernel)
+ 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 )
+int servicent_main(int (*main_fn)(int, char **), int argc, char **argv )
{
SERVICE_TABLE_ENTRY dispatchTable[] =
{
@@ -166,24 +250,12 @@
}
}
-void service_cd()
+static void CALLBACK report_servicent_started()
{
- /* change to the drive with the executable */
- char buf[300];
- GetModuleFileName(NULL, buf, 300);
- buf[2] = 0;
- 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)
@@ -217,10 +289,8 @@
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000); // wait hint
-
- ap_mpm_init_complete = report_service_started;
- service_cd();
+ ap_mpm_init_complete = report_servicent_started;
/* Fetch server_conf from the registry
* Rebuild argv and argc adding the -d server_root and -f server_conf then
@@ -274,7 +344,6 @@
{
int state;
-
state = globdat.ssStatus.dwCurrentState;
switch(dwCtrlCode)
{
@@ -342,7 +411,7 @@
return(1);
}
-void InstallService(char *display_name, char *conf)
+void InstallServiceNT(char *display_name, char *conf)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
@@ -415,7 +484,7 @@
}
-void RemoveService(char *display_name)
+void RemoveServiceNT(char *display_name)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
@@ -473,16 +542,27 @@
}
/* Determine is service_name is a valid service
+ * Simplify by testing the registry rather than the SCM
+ * as this will work on both WinNT and Win9x.
*/
-BOOL isValidService(char *display_name) {
- SC_HANDLE schSCM, schSVC;
+BOOL isValidService(ap_pool_t *p, char *display_name) {
char service_name[256];
- int Err;
+ char *service_conf;
/* Remove spaces from display name to create service name */
ap_collapse_spaces(service_name, display_name);
+ if(ap_registry_get_service_conf(p, &service_conf, service_name)) {
+ return TRUE;
+ }
+
+ return FALSE;
+
+#if 0
+ SC_HANDLE schSCM, schSVC;
+ int Err;
+
if (!(schSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) {
ap_log_error(APLOG_MARK, APLOG_ERR, GetLastError(), NULL,
"OpenSCManager failed");
@@ -501,8 +581,12 @@
"OpenService failed");
return FALSE;
+#endif
}
+/* Although the Win9x service enhancement added -k startservice,
+ * it is never processed here, so we still ignore that param.
+ */
int send_signal_to_service(char *display_name, char *sig) {
SC_HANDLE schService;
SC_HANDLE schSCManager;
@@ -607,6 +691,6 @@
return TRUE;
return FALSE;
}
-
+
#endif /* WIN32 */
1.5 +11 -8 apache-2.0/src/os/win32/service.h
Index: service.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/os/win32/service.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- service.h 2000/05/17 00:35:21 1.4
+++ service.h 2000/05/19 05:01:50 1.5
@@ -60,16 +60,19 @@
#define SERVICE_H
#ifdef WIN32
-int service_main(int (*main_fn)(int, char **), int argc, char **argv);
-int service95_main(int (*main_fn)(int, char **), int argc, char **argv);
-void service_set_status(int status);
-void service_cd();
BOOL isProcessService();
-BOOL isValidService(char *display_name);
-void InstallService(char *display_name, char *conf);
-void RemoveService(char *display_name);
-int service_init();
+BOOL isValidService(ap_pool_t *p, char *display_name);
int send_signal_to_service(char *display_name, char *sig);
+
+int service9x_main(int (*main_fn)(int, char **), int argc, char **argv);
+
+int servicent_main(int (*main_fn)(int, char **), int argc, char **argv);
+void InstallServiceNT(char *display_name, char *conf);
+void RemoveServiceNT(char *display_name);
+
+//void service_set_status(int status);
+//void service_cd();
+//int service_init();
#endif /* WIN32 */
#endif /* SERVICE_H */
1.1 apache-2.0/src/os/win32/main_win32.h
Index: main_win32.h
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* Portions of this software are based upon public domain software
* originally written at the National Center for Supercomputing Applications,
* University of Illinois, Urbana-Champaign.
*/
/*
* Declarations for users of the functions defined in registry.c
*/
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#ifndef NOGDI
#define NOGDI
#endif
#ifndef NONLS
#define NONLS
#endif
#ifndef NOMCX
#define NOMCX
#endif
#ifndef NOIME
#define NOIME
#endif
#include <windows.h>
#include <winsock2.h>
#include <mswsock.h>
1.12 +1 -0 apache-2.0/src/include/ap_listen.h
Index: ap_listen.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/include/ap_listen.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- ap_listen.h 2000/03/31 07:18:52 1.11
+++ ap_listen.h 2000/05/19 05:01:52 1.12
@@ -56,6 +56,7 @@
#define AP_LISTEN_H
#include "apr_network_io.h"
+#include "http_config.h"
typedef struct ap_listen_rec ap_listen_rec;
struct ap_listen_rec {
1.7 +4 -0 apache-2.0/src/include/http_main.h
Index: http_main.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/include/http_main.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- http_main.h 2000/03/31 07:18:59 1.6
+++ http_main.h 2000/05/19 05:01:52 1.7
@@ -71,6 +71,10 @@
extern ap_array_header_t *ap_server_post_read_config;
extern ap_array_header_t *ap_server_config_defines;
+#ifdef WIN32
+API_EXPORT(int) apache_main(int argc, char *argv[]);
+#endif
+
#ifdef __cplusplus
}
#endif
1.11 +0 -1 apache-2.0/src/lib/apr/include/apr.hw
Index: apr.hw
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr.hw,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- apr.hw 2000/05/18 02:17:22 1.10
+++ apr.hw 2000/05/19 05:01:52 1.11
@@ -91,7 +91,6 @@
#define NOIME
#endif
#include <windows.h>
-#include <windows.h>
/*
* Add a _very_few_ declarations missing from the restricted set of headers
* (If this list becomes extensive, re-enable the required headers above!)
1.29 +3 -1 apache-2.0/src/lib/apr/threadproc/win32/proc.c
Index: proc.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/threadproc/win32/proc.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- proc.c 2000/05/01 03:24:35 1.28
+++ proc.c 2000/05/19 05:01:52 1.29
@@ -340,7 +340,9 @@
pNext = pNext + strlen(pNext) + 1;
i++;
}
- strcpy(pNext, envstr);
+ strcpy(pNext, envstr);
+ pNext = pNext + strlen(pNext) + 1;
+ *pNext = '\0';
}
else {
SetEnvironmentVariable("parentpid", ppid);
1.67 +43 -13 apache-2.0/src/modules/mpm/winnt/winnt.c
Index: winnt.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/mpm/winnt/winnt.c,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -r1.66 -r1.67
--- winnt.c 2000/05/17 00:35:19 1.66
+++ winnt.c 2000/05/19 05:01:53 1.67
@@ -68,11 +68,9 @@
#include "ap_config.h"
#include "ap_listen.h"
#include "mpm_default.h"
-//#include "service.h"
#include "iol_socket.h"
#include "winnt.h"
-
/*
* Definitions of WINNT MPM specific config globals
*/
@@ -105,9 +103,8 @@
static event *exit_event;
HANDLE maintenance_event;
ap_lock_t *start_mutex;
-int my_pid;
-int parent_pid;
-typedef void (CALLBACK *ap_completion_t)();
+DWORD my_pid;
+DWORD parent_pid;
API_VAR_EXPORT ap_completion_t ap_mpm_init_complete = NULL;
static ap_status_t socket_cleanup(void *sock)
@@ -299,15 +296,19 @@
}
CloseHandle(e);
}
+
static int volatile is_graceful = 0;
+
API_EXPORT(int) ap_graceful_stop_signalled(void)
{
return is_graceful;
}
-void ap_start_shutdown(void)
+
+API_EXPORT(void) ap_start_shutdown(void)
{
signal_parent(0);
}
+
/*
* Initialise the signal names, in the global variables signal_name_prefix,
* signal_restart_name and signal_shutdown_name.
@@ -354,6 +355,7 @@
* Routines to deal with managing the list of listening sockets.
*/
static ap_listen_rec *head_listener;
+
static ap_inline ap_listen_rec *find_ready_listener(fd_set * main_fds)
{
ap_listen_rec *lr;
@@ -371,6 +373,7 @@
}
return NULL;
}
+
static int setup_listeners(server_rec *s)
{
ap_listen_rec *lr;
@@ -1390,7 +1393,10 @@
int rv;
char buf[1024];
char *pCommand;
+ char *pEnvVar;
+ char *pEnvBlock;
int i;
+ int iEnvBlockLen;
STARTUPINFO si; /* Filled in prior to call to CreateProcess */
PROCESS_INFORMATION pi; /* filled in on call to CreateProces */
@@ -1425,6 +1431,32 @@
pCommand = ap_pstrcat(p, pCommand, " \"", server_conf->process->argv[i], "\"", NULL);
}
+ /* Build the environment, since Win9x disrespects the active env */
+ // SetEnvironmentVariable("AP_PARENT_PID",ap_psprintf(p,"%l",parent_pid));
+ pEnvVar = ap_psprintf(p, "AP_PARENT_PID=%i", parent_pid);
+ /*
+ * Win32's CreateProcess call requires that the environment
+ * be passed in an environment block, a null terminated block of
+ * null terminated strings.
+ */
+ i = 0;
+ iEnvBlockLen = 1;
+ while (_environ[i]) {
+ iEnvBlockLen += strlen(_environ[i]) + 1;
+ i++;
+ }
+
+ pEnvBlock = (char *)ap_pcalloc(p, iEnvBlockLen + strlen(pEnvVar) + 1);
+ strcpy(pEnvBlock, pEnvVar);
+ pEnvVar = strchr(pEnvBlock, '\0') + 1;
+
+ i = 0;
+ while (_environ[i]) {
+ strcpy(pEnvVar, _environ[i]);
+ pEnvVar = strchr(pEnvVar, '\0') + 1;
+ i++;
+ }
+ pEnvVar = '\0';
/* Create a pipe to send socket info to the child */
if (!CreatePipe(&hPipeRead, &hPipeWrite, &sa, 0)) {
ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
@@ -1432,8 +1464,6 @@
return -1;
}
- SetEnvironmentVariable("AP_PARENT_PID",ap_psprintf(p,"%d",parent_pid));
-
/* Give the read end of the pipe (hPipeRead) to the child as stdin. The
* parent will write the socket data to the child on this pipe.
*/
@@ -1447,7 +1477,7 @@
if (!CreateProcess(NULL, pCommand, NULL, NULL,
TRUE, /* Inherit handles */
CREATE_SUSPENDED, /* Creation flags */
- NULL, /* Environment block */
+ pEnvBlock, /* Environment block */
NULL,
&si, &pi)) {
ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
@@ -1694,12 +1724,12 @@
pid = getenv("AP_PARENT_PID");
if (pid) {
/* This is the child */
- parent_pid = atoi(pid);
- my_pid = getpid();
+ parent_pid = (DWORD) atol(pid);
+ my_pid = GetCurrentProcessId();
}
else {
/* This is the parent */
- parent_pid = my_pid = getpid();
+ parent_pid = my_pid = GetCurrentProcessId();
}
ap_listen_pre_config();
@@ -1806,7 +1836,7 @@
if (pidfile != NULL && unlink(pidfile) == 0) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO,APR_SUCCESS,
server_conf, "removed PID file %s (pid=%ld)",
- pidfile, (long)getpid());
+ pidfile, GetCurrentProcessId());
}
ap_destroy_lock(start_mutex);
1.11 +6 -0 apache-2.0/src/modules/mpm/winnt/winnt.h
Index: winnt.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/mpm/winnt/winnt.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- winnt.h 2000/04/14 15:59:04 1.10
+++ winnt.h 2000/05/19 05:01:53 1.11
@@ -59,11 +59,17 @@
#ifndef APACHE_MPM_WINNT_H
#define APACHE_MPM_WINNT_H
+#include "ap_listen.h"
+
extern int ap_threads_per_child;
extern int ap_max_requests_per_child;
extern int ap_extended_status;
extern void clean_child_exit(int);
+typedef void (CALLBACK *ap_completion_t)();
+API_VAR_IMPORT ap_completion_t ap_mpm_init_complete;
+
+API_EXPORT(void) ap_start_shutdown(void);
typedef struct CompContext {
OVERLAPPED Overlapped;