Skip to content

Commit 9199480

Browse files
committed
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. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@85253 13f79535-47bb-0310-9956-ffa450edef68
1 parent 96fb11c commit 9199480

7 files changed

Lines changed: 275 additions & 98 deletions

File tree

include/ap_listen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#define AP_LISTEN_H
5757

5858
#include "apr_network_io.h"
59+
#include "http_config.h"
5960

6061
typedef struct ap_listen_rec ap_listen_rec;
6162
struct ap_listen_rec {

include/http_main.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ extern ap_array_header_t *ap_server_pre_read_config;
7171
extern ap_array_header_t *ap_server_post_read_config;
7272
extern ap_array_header_t *ap_server_config_defines;
7373

74+
#ifdef WIN32
75+
API_EXPORT(int) apache_main(int argc, char *argv[]);
76+
#endif
77+
7478
#ifdef __cplusplus
7579
}
7680
#endif

os/win32/main_win32.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/* ====================================================================
2+
* The Apache Software License, Version 1.1
3+
*
4+
* Copyright (c) 2000 The Apache Software Foundation. All rights
5+
* reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions
9+
* are met:
10+
*
11+
* 1. Redistributions of source code must retain the above copyright
12+
* notice, this list of conditions and the following disclaimer.
13+
*
14+
* 2. Redistributions in binary form must reproduce the above copyright
15+
* notice, this list of conditions and the following disclaimer in
16+
* the documentation and/or other materials provided with the
17+
* distribution.
18+
*
19+
* 3. The end-user documentation included with the redistribution,
20+
* if any, must include the following acknowledgment:
21+
* "This product includes software developed by the
22+
* Apache Software Foundation (http://www.apache.org/)."
23+
* Alternately, this acknowledgment may appear in the software itself,
24+
* if and wherever such third-party acknowledgments normally appear.
25+
*
26+
* 4. The names "Apache" and "Apache Software Foundation" must
27+
* not be used to endorse or promote products derived from this
28+
* software without prior written permission. For written
29+
* permission, please contact apache@apache.org.
30+
*
31+
* 5. Products derived from this software may not be called "Apache",
32+
* nor may "Apache" appear in their name, without prior written
33+
* permission of the Apache Software Foundation.
34+
*
35+
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38+
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39+
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42+
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45+
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46+
* SUCH DAMAGE.
47+
* ====================================================================
48+
*
49+
* This software consists of voluntary contributions made by many
50+
* individuals on behalf of the Apache Software Foundation. For more
51+
* information on the Apache Software Foundation, please see
52+
* <http://www.apache.org/>.
53+
*
54+
* Portions of this software are based upon public domain software
55+
* originally written at the National Center for Supercomputing Applications,
56+
* University of Illinois, Urbana-Champaign.
57+
*/
58+
59+
/*
60+
* Declarations for users of the functions defined in registry.c
61+
*/
62+
63+
#ifndef _WIN32_WINNT
64+
#define _WIN32_WINNT 0x0400
65+
#endif
66+
#ifndef NOGDI
67+
#define NOGDI
68+
#endif
69+
#ifndef NONLS
70+
#define NONLS
71+
#endif
72+
#ifndef NOMCX
73+
#define NOMCX
74+
#endif
75+
#ifndef NOIME
76+
#define NOIME
77+
#endif
78+
#include <windows.h>
79+
#include <winsock2.h>
80+
#include <mswsock.h>

server/mpm/winnt/mpm_winnt.c

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,9 @@
6868
#include "ap_config.h"
6969
#include "ap_listen.h"
7070
#include "mpm_default.h"
71-
//#include "service.h"
7271
#include "iol_socket.h"
7372
#include "winnt.h"
7473

75-
7674
/*
7775
* Definitions of WINNT MPM specific config globals
7876
*/
@@ -105,9 +103,8 @@ int ap_daemons_to_start=0;
105103
static event *exit_event;
106104
HANDLE maintenance_event;
107105
ap_lock_t *start_mutex;
108-
int my_pid;
109-
int parent_pid;
110-
typedef void (CALLBACK *ap_completion_t)();
106+
DWORD my_pid;
107+
DWORD parent_pid;
111108
API_VAR_EXPORT ap_completion_t ap_mpm_init_complete = NULL;
112109

113110
static ap_status_t socket_cleanup(void *sock)
@@ -299,15 +296,19 @@ static void signal_parent(int type)
299296
}
300297
CloseHandle(e);
301298
}
299+
302300
static int volatile is_graceful = 0;
301+
303302
API_EXPORT(int) ap_graceful_stop_signalled(void)
304303
{
305304
return is_graceful;
306305
}
307-
void ap_start_shutdown(void)
306+
307+
API_EXPORT(void) ap_start_shutdown(void)
308308
{
309309
signal_parent(0);
310310
}
311+
311312
/*
312313
* Initialise the signal names, in the global variables signal_name_prefix,
313314
* signal_restart_name and signal_shutdown_name.
@@ -354,6 +355,7 @@ static void sock_disable_nagle(int s)
354355
* Routines to deal with managing the list of listening sockets.
355356
*/
356357
static ap_listen_rec *head_listener;
358+
357359
static ap_inline ap_listen_rec *find_ready_listener(fd_set * main_fds)
358360
{
359361
ap_listen_rec *lr;
@@ -371,6 +373,7 @@ static ap_inline ap_listen_rec *find_ready_listener(fd_set * main_fds)
371373
}
372374
return NULL;
373375
}
376+
374377
static int setup_listeners(server_rec *s)
375378
{
376379
ap_listen_rec *lr;
@@ -1390,7 +1393,10 @@ static int create_process(ap_pool_t *p, HANDLE *handles, HANDLE *events, int *pr
13901393
int rv;
13911394
char buf[1024];
13921395
char *pCommand;
1396+
char *pEnvVar;
1397+
char *pEnvBlock;
13931398
int i;
1399+
int iEnvBlockLen;
13941400
STARTUPINFO si; /* Filled in prior to call to CreateProcess */
13951401
PROCESS_INFORMATION pi; /* filled in on call to CreateProces */
13961402

@@ -1425,15 +1431,39 @@ static int create_process(ap_pool_t *p, HANDLE *handles, HANDLE *events, int *pr
14251431
pCommand = ap_pstrcat(p, pCommand, " \"", server_conf->process->argv[i], "\"", NULL);
14261432
}
14271433

1434+
/* Build the environment, since Win9x disrespects the active env */
1435+
// SetEnvironmentVariable("AP_PARENT_PID",ap_psprintf(p,"%l",parent_pid));
1436+
pEnvVar = ap_psprintf(p, "AP_PARENT_PID=%i", parent_pid);
1437+
/*
1438+
* Win32's CreateProcess call requires that the environment
1439+
* be passed in an environment block, a null terminated block of
1440+
* null terminated strings.
1441+
*/
1442+
i = 0;
1443+
iEnvBlockLen = 1;
1444+
while (_environ[i]) {
1445+
iEnvBlockLen += strlen(_environ[i]) + 1;
1446+
i++;
1447+
}
1448+
1449+
pEnvBlock = (char *)ap_pcalloc(p, iEnvBlockLen + strlen(pEnvVar) + 1);
1450+
strcpy(pEnvBlock, pEnvVar);
1451+
pEnvVar = strchr(pEnvBlock, '\0') + 1;
1452+
1453+
i = 0;
1454+
while (_environ[i]) {
1455+
strcpy(pEnvVar, _environ[i]);
1456+
pEnvVar = strchr(pEnvVar, '\0') + 1;
1457+
i++;
1458+
}
1459+
pEnvVar = '\0';
14281460
/* Create a pipe to send socket info to the child */
14291461
if (!CreatePipe(&hPipeRead, &hPipeWrite, &sa, 0)) {
14301462
ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
14311463
"Parent: Unable to create pipe to child process.\n");
14321464
return -1;
14331465
}
14341466

1435-
SetEnvironmentVariable("AP_PARENT_PID",ap_psprintf(p,"%d",parent_pid));
1436-
14371467
/* Give the read end of the pipe (hPipeRead) to the child as stdin. The
14381468
* parent will write the socket data to the child on this pipe.
14391469
*/
@@ -1447,7 +1477,7 @@ static int create_process(ap_pool_t *p, HANDLE *handles, HANDLE *events, int *pr
14471477
if (!CreateProcess(NULL, pCommand, NULL, NULL,
14481478
TRUE, /* Inherit handles */
14491479
CREATE_SUSPENDED, /* Creation flags */
1450-
NULL, /* Environment block */
1480+
pEnvBlock, /* Environment block */
14511481
NULL,
14521482
&si, &pi)) {
14531483
ap_log_error(APLOG_MARK, APLOG_CRIT, GetLastError(), server_conf,
@@ -1694,12 +1724,12 @@ static void winnt_pre_config(ap_pool_t *pconf, ap_pool_t *plog, ap_pool_t *ptemp
16941724
pid = getenv("AP_PARENT_PID");
16951725
if (pid) {
16961726
/* This is the child */
1697-
parent_pid = atoi(pid);
1698-
my_pid = getpid();
1727+
parent_pid = (DWORD) atol(pid);
1728+
my_pid = GetCurrentProcessId();
16991729
}
17001730
else {
17011731
/* This is the parent */
1702-
parent_pid = my_pid = getpid();
1732+
parent_pid = my_pid = GetCurrentProcessId();
17031733
}
17041734

17051735
ap_listen_pre_config();
@@ -1806,7 +1836,7 @@ API_EXPORT(int) ap_mpm_run(ap_pool_t *_pconf, ap_pool_t *plog, server_rec *s )
18061836
if (pidfile != NULL && unlink(pidfile) == 0) {
18071837
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO,APR_SUCCESS,
18081838
server_conf, "removed PID file %s (pid=%ld)",
1809-
pidfile, (long)getpid());
1839+
pidfile, GetCurrentProcessId());
18101840
}
18111841
ap_destroy_lock(start_mutex);
18121842

server/mpm/winnt/mpm_winnt.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,17 @@
5959
#ifndef APACHE_MPM_WINNT_H
6060
#define APACHE_MPM_WINNT_H
6161

62+
#include "ap_listen.h"
63+
6264
extern int ap_threads_per_child;
6365
extern int ap_max_requests_per_child;
6466
extern int ap_extended_status;
6567
extern void clean_child_exit(int);
6668

69+
typedef void (CALLBACK *ap_completion_t)();
70+
API_VAR_IMPORT ap_completion_t ap_mpm_init_complete;
71+
72+
API_EXPORT(void) ap_start_shutdown(void);
6773

6874
typedef struct CompContext {
6975
OVERLAPPED Overlapped;

server/mpm/winnt/registry.c

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
#define SERVICEKEYPRE "System\\CurrentControlSet\\Services\\"
102102
#define SERVICEKEYPOST "\\Parameters"
103103

104+
#define SERVICELAUNCH9X "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices\\"
104105
/*
105106
* The Windows API registry key functions don't set the last error
106107
* value (the windows equivalent of errno). So we need to set it
@@ -253,19 +254,6 @@ static int ap_registry_get_key_int(ap_pool_t *p, char *key, char *name, char *pB
253254
* dir will contain an empty string), or -1 if there was
254255
* an error getting the key.
255256
*/
256-
#if 0
257-
int ap_registry_get_server_root(ap_pool_t *p, char *dir, int size)
258-
{
259-
int rv;
260-
261-
rv = ap_registry_get_key_int(p, REGKEY, "ServerRoot", dir, size, NULL);
262-
if (rv < 0) {
263-
dir[0] = '\0';
264-
}
265-
266-
return (rv < -1) ? -1 : 0;
267-
}
268-
#else
269257
int ap_registry_get_server_root(ap_pool_t *p, char **buf)
270258
{
271259
int rv;
@@ -277,7 +265,7 @@ int ap_registry_get_server_root(ap_pool_t *p, char **buf)
277265

278266
return (rv < -1) ? -1 : 0;
279267
}
280-
#endif
268+
281269
char *ap_get_service_key(char *display_name)
282270
{
283271
size_t keylen = strlen(display_name);
@@ -290,21 +278,7 @@ char *ap_get_service_key(char *display_name)
290278

291279
return(key);
292280
}
293-
#if 0
294-
int ap_registry_get_service_conf(ap_pool_t *p, char *dir, int size, char *display_name)
295-
{
296-
int rv;
297-
char *key = ap_get_service_key(display_name);
298-
299-
rv = ap_registry_get_key_int(p, key, "ConfPath", dir, size, NULL);
300-
if (rv < 0) {
301-
dir[0] = '\0';
302-
}
303281

304-
free(key);
305-
return (rv < -1) ? -1 : 0;
306-
}
307-
#else
308282
int ap_registry_get_service_conf(ap_pool_t *p, char **buf, char *service_name)
309283
{
310284
int rv;
@@ -318,7 +292,6 @@ int ap_registry_get_service_conf(ap_pool_t *p, char **buf, char *service_name)
318292
free(key);
319293
return (rv < -1) ? -1 : 0;
320294
}
321-
#endif
322295

323296
/**********************************************************************
324297
* The rest of this file deals with storing keys or values in the registry
@@ -552,4 +525,3 @@ int ap_registry_set_server_root(char *dir)
552525

553526
return rv < 0 ? -1 : 0;
554527
}
555-

0 commit comments

Comments
 (0)