From 4d82cc0c15bd43f70375eec295e9f08e092bc9ed Mon Sep 17 00:00:00 2001
From: davidely <davidely@localhost>
Date: Mon, 07 May 2007 16:33:57 +0000
Subject: [PATCH] Updating Windows service related code and executables. This fixes a problem with stopping the server on Windows, and also adds a lot of debug logging to the service code, so we can track problems down in the future
---
opendj-sdk/opends/src/build-tools/windows/common.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 191 insertions(+), 11 deletions(-)
diff --git a/opendj-sdk/opends/src/build-tools/windows/common.c b/opendj-sdk/opends/src/build-tools/windows/common.c
index 0868745..b8e598b 100644
--- a/opendj-sdk/opends/src/build-tools/windows/common.c
+++ b/opendj-sdk/opends/src/build-tools/windows/common.c
@@ -26,6 +26,19 @@
*/
#include "common.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <io.h>
+#include <stdio.h>
+#include <sys/locking.h>
+#include <time.h>
+
+BOOL DEBUG = TRUE;
+char * DEBUG_LOG_NAME = "native-windows.out";
+DWORD MAX_DEBUG_LOG_SIZE = 500 * 1000;
+char * getDebugLogFileName();
+void debugInner(BOOL isError, const char *msg, va_list ap);
+void deleteIfLargerThan(char * fileName, DWORD maxSize);
// ----------------------------------------------------
// Function used to create a process with the given command.
@@ -40,6 +53,8 @@
STARTUPINFO startInfo; // info to pass to the new process
DWORD processFlag; // background process flag
+ debug("Attempting to child process '%s' background=%d.", command, background);
+
// reset process info first
ZeroMemory(procInfo, sizeof(PROCESS_INFORMATION));
@@ -51,18 +66,27 @@
// Create the child process
processFlag = background == TRUE ? DETACHED_PROCESS : 0;
createOk = CreateProcess(
- NULL, // application name
- command, // command line
- NULL, // process security attributes
- NULL, // primary thread security attributes
- TRUE, // handles are inherited
- processFlag, // creation flags
- NULL, // use parent's environment
- NULL, // use parent's current directory
- &startInfo, // STARTUPINFO pointer
- procInfo // receives PROCESS_INFORMATION
+ NULL, // application name
+ command, // command line
+ NULL, // process security attributes
+ NULL, // primary thread security attributes
+ TRUE, // handles are inherited
+ processFlag, // creation flags
+ NULL, // use parent's environment
+ NULL, // use parent's current directory
+ &startInfo, // STARTUPINFO pointer
+ procInfo // receives PROCESS_INFORMATION
);
+ if (createOk)
+ {
+ debug("Successfully created child process '%s'.", command);
+ }
+ else
+ {
+ debugError("Failed to create child process '%s'. Last error = %d.", command, GetLastError());
+ }
+
return createOk;
} // createChildProcess
@@ -73,7 +97,7 @@
// ----------------------------------------------------
int spawn(const char* command, BOOL background)
{
- DWORD childPid; // child's pid
+ DWORD childPid = -1; // child's pid
PROCESS_INFORMATION procInfo; // info on the new process
BOOL createOk;
@@ -86,11 +110,167 @@
if (childPid != -1)
{
+ debug("The PID of the spawned process is %d.", childPid);
return childPid;
}
else
{
+ debugError("Could not get the PID of the spawned process.");
return -1;
}
} // spawn
+
+// ---------------------------------------------------
+// Debug utility.
+// ---------------------------------------------------
+void debug(const char *msg, ...)
+{
+ va_list ap;
+ va_start (ap, msg);
+ debugInner(FALSE, msg, ap);
+ va_end (ap);
+}
+
+void debugError(const char *msg, ...)
+{
+ va_list ap;
+ va_start (ap, msg);
+ debugInner(TRUE, msg, ap);
+ va_end (ap);
+}
+
+void debugInner(BOOL isError, const char *msg, va_list ap)
+{
+ static DWORD currentProcessPid = 0;
+ static BOOL noMessageLogged = TRUE;
+
+ // The file containing the log.
+ char * logFile;
+ FILE *fp;
+ time_t rawtime;
+ struct tm * timeinfo;
+ char formattedTime[100];
+
+ if (noMessageLogged)
+ {
+ currentProcessPid = GetCurrentProcessId();
+ noMessageLogged = FALSE;
+ debug("--------------- FIRST LOG MESSAGE FROM '%s' ---------------", _pgmptr);
+ }
+
+ // Time-stamp
+ time(&rawtime);
+ timeinfo = localtime(&rawtime);
+ strftime(formattedTime, 100, "%Y/%m/%d %H:%M:%S", timeinfo);
+
+ logFile = getDebugLogFileName();
+ deleteIfLargerThan(logFile, MAX_DEBUG_LOG_SIZE);
+ if ((fp = fopen(logFile, "a")) != NULL)
+ {
+ fprintf(fp, "%s: (pid=%d) ", formattedTime, currentProcessPid);
+ if (isError)
+ {
+ fprintf(fp, "ERROR: ");
+ // It would be nice to echo to stderr, but that doesn't appear to work.
+ }
+
+ vfprintf(fp, msg, ap);
+
+ fprintf(fp, "\n");
+ fclose(fp);
+ }
+ else
+ {
+ fprintf(stdout, "Could not create log file.\n");
+ }
+}
+
+// ---------------------------------------------------------------
+// Get the fully-qualified debug log file name. The logic in this
+// method assumes that the executable of this process is in a
+// direct subdirectory of the instance root.
+// ---------------------------------------------------------------
+
+char * getDebugLogFileName()
+{
+ static char * logFile = NULL;
+ char path [MAX_PATH];
+ char execName [MAX_PATH];
+ char * lastSlash;
+
+ if (logFile != NULL)
+ {
+ return logFile;
+ }
+
+ // Get the name of the executable.
+ GetModuleFileName (
+ NULL,
+ execName,
+ MAX_PATH
+ );
+
+ // Cut everything after the last slash, twice. This will take us back to the instance root.
+ // This logic assumes that we are in a directory above the instance root.
+ lastSlash = strrchr(execName, '\\');
+ lastSlash[0] = '\0';
+ lastSlash = strrchr(execName, '\\');
+ lastSlash[0] = '\0';
+
+ sprintf(path, "%s\\logs\\%s", execName, DEBUG_LOG_NAME);
+ logFile = _strdup(path);
+
+ return logFile;
+}
+
+// ---------------------------------------------------------------
+// Function called to know if the --debug option was passed
+// when calling this executable or not. The DEBUG variable is
+// updated accordingly.
+// ---------------------------------------------------------------
+
+void updateDebugFlag(char* argv[], int argc)
+{
+ int i;
+ DEBUG = FALSE;
+ for (i=1; (i<argc) && !DEBUG; i++)
+ {
+ if (strcmp(argv[i], "--debug") == 0)
+ {
+ DEBUG = TRUE;
+ }
+ }
+}
+
+// ---------------------------------------------------------------
+// Deletes a file if it's larger than the given maximum size.
+// ---------------------------------------------------------------
+
+void deleteIfLargerThan(char * fileName, DWORD maxSize)
+{
+ DWORD fileSize = 0;
+ HANDLE fileHandle = CreateFile(
+ fileName,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL
+ );
+
+ if (fileHandle == INVALID_HANDLE_VALUE)
+ {
+ return;
+ }
+
+ fileSize = GetFileSize(fileHandle, NULL);
+
+ CloseHandle(fileHandle);
+
+ if (fileSize > maxSize)
+ {
+ DeleteFile(fileName);
+ }
+}
--
Gitblit v1.10.0