I've noticed something very interesting in the Win32 code.
Services gain no stdin/out/err handles as the parent is launched.
I suspected this could be confusing perl56.dll when it tries to
clean up before stopping the service. That appears to _not_ be
the issue. But there is a bug report, 7198 [hope I don't transpose
the digits yet again :-] that indicates the system fails on dup2(stdin)
when the user tries to use rotatelogs. Now I've come up with the
following patch that introduces "NUL" handles for win32 stdin/stdout,
and the stderr is already set to a pipe that captures all 'pre-logging'
fprintf(stderr...) stuff into the event log.
Here's the code I'm suggesting we include in 1.3.19 that resolves the
spawning rotatelogs bug after I test on NT (it's already tested on Win2K):
Index: service.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/os/win32/service.c,v
retrieving revision 1.44
diff -u -r1.44 service.c
--- service.c 2001/02/21 00:36:38 1.44
+++ service.c 2001/02/24 21:00:13
@@ -547,6 +547,7 @@
HANDLE hCurrentProcess;
HANDLE hPipeRead = NULL;
HANDLE hPipeReadDup;
+ HANDLE hNullFile;
DWORD threadid;
SECURITY_ATTRIBUTES sa = {0};
char **newargv;
@@ -601,6 +602,46 @@
CloseHandle(eventlog_pipewrite);
eventlog_pipewrite = NULL;
}
+ }
+
+ /* Open a null handle to spoof our stdin */
+ hNullFile = CreateFile("nul", GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &sa, OPEN_EXISTING, 0, NULL);
+ if (hNullFile == INVALID_HANDLE_VALUE) {
+ ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, NULL,
+ "Parent: Unable to create null stdin pipe for this service
+process.\n");
+ }
+ else {
+ int fh;
+ FILE *fl;
+ fflush(stdin);
+ SetStdHandle(STD_INPUT_HANDLE, hNullFile);
+ fh = _open_osfhandle((long) STD_INPUT_HANDLE,
+ _O_WRONLY | _O_BINARY);
+ dup2(fh, STDIN_FILENO);
+ fl = _fdopen(STDIN_FILENO, "wcb");
+ memcpy(stdin, fl, sizeof(FILE));
+ }
+
+ /* Open a null handle to soak our stdout */
+ hNullFile = CreateFile("nul", GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &sa, OPEN_EXISTING, 0, NULL);
+ if (hNullFile == INVALID_HANDLE_VALUE) {
+ ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, NULL,
+ "Parent: Unable to create null stdout pipe for this service
+process.\n");
+ }
+ else {
+ int fh;
+ FILE *fl;
+ fflush(stdout);
+ SetStdHandle(STD_OUTPUT_HANDLE, hNullFile);
+ fh = _open_osfhandle((long) STD_OUTPUT_HANDLE,
+ _O_WRONLY | _O_BINARY);
+ dup2(fh, STDOUT_FILENO);
+ fl = _fdopen(STDOUT_FILENO, "wcb");
+ memcpy(stdout, fl, sizeof(FILE));
}
atexit(service_main_fn_terminate);