mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

davidely
07.33.2007 73cd90e4f9eb24891ad70f15ef6ede5f077c88aa
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
10 files modified
690 ■■■■ changed files
opends/lib/opends_service.exe patch | view | raw | blame | history
opends/lib/winlauncher.exe patch | view | raw | blame | history
opends/resource/bin/start-ds.bat 20 ●●●●● patch | view | raw | blame | history
opends/resource/bin/stop-ds.bat 22 ●●●●● patch | view | raw | blame | history
opends/src/build-tools/windows/common.c 202 ●●●●● patch | view | raw | blame | history
opends/src/build-tools/windows/common.h 6 ●●●●● patch | view | raw | blame | history
opends/src/build-tools/windows/service.c 321 ●●●● patch | view | raw | blame | history
opends/src/build-tools/windows/service.h 2 ●●● patch | view | raw | blame | history
opends/src/build-tools/windows/winlauncher.c 115 ●●●● patch | view | raw | blame | history
opends/src/build-tools/windows/winlauncher.h 2 ●●● patch | view | raw | blame | history
opends/lib/opends_service.exe
Binary files differ
opends/lib/winlauncher.exe
Binary files differ
opends/resource/bin/start-ds.bat
@@ -30,6 +30,11 @@
set DIR_HOME=%~dP0..
set INSTANCE_ROOT=%DIR_HOME%
set LOG=%INSTANCE_ROOT%\logs\native-windows.out
set SCRIPT=start-ds.bat
echo %SCRIPT%: invoked >> %LOG%
:checkJavaBin
if "%JAVA_BIN%" == "" goto noJavaBin
goto setClassPath
@@ -47,11 +52,13 @@
goto setClassPath
:noSetJavaHome
echo %SCRIPT%: JAVA_HOME environment variable is not set. >> %LOG%
echo Error: JAVA_HOME environment variable is not set.
echo        Please set it to a valid Java 5 (or later) installation.
goto end
:noValidJavaHome
echo %SCRIPT%: The detected Java version could notf be used. JAVA_HOME=[%JAVA_HOME%] >> %LOG%
echo ERROR:  The detected Java version could not be used.  Please set 
echo         JAVA_HOME to to a valid Java 5 (or later) installation.
goto end
@@ -59,8 +66,12 @@
:setClassPath
FOR %%x in ("%DIR_HOME%\lib\*.jar") DO call "%DIR_HOME%\lib\setcp.bat" %%x
echo %SCRIPT%: CLASSPATH=%CLASSPATH% >> %LOG%
set PATH=%SystemRoot%
echo %SCRIPT%: PATH=%PATH% >> %LOG%
set SCRIPT_NAME_ARG=-Dorg.opends.server.scriptName=start-ds
rem Test that the provided JDK is 1.5 compatible.
@@ -77,9 +88,11 @@
goto end
:serverAlreadyStarted
echo %SCRIPT%: Server already started  >> %LOG%
goto end
:runNoDetach
echo %SCRIPT%: Run no detach  >> %LOG%
if not exist "%DIR_HOME%\logs\server.out" echo. > "%DIR_HOME%\logs\server.out"
if not exist "%DIR_HOME%\logs\server.starting" echo. > "%DIR_HOME%\logs\server.starting"
"%JAVA_BIN%" %JAVA_ARGS% org.opends.server.core.DirectoryServer --configClass org.opends.server.extensions.ConfigFileHandler --configFile "%DIR_HOME%\config\config.ldif" %*
@@ -87,28 +100,35 @@
:runDetach
echo %SCRIPT%: Run detach  >> %LOG%
if not exist "%DIR_HOME%\logs\server.out" echo. > "%DIR_HOME%\logs\server.out"
if not exist "%DIR_HOME%\logs\server.starting" echo. > "%DIR_HOME%\logs\server.starting"
"%DIR_HOME%\lib\winlauncher.exe" start "%DIR_HOME%" "%JAVA_BIN%" %JAVA_ARGS%  org.opends.server.core.DirectoryServer --configClass org.opends.server.extensions.ConfigFileHandler --configFile "%DIR_HOME%\config\config.ldif" %*
echo %SCRIPT%: Waiting for "%DIR_HOME%\logs\server.out" to be deleted >> %LOG%
"%JAVA_BIN%" -Xms8M -Xmx8M org.opends.server.tools.WaitForFileDelete --targetFile "%DIR_HOME%\logs\server.starting" --logFile "%DIR_HOME%\logs\server.out"
goto end
:runDetachCalledByWinService
rem We write the output of the start command to the winwervice.out file.
echo %SCRIPT%: Run detach called by windows service  >> %LOG%
if not exist "%DIR_HOME%\logs\server.out" echo. > "%DIR_HOME%\logs\server.out"
if not exist "%DIR_HOME%\logs\server.starting" echo. > "%DIR_HOME%\logs\server.starting"
echo. > "%DIR_HOME%\logs\server.startingservice"
echo. > "%DIR_HOME%\logs\winservice.out"
"%DIR_HOME%\lib\winlauncher.exe" start "%DIR_HOME%" "%JAVA_BIN%" %JAVA_ARGS%  org.opends.server.core.DirectoryServer --configClass org.opends.server.extensions.ConfigFileHandler --configFile "%DIR_HOME%\config\config.ldif" %*
echo %SCRIPT%: Waiting for "%DIR_HOME%\logs\server.out" to be deleted >> %LOG%
"%JAVA_BIN%" -Xms8M -Xmx8M org.opends.server.tools.WaitForFileDelete --targetFile "%DIR_HOME%\logs\server.starting" --logFile "%DIR_HOME%\logs\server.out" --outputFile "%DIR_HOME%\logs\winservice.out"
erase "%DIR_HOME%\logs\server.startingservice"
goto end
:runAsService
echo %SCRIPT%: Run as service >> %LOG%
"%JAVA_BIN%" -Xms8M -Xmx8M org.opends.server.tools.StartWindowsService
echo %SCRIPT%: Waiting for "%DIR_HOME%\logs\server.startingservice" to be deleted >> %LOG%
"%JAVA_BIN%" -Xms8M -Xmx8M org.opends.server.tools.WaitForFileDelete --targetFile "%DIR_HOME%\logs\server.startingservice"
rem Type the contents the winwervice.out file and delete it.
if exist "%DIR_HOME%\logs\winservice.out" type "%DIR_HOME%\logs\winservice.out"
if exist "%DIR_HOME%\logs\winservice.out" erase "%DIR_HOME%\logs\winservice.out"
:end
echo %SCRIPT%: finished >> %LOG%
opends/resource/bin/stop-ds.bat
@@ -33,6 +33,15 @@
set SCRIPT_NAME_ARG="-Dorg.opends.server.scriptName=stop-ds"
set DIR_HOME=%~dP0..
set INSTANCE_ROOT=%DIR_HOME%
set LOG=%INSTANCE_ROOT%\logs\native-windows.out
set SCRIPT=stop-ds.bat
rem This is the template to use for logging.  Make sure to use >>
rem echo %SCRIPT%: your-message-here >> %LOG%
echo %SCRIPT%: invoked >> %LOG%
:checkJavaBin
if "%JAVA_BIN%" == "" goto noJavaBin
goto setClassPath
@@ -52,9 +61,11 @@
:noSetJavaHome
echo Error: JAVA_HOME environment variable is not set.
echo        Please set it to a valid Java 5 (or later) installation.
echo %SCRIPT%: JAVA_HOME environment variable is not set. >> %LOG%
goto end
:noValidJavaHome
echo %SCRIPT%: The detected Java version could not be used. JAVA_HOME=[%JAVA_HOME%] >> %LOG%
echo ERROR:  The detected Java version could not be used.  Please set 
echo         JAVA_HOME to to a valid Java 5 (or later) installation.
goto end
@@ -62,6 +73,8 @@
:setClassPath
FOR %%x in ("%DIR_HOME%\lib\*.jar") DO call "%DIR_HOME%\lib\setcp.bat" %%x
echo %SCRIPT%: CLASSPATH=%CLASSPATH% >> %LOG%
rem Test that the provided JDK is 1.5 compatible.
"%JAVA_BIN%" org.opends.server.tools.InstallDS -t > NUL 2>&1
if not %errorlevel% == 0 goto noValidJavaHome
@@ -79,33 +92,41 @@
goto end
:serverAlreadyStopped
echo %SCRIPT%: server already stopped >> %LOG%
if exist "%DIR_HOME%\logs\server.pid" erase "%DIR_HOME%\logs\server.pid"
goto end
:startUsingSystemCall
echo %SCRIPT%: start using system call >> %LOG%
"%DIR_HOME%\bat\start-ds.bat"
goto end
:stopUsingSystemCall
echo %SCRIPT%: stop using system call >> %LOG%
"%DIR_HOME%\lib\winlauncher.exe" stop "%DIR_HOME%"
goto end
:restartUsingSystemCall
echo %SCRIPT%: restart using system call >> %LOG%
"%DIR_HOME%\lib\winlauncher.exe" stop "%DIR_HOME%"
if not %errorlevel% == 0 goto end
goto startUsingSystemCall
:stopUsingProtocol
echo %SCRIPT%: stop using protocol >> %LOG%
call "%DIR_HOME%\lib\_client-script.bat" %*
goto end
:stopAsWindowsService
echo %SCRIPT%: stop as windows service >> %LOG%
"%JAVA_BIN%" -Xms8M -Xmx8M org.opends.server.tools.StopWindowsService
goto end
:restartAsWindowsService
echo %SCRIPT%: restart as windows service, stopping >> %LOG%
"%JAVA_BIN%" -Xms8M -Xmx8M org.opends.server.tools.StopWindowsService
if not %errorlevel% == 0 goto end
echo %SCRIPT%: restart as windows service, starting >> %LOG%
"%JAVA_BIN%" -Xms8M -Xmx8M org.opends.server.tools.StartWindowsService
"%JAVA_BIN%" -Xms8M -Xmx8M org.opends.server.tools.WaitForFileDelete --targetFile "%DIR_HOME%\logs\server.startingservice"
rem Type the contents the winwervice.out file and delete it.
@@ -115,3 +136,4 @@
:end
echo %SCRIPT%: finished >> %LOG%
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);
  }
}
opends/src/build-tools/windows/common.h
@@ -28,8 +28,14 @@
// Just some functions and constants to be used by winlauncher.c
// and service.c
// This stops warnings about deprecation of stdio functions
#define _CRT_SECURE_NO_DEPRECATE 1
#include <Windows.h>
int spawn(const char* command, BOOL background);
BOOL createChildProcess(char* command, BOOL background,
PROCESS_INFORMATION* procInfo);
void debug(const char *msg, ...);
void debugError(const char *msg, ...);
void updateDebugFlag(char* argv[], int argc);
opends/src/build-tools/windows/service.c
@@ -33,8 +33,6 @@
char *_instanceDir = NULL;
HANDLE _eventLog = NULL;
char * _logFile = NULL;
BOOL DEBUG = FALSE;
// ----------------------------------------------------
// Register a service handler to the service control dispatcher.
@@ -58,6 +56,8 @@
{
  ServiceReturnCode returnValue;
  debug("Registering the service handler for '%s'", serviceName);
  // register the service to the service control dispatcher (SCM)
  *serviceStatusHandle = RegisterServiceCtrlHandler (
  serviceName, (LPHANDLER_FUNCTION) serviceHandler
@@ -70,89 +70,13 @@
  {
    returnValue = SERVICE_RETURN_OK;
  }
  debug("registerServiceHandler returning '%d'", returnValue);
  return returnValue;
}  // registerServiceHandler
// ---------------------------------------------------
// Debug utility.
// If the _eventLog is NULL and the DEBUG variable is TRUE write the message
// in a log file.
// ---------------------------------------------------
void debug(char* msg)
{
  if (DEBUG == TRUE)
  {
    /*
    if (_eventLog != NULL)
    {
      const char* args[1];
      args[0] = msg;
      // report the event
      ReportEvent(
      _eventLog,          // event log handle
      EVENTLOG_INFORMATION_TYPE,  // info, warning, error
      WIN_FACILITY_NAME_OPENDS,   // unique category for OPENDS
      WIN_EVENT_ID_DEBUG,
      NULL,           // no user security identifier
      1,              // number of  args
      0,              // raw data size
      (const char**)args,     // args
      NULL            // no war data
      );
    }
    */
    // Log to the file
    FILE *fp;
    if (_logFile == NULL)
    {
      char path [MAX_PATH];
      if (_instanceDir != NULL)
      {
        int length = strlen(_instanceDir);
        if ((length > 0) && (_instanceDir[length - 1] == '\\'))
        {
          sprintf(path, "%slogs\\windows-service.out", _instanceDir);
          _logFile = strdup(path);
        }
        else
        {
          sprintf(path, "%s\\logs\\windows-service.out", _instanceDir);
          _logFile = strdup(path);
        }
      }
      else
      {
        char execName [MAX_PATH];
        char instanceDir [MAX_PATH];
        int length;
        GetModuleFileName (
            NULL,
            execName,
            MAX_PATH
        );
        length = strlen(execName) - strlen("lib\\opends_service.exe");
        if (length > 0)
        {
          strncpy(instanceDir, execName, length);
          instanceDir[length] = '\0';
          sprintf(path, "%slogs\\windows-service.out", instanceDir);
          _logFile = strdup(path);
        }
      }
    }
    if ((_logFile != NULL) && ((fp = fopen(_logFile, "a")) != NULL))
    {
      fprintf(fp, "%s\n", msg);
      fclose(fp);
    }
    else
    {
      fprintf(stdout, "Could not create log file.\n");
    }
  }
}
// ---------------------------------------------------
// Reports a log event of a given type, id and arguments
@@ -223,11 +147,12 @@
  );
  if (scm == NULL)
  {
    debug("scm is NULL.");
    debugError("Failed to open the Service Control Manager.  Last error = %d", GetLastError());
    returnValue = SERVICE_RETURN_ERROR;
  }
  else
  {
    debug("Successfully opened the Service Control Manager.");
    returnValue = SERVICE_RETURN_OK;
  }
  return returnValue;
@@ -262,6 +187,9 @@
  // here because we already required it to figure out to get the service
  // name based on the command to run associated with it.
  char execName [MAX_PATH];
  debug("Creating registry key for service '%s'.", serviceName);
  GetModuleFileName (
  NULL,
  execName,
@@ -280,6 +208,7 @@
  );
  if (result == ERROR_SUCCESS)
  {
    debug("The registry key for service '%s' already exists.", serviceName);
    alreadyRegistered = TRUE;
    success = FALSE;
  }
@@ -300,7 +229,7 @@
    );
    if (result != ERROR_SUCCESS)
    {
      debug("RegCreateKeyEx failed.");
      debugError("RegCreateKeyEx failed, result=%d.", result);
      success = FALSE;
    }
  }
@@ -318,6 +247,7 @@
    );
    if (result != ERROR_SUCCESS)
    {
      debugError("RegSetValueEx('EventMessageFile') failed, result=%d.", result);
      success = FALSE;
    }
  }
@@ -341,6 +271,7 @@
    );
    if (result != ERROR_SUCCESS)
    {
      debugError("RegSetValueEx('TypesSupported') failed, result=%d.", result);
      success = FALSE;
    }
  }
@@ -359,6 +290,7 @@
    );
    if (result != ERROR_SUCCESS)
    {
      debugError("RegSetValueEx('CategoryMessageFile') failed, result=%d.", result);
      success = FALSE;
    }
  }
@@ -376,6 +308,7 @@
    );
    if (result != ERROR_SUCCESS)
    {
      debugError("RegSetValueEx('CategoryCount') failed, result=%d.", result);
      success = FALSE;
    }
  }
@@ -392,7 +325,7 @@
  }
  else
  {
    debug("Could not create a registry key.");
    debugError("Could not create a registry key.");
    return FALSE;
  }
}  // createRegistryKey
@@ -406,7 +339,7 @@
// ---------------------------------------------------
BOOLEAN removeRegistryKey(char* serviceName)
{
  BOOL returnValue;
  BOOL returnValue = FALSE;
  // Create the event source subkey (or open it if it already exists)
  char subkey [MAX_REGISTRY_KEY];
@@ -415,6 +348,8 @@
  HKEY hkey = NULL;
  debug("Removing registry key for service '%s'.", serviceName);
  // Check whether the Registry Key is already created,
  // If so don't create a new one.
  sprintf (subkey, EVENT_LOG_KEY, serviceName);
@@ -427,6 +362,7 @@
  );
  if (result != ERROR_SUCCESS)
  {
    debug("The registry key for service '%s' does not exist, so we do not need to remove it.", serviceName);
    // Assume that the registry key does not exist.
    returnValue = TRUE;
  }
@@ -437,6 +373,10 @@
    {
      returnValue = TRUE;
    }
    else
    {
      debugError("RegDeleteKey('%s') failed, result=%d.", subkey, result);
    }
  }
  return returnValue;
@@ -453,6 +393,8 @@
  // subkey under Eventlog registry key
  char subkey [MAX_SERVICE_NAME];
  debug("Registering the Event Log for service '%s'.", serviceName);
  sprintf (subkey, serviceName);
  eventLog = RegisterEventSource(
@@ -471,6 +413,7 @@
{
  if (_eventLog != NULL)
  {
    debug("Deregistering the Event Log.");
    DeregisterEventSource(_eventLog);
  }
}
@@ -485,21 +428,26 @@
  ServiceReturnCode returnValue;
  char* relativePath = "\\locks\\server.lock";
  char lockFile[MAX_PATH];
  debug("Determining if the server is running.");
  if (strlen(relativePath)+strlen(_instanceDir)+1 < MAX_PATH)
  {
    int fd;
    sprintf(lockFile, "%s%s", _instanceDir, relativePath);
    debug("When determining whether the server is running, the lock file name is '%s'.", lockFile);
    fd = _open(lockFile, _O_RDWR);
    if (fd != -1)
    {
      debug("Able to open the lock file '%s'.", lockFile);
      returnValue = SERVICE_RETURN_OK;
      // Test if there is a lock
      /* Lock some bytes and read them. Then unlock. */
      if(_locking(fd, LK_NBLCK, 1) != -1)
      {
        debug("Able to lock '%s', so the server is not running.", lockFile);
        *running = FALSE;
        _locking(fd, LK_UNLCK, 1);
      }
@@ -507,20 +455,21 @@
      {
        if (errno == EACCES)
        {
          debug("Unable to lock '%s', so the server is running.", lockFile);
          *running = TRUE;
        }
        else
        {
          *running = FALSE;
          returnValue = SERVICE_RETURN_ERROR;
          debug("Unexpected error locking");
          debugError("Unexpected error locking: %d", errno);
        }
      }
      _close(fd);
    }
    else
    {
      debug("Could not open lock file.");
      debug("Could not open lock file '%s', which means the server is not running.", lockFile);
      *running = FALSE;
      returnValue = SERVICE_RETURN_ERROR;
    }
@@ -531,6 +480,7 @@
    *running = FALSE;
    returnValue = SERVICE_RETURN_ERROR;
  }
  return returnValue;
}  // isServerRunning
@@ -545,35 +495,40 @@
  // init out params
  char* relativePath = "\\bat\\start-ds.bat";
  char command[COMMAND_SIZE];
  debug("doStartApplication called.");
  
  if (strlen(relativePath)+strlen(_instanceDir)+1 < COMMAND_SIZE)
  {
    sprintf(command, "\"%s%s\" --windowsNetStart", _instanceDir, relativePath);
    // launch the command
    debug("doStartApplication attempting to spawn '%s'", command);
    if (spawn(command, FALSE) != -1)
    {
      // Try to see if server is really running
      int nTries = 10;
      BOOL running = FALSE;
      
      debug("doStartApplication: the spawn of the process worked.");
      debug("Command:");
      debug(command);
      debug("doStartApplication: the spawn of the process worked.  Command: '%s'", command);
      // Wait to be able to launch the java process in order it to free the lock
      // on the file.
      debug("Sleeping for 3 seconds to allow the process to free the lock.");
      Sleep(3000);
      while ((nTries > 0) && !running)
      {
        nTries--;
        if (isServerRunning(&running) != SERVICE_RETURN_OK)
        {
          break;
        }
        if (!running)
        {
          debug("Sleeping for 2 seconds to allow the process to free the lock.  %d tries remaining.", nTries);
          Sleep(2000);
        }
        nTries--;
      }
      if (running)
      {
@@ -695,10 +650,12 @@
  {
    // failed to get the path of the executable file
    returnValue = SERVICE_RETURN_ERROR;
    debug("Could not get the path of the executable file.\n");
    debug("Could not get the path of the executable file.");
  }
  else
  {
    debug("When determining the service bin path, the module file name is '%s'.", fileName);
    if (result == MAX_PATH)
    {
      // buffer was too small, executable name is probably not valid
@@ -707,7 +664,7 @@
    }
    else
    {
      if (strlen(fileName) + strlen(" start ") + strlen(_instanceDir)
      if ((strlen(fileName) + strlen(" start ") + strlen(_instanceDir) + strlen("\"\""))
        < COMMAND_SIZE)
      {
        sprintf(serviceBinPath, "%s start \"%s\"", fileName,
@@ -715,10 +672,11 @@
      }
      else
      {
        char * msg = "The name of the resulting windows service command is too long.\n";
        debug(msg);
        // buffer was too small, executable name is probably not valid
        returnValue = SERVICE_RETURN_ERROR;
        fprintf(stdout,
            "The name of the resulting windows service command is too long.\n");
        fprintf(stdout, msg);
      }
    }
  }
@@ -745,6 +703,11 @@
  // retrieve list of services
  ServiceDescriptor* serviceList = NULL;
  int nbServices = -1;
  strcpy(serviceName, "");
  debug("Attempting to get the service name assuming command to run is '%s'.", cmdToRun);
  returnValue = getServiceList(&serviceList, &nbServices);
  // go through the list of services and search for the service name
@@ -772,8 +735,7 @@
            }
            else
            {
              debug("The service name found is too long:");
              debug(curService.serviceName);
              debug("The service name found is too long: '%s'", curService.serviceName);
            }
            break;
          }
@@ -786,6 +748,9 @@
  {
    debug("getServiceName: could not get service list.");
  }
  debug("The service name was found to be '%s'.", serviceName);
  return returnValue;
}  // getServiceName
@@ -817,6 +782,8 @@
{
  ServiceReturnCode returnValue;
  // elaborate service type:
  // SERVICE_WIN32_OWN_PROCESS means this is not a driver and there is
  // only one service in the process
@@ -832,8 +799,14 @@
  DWORD controls;
  SERVICE_STATUS serviceStatus;
  BOOL success;
  debug("Updating the service status.  statusToSet=%d win32ExitCode=%d serviceExitCode=%d checkPoint=%d waitHint=%d",
        statusToSet, win32ExitCode, serviceExitCode,
        checkPoint, waitHint);
  if (statusToSet == SERVICE_START_PENDING)
  {
    debug("Service start pending.");
    // do not accept any command when the service is starting up...
    controls = SERVICE_ACCEPT_NONE;
  }
@@ -864,6 +837,7 @@
  if (!success)
  {
    debugError("Failed to set the service status.  Last error = %d.", GetLastError());
    returnValue = SERVICE_RETURN_ERROR;
  }
  else
@@ -897,6 +871,8 @@
  DWORD checkPoint = CHECKPOINT_FIRST_VALUE;
  SERVICE_STATUS_HANDLE serviceStatusHandle;
  // __debugbreak();
  debug("serviceMain called.");
  
  code = createServiceBinPath(cmdToRun);
@@ -997,6 +973,7 @@
      break;
      default:
      debugError("doApplication() failed");
      code = SERVICE_RETURN_ERROR;
      _serviceCurStatus = SERVICE_STOPPED;
      updateServiceStatus (
@@ -1027,7 +1004,9 @@
  // if all is ok wait for the application to die before we leave
  if (code == SERVICE_RETURN_OK)
  {
    debug("Waiting indefinitely for the application to exit.");
    WaitForSingleObject (_terminationEvent, INFINITE);
    debug("The application has exited.");
  }
  // update the service status to STOPPED if it's not already done
@@ -1044,6 +1023,7 @@
    _serviceStatusHandle
    );
  }
  debug("serviceMain() returning.");
}  // serviceMain
@@ -1054,6 +1034,7 @@
// ----------------------------------------------------
void doTerminateService(HANDLE terminationEvent)
{
  debug("Faking a service termination so serviceMain can return.");
  SetEvent(terminationEvent);
  return;
@@ -1071,17 +1052,17 @@
  ServiceReturnCode code;
  DWORD checkpoint;
  BOOL running;
  debug("serviceHandler called.");
  debug("serviceHandler called with controlCode=%d.", controlCode);
  switch (controlCode)
  {
    case SERVICE_CONTROL_SHUTDOWN:
    // If system is shuting down then stop the service
    // -> no break here
      debug("serviceHandler: Shutdown.");
      debug("serviceHandler: shutdown");
    case SERVICE_CONTROL_STOP:
    {
      // update service status to STOP_PENDING
      debug("serviceHandler: Stop.");
      debug("serviceHandler: stop");
      _serviceCurStatus = SERVICE_STOP_PENDING;
      checkpoint = CHECKPOINT_FIRST_VALUE;
      updateServiceStatus (
@@ -1123,6 +1104,7 @@
      {
        WORD argCount = 1;
        const char *argc[] = {_instanceDir};
        debug("The server could not be stopped.");
        // We could not stop the server
        reportLogEvent(
        EVENTLOG_ERROR_TYPE,
@@ -1222,7 +1204,11 @@
    );
  }
  if (myService != NULL)
  if (myService == NULL)
  {
      debugError("Failed to open the service '%s'.", serviceName);
  }
  else
  {
    while (!getConfigOk)
    {
@@ -1240,7 +1226,7 @@
        DWORD errCode = GetLastError();
        if (errCode == ERROR_INSUFFICIENT_BUFFER)
        {
          // buffer nor big enough...
          // buffer not big enough...
          configSize += bytesNeeded;
          serviceConfig =
          (LPQUERY_SERVICE_CONFIG)realloc(serviceConfig, configSize);
@@ -1248,12 +1234,7 @@
        }
        else
        {
          char msg[200];
          sprintf(msg,
              "getBinaryPath: error calling QueryServiceConfig. Code [%d]",
              errCode);
          // error
          debug(msg);
          debug("getBinaryPath: error calling QueryServiceConfig. Code [%d]", errCode);
          break;
        }
      }
@@ -1266,12 +1247,7 @@
        }
        else
        {
          debug(
              "getBinaryPath: the length of the binary path name is too big.");
          debug("serviceName:");
          debug(serviceName);
          debug("binary path:");
          debug(serviceConfig->lpBinaryPathName);
          debug("getBinaryPath: the length of the binary path name is too big. serviceName='%s', binaryPath='%s'", serviceName, serviceConfig->lpBinaryPathName);
        }
      }
    }
@@ -1329,11 +1305,7 @@
      DWORD lastError = GetLastError();
      if (lastError != ERROR_MORE_DATA)
      {
        char msg[200];
        sprintf(msg, "getServiceList: generic error. Code [%d]",
        lastError);
        // error
        debug(msg);
        debug("getServiceList: generic error. Code [%d]", lastError);
        returnValue = SERVICE_RETURN_ERROR;
      }
      else
@@ -1359,10 +1331,8 @@
          DWORD lastError = GetLastError();
          if (lastError != ERROR_MORE_DATA)
          {
    char msg[200];
            returnValue = SERVICE_RETURN_ERROR;
          sprintf(msg, "getServiceList: second try generic error. Code [%d]",
          lastError);
            debug("getServiceList: second try generic error. Code [%d]", lastError);
          }
          else
          {
@@ -1406,18 +1376,17 @@
      l = (ServiceDescriptor*)calloc(sizeof(ServiceDescriptor), aux);
      for (i = 0; i < aux; i++)
      {
        l[i].serviceName = strdup(curService->lpServiceName);
        l[i].displayName = strdup(curService->lpDisplayName);
        l[i].serviceName = _strdup(curService->lpServiceName);
        l[i].displayName = _strdup(curService->lpDisplayName);
        if (getBinaryPathName(scm, l[i].serviceName, binPath) ==
          SERVICE_RETURN_OK)
        {
          l[i].cmdToRun = strdup(binPath);
          l[i].cmdToRun = _strdup(binPath);
        }
    else
        else
        {
          debug("Error getting binary path name of service:");
      debug(l[i].serviceName);
          debug("Error getting binary path name of service: %s", l[i].serviceName);
        }
        curService++;
      }
@@ -1457,6 +1426,8 @@
  int nbServices = -1;
  int i;
  debug("Determining if service name '%s' is in use.", serviceName);
  // go through the list of services and search for the service name
  if (getServiceList(&serviceList, &nbServices) == SERVICE_RETURN_OK)
  {
@@ -1477,6 +1448,7 @@
          if (strcmp (serviceName, curService.serviceName) == 0)
          {
            // found the service!
            debug("The service name '%s' is in use.", serviceName);
            returnValue = SERVICE_IN_USE;
          }
        }
@@ -1486,6 +1458,7 @@
  }
  else
  {
    debugError("Could not determine if the service name '%s' is in use because listing the services failed.", serviceName);
    returnValue = SERVICE_RETURN_ERROR;
  }
  return returnValue;
@@ -1509,6 +1482,7 @@
  int i = 1;
  BOOL ended = FALSE;
  ServiceReturnCode nameInUseResult;
  strcpy(serviceName, "");
  while (!ended)
  {
    if (i == 1)
@@ -1540,6 +1514,9 @@
    }
  }
  debug("createServiceName returning serviceName='%s' and returnValue=%d",
        serviceName, returnValue);
  return returnValue;
} // createServiceName
@@ -1586,6 +1563,7 @@
  if (returnValue == SERVICE_RETURN_OK)
  {
    debug("Creating the service '%s'.", serviceName);
    myService = CreateService(
    scm,
    serviceName,                // name of service
@@ -1607,6 +1585,7 @@
  if ((returnValue == SERVICE_RETURN_OK) && (myService == NULL))
  {
    DWORD errCode = GetLastError();
    debugError("Failed to create the service '%s'.  Last error = %d.", serviceName, errCode);
    if (errCode == ERROR_DUPLICATE_SERVICE_NAME)
    {
      returnValue = DUPLICATED_SERVICE_NAME;
@@ -1635,6 +1614,7 @@
    if (!success)
    {
      debugError("Failed to add a description to the service '%s'.  Last error = %d.", serviceName, GetLastError());
      returnValue = SERVICE_RETURN_ERROR;
    }
  }
@@ -1656,6 +1636,8 @@
    free (serviceName);
  }
  debug("createServiceInScm returning %d.", returnValue);
  return returnValue;
} // createServiceInScm
@@ -1675,6 +1657,8 @@
  SC_HANDLE myService = NULL;
  SERVICE_STATUS serviceStatus;
  debug("Removing service '%s' from the Service Control Manager.", serviceName);
  returnValue = openScm(GENERIC_WRITE, &scm);
  // open the service
@@ -1687,6 +1671,7 @@
    );
    if (myService == NULL)
    {
      debugError("Failed to open the service '%s'. Last error = %d", serviceName, GetLastError());
      returnValue = SERVICE_RETURN_ERROR;
    }
  }
@@ -1699,6 +1684,7 @@
    );
    if (!success)
    {
      debugError("Failed to query the status for service '%s'. Last error = %d", serviceName, GetLastError());
      returnValue = SERVICE_RETURN_ERROR;
    }
  }
@@ -1708,7 +1694,9 @@
  {
    if (serviceStatus.dwCurrentState != SERVICE_STOPPED)
    {
      BOOL success = ControlService (
      BOOL success;
      debug("Attempting to stop the service '%s'.", serviceName);
      success = ControlService (
      myService,
      SERVICE_CONTROL_STOP,
      &serviceStatus
@@ -1716,6 +1704,7 @@
      if (!success)
      {
        DWORD errCode = GetLastError();
        debugError("Failed to stop the service '%s'.  Last error = %d.", serviceName, errCode);
        if (errCode == ERROR_SERVICE_MARKED_FOR_DELETE)
        {
          returnValue = SERVICE_MARKED_FOR_DELETION;
@@ -1735,11 +1724,13 @@
  // remove the service
  if (returnValue == SERVICE_RETURN_OK)
  {
    BOOL success = DeleteService (myService);
    BOOL success;
    debug("Deleting the service '%s'.");
    success = DeleteService (myService);
    if (!success)
    {
      DWORD errCode = GetLastError();
      debugError("Failed to delete the service '%s'.  Last error = %d.", serviceName, errCode);
      if (errCode == ERROR_SERVICE_MARKED_FOR_DELETE)
      {
        returnValue = SERVICE_MARKED_FOR_DELETION;
@@ -1784,7 +1775,7 @@
  char cmdToRun[COMMAND_SIZE];
  ServiceReturnCode code;
  debug("Creating service.");
  debug("Creating service displayName='%s' description='%s'.", displayName, description);
  code = createServiceBinPath(cmdToRun);
  if (code == SERVICE_RETURN_OK)
@@ -1793,6 +1784,7 @@
    code = getServiceName(cmdToRun, serviceName);
    if (code == SERVICE_RETURN_OK)
    {
      debug("Service '%s' already exists.", displayName);
      // There is a valid serviceName for the command to run, so
      // OpenDS is registered as a service.
      code = SERVICE_ALREADY_EXISTS;
@@ -1800,6 +1792,7 @@
    }
    else
    {
      debug("Could not find service '%s', so creating it now.", displayName);
      // We could not find a serviceName for the command to run, so
      // try to create the service.
      code = createServiceInScm(displayName, description, cmdToRun);
@@ -1812,7 +1805,7 @@
        }
        else
        {
          debug("Could not get a service name for command to run");
          debug("Could not get a service name for command to run.");
        }
      }
    }
@@ -1859,24 +1852,27 @@
  char serviceName[MAX_SERVICE_NAME];
  ServiceReturnCode code;
  strcpy(serviceName, "");
  debug("Getting service state.");
  code = createServiceBinPath(cmdToRun);
  debug("Created the service bin path. code=%d.  cmdToRun='%s'.", code, cmdToRun);
  if (code == SERVICE_RETURN_OK)
  {
    code = getServiceName(cmdToRun, serviceName);
    if (code == SERVICE_RETURN_OK)
    {
      // There is a valid serviceName for the command to run, so
      // OpenDS is registered as a service.
      fprintf(stdout, serviceName);
      returnCode = 0;
      debug("Service is enabled.");
      debug("Service '%s' is enabled.", serviceName);
    }
    else
    {
      returnCode = 1;
      debug("Service is disabled.");
      debug("Service '%s' is disabled enabled.", serviceName);
    }
  }
  else
@@ -1950,6 +1946,7 @@
  char serviceName[MAX_SERVICE_NAME];
  ServiceReturnCode code;
  debug("removeService()");
  code = createServiceBinPath(cmdToRun);
  if (code == SERVICE_RETURN_OK)
@@ -1969,6 +1966,7 @@
    returnCode = 2;
  }
  debug("removeService() returning %d.", returnCode);
  return returnCode;
} // removeService
@@ -1987,6 +1985,7 @@
  char cmdToRun[COMMAND_SIZE];
  ServiceReturnCode code;
  debug("startService()");
  code = createServiceBinPath(cmdToRun);
  if (code == SERVICE_RETURN_OK)
@@ -2042,6 +2041,7 @@
      WIN_EVENT_ID_SERVER_START_FAILED,
      argCount, argc
      );
      debugError("For instance dir '%s', %s", argc[0], argc[1]);
    }
    deregisterEventLog();
  }
@@ -2063,29 +2063,22 @@
}  // startService
// ---------------------------------------------------------------
// 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 startIndex)
{
  int i;
  DEBUG = FALSE;
  for (i=startIndex; (i<argc) && !DEBUG; i++)
  {
    if (strcmp(argv[i], "--debug") == 0)
    {
      DEBUG = TRUE;
    }
  }
}
int main(int argc, char* argv[])
{
  char* subcommand;
  int returnCode = 0;
  int i;
  updateDebugFlag(argv, argc);
  debug("main called.");
  for (i = 0; i < argc; i++) {
      debug("  argv[%d] = '%s'", i, argv[i]);
  }
  // __debugbreak();
  if (argc <= 1)
  {
    fprintf(stdout,
@@ -2105,8 +2098,7 @@
      }
      else
      {
        _instanceDir = strdup(argv[2]);
        updateDebugFlag(argv, argc, 5);
        _instanceDir = _strdup(argv[2]);
        returnCode = createService(argv[3], argv[4]);
        free(_instanceDir);
      }
@@ -2121,8 +2113,7 @@
      }
      else
      {
        _instanceDir = strdup(argv[2]);
        updateDebugFlag(argv, argc, 3);
        _instanceDir = _strdup(argv[2]);
        returnCode = serviceState();
        free(_instanceDir);
      }
@@ -2137,8 +2128,7 @@
      }
      else
      {
        _instanceDir = strdup(argv[2]);
        updateDebugFlag(argv, argc, 3);
        _instanceDir = _strdup(argv[2]);
        returnCode = removeService();
        free(_instanceDir);
      }
@@ -2153,8 +2143,7 @@
      }
      else
      {
        _instanceDir = strdup(argv[2]);
        DEBUG = TRUE;
        _instanceDir = _strdup(argv[2]);
        returnCode = startService();
        free(_instanceDir);
      }
@@ -2171,8 +2160,7 @@
      {
        BOOL running;
        ServiceReturnCode code;
        _instanceDir = strdup(argv[2]);
        updateDebugFlag(argv, argc, 3);
        _instanceDir = _strdup(argv[2]);
        code = isServerRunning(&running);
        if (code == SERVICE_RETURN_OK)
        {
@@ -2196,8 +2184,7 @@
      }
      else
      {
        char* serviceName = strdup(argv[2]);
        updateDebugFlag(argv, argc, 3);
        char* serviceName = _strdup(argv[2]);
        returnCode = removeServiceWithServiceName(serviceName);
        free(serviceName);
      }
@@ -2210,6 +2197,8 @@
    }
  }
  debug("main returning %d.", returnCode);
  return returnCode;
} // main
opends/src/build-tools/windows/service.h
@@ -25,12 +25,12 @@
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
#include "common.h"
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <sys/locking.h>
#include "common.h"
#include "EventLogMsg.h"
#define MAX_SERVICE_NAME 256
opends/src/build-tools/windows/winlauncher.c
@@ -27,7 +27,6 @@
#include "winlauncher.h"
// ----------------------------------------------------
// Generates the pid file name for a given instanceDir.
// Returns TRUE if the command name could be initiated and
@@ -38,13 +37,18 @@
{
  BOOL returnValue;
  char* relativePath = "\\logs\\server.pid";
  debug("Attempting to get the PID file for instanceDir='%s'", instanceDir);
  if ((strlen(relativePath) + strlen(instanceDir)) < maxSize)
  {
    sprintf(pidFile, "%s\\logs\\server.pid", instanceDir);
    sprintf(pidFile, maxSize, "%s\\logs\\server.pid", instanceDir);
    returnValue = TRUE;
    debug("PID file name is '%s'.", pidFile);
  }
  else
  {
    debugError("Unable to get the PID file name because the path was too long.");
    returnValue = FALSE;
  }
  return returnValue;
@@ -68,7 +72,9 @@
  {
    returnValue = TRUE;
  }
  debug("File '%s' does%s exist.", fileName, (returnValue ? "" : " not"));
  return returnValue;
} // fileExists
@@ -84,23 +90,28 @@
  char pidFile[PATH_SIZE];
  int nTries = 10;
  
  debug("Attempting to delete the PID file from instanceDir='%s'.", instanceDir);
  // Sometimes the lock on the system in windows takes time to be released.
  if (getPidFile(instanceDir, pidFile, PATH_SIZE))
  {
    while (fileExists(pidFile) && (nTries > 0) && !returnValue)
    {
      debug("PID file '%s' exists, attempting to remove it.", instanceDir);
      if (remove(pidFile) == 0)
      {
        debug("Successfully removed PID file: '%s'.", pidFile);
        returnValue = TRUE;
      }
      else
      {
        Sleep(500);
        nTries--;
        debug("Failed to remove the PID file.  Sleeping for a bit.  Will try %d more time(s).", nTries);
        Sleep(500);
      }
    }
  }
  
  debug("deletePidFile('%s') returning %d.", instanceDir, returnValue);
  return returnValue;
}  // deletePidFile
@@ -118,11 +129,13 @@
  char buf[BUF_SIZE];
  int read;
  
  debug("Attempting to get the PID for the server rooted at '%s'.", instanceDir);
  if (getPidFile(instanceDir, pidFile, PATH_SIZE))
  {
    if ((f = fopen(pidFile, "r")) != NULL)
    {
      read = fread(buf, 1, sizeof(buf),f);
      debug("Read '%s' from the PID file '%s'.", buf, pidFile);
    }
    
    if (f != NULL)
@@ -132,7 +145,9 @@
    }
    else
    {
      fprintf(stderr, "File %s could not be opened", pidFile);
      char * msg = "File %s could not be opened.\nMost likely the server has already stopped.\n\n";
      debug(msg, pidFile);
      fprintf(stderr, msg, pidFile);
      returnValue = 0;
    }
  }
@@ -140,6 +155,7 @@
  {
    returnValue = 0;
  }
  debug("getPid('%s') returning %d.", instanceDir, returnValue);
  return returnValue;
}  // getPid
@@ -152,7 +168,12 @@
BOOL killProcess(int pid)
{
  BOOL processDead;
  HANDLE procHandle = OpenProcess(
  HANDLE procHandle;
  debug("killProcess(pid=%d)", pid);
  debug("Opening process with pid=%d.", pid);
  procHandle = OpenProcess(
  PROCESS_TERMINATE               // to terminate the process
  | PROCESS_QUERY_INFORMATION,    // to get exit code
  FALSE,                          // handle is not inheritable
@@ -161,6 +182,7 @@
  
  if (procHandle == NULL)
  {
    debug("The process with pid=%d has already terminated.", pid);
    // process already dead
    processDead = TRUE;
  }
@@ -168,14 +190,17 @@
  {
    if (!TerminateProcess(procHandle, 0))
    {
      debugError("Failed to terminate process (pid=%d) lastError=%d.", pid, GetLastError());
      // failed to terminate the process
      processDead = FALSE;
    }
    else
    {
      // wait for the process to end.
      DWORD exitCode;
      int nTries = 20;
      debug("Successfully began termination process for (pid=%d).", pid);
      // wait for the process to end.
      
      processDead = FALSE;
      while ((nTries > 0) && !processDead)
@@ -184,18 +209,21 @@
        if (exitCode == STILL_ACTIVE)
        {
          // process is still alive, let's wait 1 sec and loop again
          Sleep(1000);
          nTries--;
          debug("Process (pid=%d) has not yet exited.  Sleeping for 1 second and will try %d more time(s).", pid, nTries);
          Sleep(1000);
        }
        else
        {
          debug("Process (pid=%d) has exited with exit code %d.", pid, exitCode);
          processDead = TRUE;
        }
      }
    }
    CloseHandle(procHandle);
  }
  debug("killProcess(pid=%d) returning %d", pid, processDead);
  return processDead;
} // killProcess
@@ -206,11 +234,13 @@
// otherwise.
// ----------------------------------------------------
BOOL createPidFile(const char* instanceDir, int pid)
{
{
  BOOL returnValue = FALSE;
  char pidFile[PATH_SIZE];
  FILE *f;
  
  debug("createPidFile(instanceDir='%s',pid=%d)", instanceDir, pid);
  if (getPidFile(instanceDir, pidFile, PATH_SIZE))
  {
    if ((f = fopen(pidFile, "w")) != NULL)
@@ -218,14 +248,17 @@
      fprintf(f, "%d", pid);
      fclose (f);
      returnValue = TRUE;
      debug("Successfully put pid=%d in the pid file '%s'.", pid, pidFile);
    }
    else
    {
      debugError("Couldn't create the pid file '%s' because the file could not be opened.", pidFile);
      returnValue = FALSE;
    }
  }
  else
  {
    debugError("Couldn't create the pid file because the pid file name could not be constructed.");
    returnValue = FALSE;
  }
  
@@ -246,7 +279,14 @@
  int curCmdInd = 0;
  int i = 0;
  BOOL overflow = FALSE;
  debug("Constructing full command line from arguments:");
  for (i = 0; (argv[i] != NULL); i++)
  {
    debug(" argv[%d]: %s", i, argv[i]);
  }
  
  i = 0;
  while ((argv[i] != NULL) && !overflow)
  {
    const char* curarg = argv[i++];
@@ -319,6 +359,15 @@
      }
    }
  }
  if (overflow)
  {
    debugError("Failed to construct the full commandline because the buffer wasn't big enough.");
  }
  else
  {
    debug("The full commandline is '%s'.", command);
  }
  
  return !overflow;
} // getCommandLine
@@ -350,7 +399,7 @@
  int childPid;
  
  char command[COMMAND_SIZE];
  if (getCommandLine(argv, command, COMMAND_SIZE))
  {
    childPid = spawn(command, TRUE);
@@ -362,11 +411,13 @@
    }
    else
    {
      debugError("Couldn't start the child process because the spawn failed.");
      returnValue = -1;
    }
  }
  else
  {
    debugError("Couldn't start the child process because the full command line could not be constructed.");
    returnValue = -1;
  }
  
@@ -401,6 +452,8 @@
  
  int childPid;
  
  debug("Attempting to stop the server running at root '%s'.", instanceDir);
  childPid = getPid(instanceDir);
  
  if (childPid != 0)
@@ -411,7 +464,11 @@
      deletePidFile(instanceDir);
    }
  }
  else
  {
    debug("Could not stop the server running at root '%s' because the pid could not be located.", instanceDir);
  }
  return returnCode;
} // stop
@@ -450,9 +507,18 @@
  if (getCommandLine(argv, command, COMMAND_SIZE))
  {
    returnValue = spawn(command, TRUE);
    if (returnValue <= 0)
    {
      debugError("Failed to launch the child process '%s'.", command);
    }
    else
    {
      debug("Successfully launched the child process '%s'.", command);
    }
  }
  else
  {
    debugError("Couldn't launch the child process because the full command line could not be constructed.");
    returnValue = -1;
  }
  
@@ -471,9 +537,25 @@
int main(int argc, char* argv[])
{
  int returnCode;
  char* subcommand = argv[1];
  char* instanceDir = argv[2];
  char* subcommand = NULL;
  char* instanceDir = NULL;
  int i;
  
  debug("main called.");
  for (i = 0; i < argc; i++) {
    debug("  argv[%d] = '%s'", i, argv[i]);
  }
  if (argc < 3) {
    char * msg = "Expected command line args of [subcommand] [server directory], but got %d arguments.\n";
    debugError(msg, argc - 1);
    fprintf(stderr, msg, argc - 1);
      return -1;
  }
  subcommand = argv[1];
  instanceDir = argv[2];
  argv += 3;
  
  if (strcmp(subcommand, "start") == 0)
@@ -490,9 +572,12 @@
  }
  else
  {
    fprintf(stderr, "Unknown subcommand: [%s]", subcommand);
    char * msg = "Unknown subcommand: [%s]\n";
    debugError(msg, argc - 1);
    fprintf(stderr, msg, subcommand);
    returnCode = -1;
  }
  debug("main finished. Returning %d", returnCode);
  return returnCode;
}
opends/src/build-tools/windows/winlauncher.h
@@ -25,11 +25,11 @@
*      Portions Copyright 2007 Sun Microsystems, Inc.
*/
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <process.h>
#include "common.h"
#define PATH_SIZE 1024
#define BUF_SIZE 1024