diff options
| -rw-r--r-- | KPLFillModSpecific.cpp | 10 | ||||
| -rw-r--r-- | KPL_Start.cpp | 114 | ||||
| -rw-r--r-- | KPL_Start.h | 23 | 
3 files changed, 97 insertions, 50 deletions
| diff --git a/KPLFillModSpecific.cpp b/KPLFillModSpecific.cpp index 6937bd6..4672228 100644 --- a/KPLFillModSpecific.cpp +++ b/KPLFillModSpecific.cpp @@ -10,10 +10,16 @@ int nbrKPmaps=8;  int nbrKPfactions=3;
  const char* cKPgame::ModFileName="Kernel_Panic_3.2.sd7\x00PaddingPaddingPaddingPadding";
 -const char* cKPgame::ScriptFileName="Kernel_Panic_script.txt\x00PaddingPaddingPaddingPadding";
 +const char* cKPgame::ScriptFileName="Kernel_Panic_script.txt\x00PaddingPaddingPaddingPadding"; +#ifdef __WIN32__
  const char* cKPgame::ExecutableFileName="spring.exe\x00PaddingPaddingPaddingPadding";
  const char* cKPgame::ClientExecutableFileName="KPSClient.exe\x00PaddingPaddingPaddingPadding";
 -const char* cKPgame::SettingsExecutableFileName="springsettings.exe\x00PaddingPaddingPaddingPadding";
 +const char* cKPgame::SettingsExecutableFileName="springsettings.exe\x00PaddingPaddingPaddingPadding"; +#else +const char* cKPgame::ExecutableFileName="spring";
 +const char* cKPgame::ClientExecutableFileName="KPSClient";
 +const char* cKPgame::SettingsExecutableFileName="springsettings"; +#endif
  //---------------------------------------------------------------------------
 diff --git a/KPL_Start.cpp b/KPL_Start.cpp index ac001c3..5bc46fd 100644 --- a/KPL_Start.cpp +++ b/KPL_Start.cpp @@ -3,30 +3,65 @@  #include "KPLTypes.h"
  #include "KPLFillModSpecific.h"
  #include "WriteScript.h"
 -#include "GenerateScript.h"
 +#include "GenerateScript.h" +#ifndef __WIN32__ +    #include <string.h>
    #include <stdio.h> +#endif
  #ifdef __WIN32__
      #include "process.h"// For spawnlp
      #include <windows.h>
      #pragma package(smart_init)
 -    DWORD ProcessID=0;
 +    static DWORD processID=0;  #else
      #include <unistd.h>
 -    #include <stdlib.h>
 +    #include <stdlib.h>      #include <sys/types.h>
      #include <sys/wait.h>
 -    pid_t ProcessID=0;
      #define P_NOWAIT 0
 +    static pid_t processID=0;      static int spawnl(int flg, const char* file, const char* name, const char* arg1, const char* arg2) {
      	int pid = fork();
  	    if (pid == 0) {
  		    // We are in the son
 -    		execl(file, name, arg1, arg2, NULL);
 +    		execlp(file, name, arg1, arg2, NULL); +    		perror("execlp");
  	    	exit(1);
      	}
  	    return pid;
      }
  #endif
 + +/* + * Wait()s without blocking to cleanup exited children processes. + * Returns: + *   -1 for error + *   0 for no running children + *   1 for running children + */ +static int cleanupWait() { +    if (!processID) +        return 0; +    #ifdef __WIN32__
 +        HANDLE ProcessHandle;
 +        ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION,false,processID);
 +        if(ProcessHandle!=NULL) {
 +            // Spring is already running
 +            return 1;
 +        }
 +    #else +        pid_t termedProc = waitpid(processID, NULL, WNOHANG); +        if (termedProc == -1) { +            perror("waitpid"); +            return -1; +        }
 +        if (termedProc == 0) {
            // Spring is already running
 +            return 1;
 +        } +        processID = 0; +    #endif +    return 0; +}  int StartSpectator(void*)
  {
 @@ -54,35 +89,26 @@ int StartVeryHard(void*)  }
  int StartMultiPlayer(void*)
 -{
 -    ProcessID=spawnl(P_NOWAIT,cKPgame::ClientExecutableFileName,cKPgame::ClientExecutableFileName,"",NULL);
 +{ +    if (cleanupWait() != 0) +        return 1;
 +    processID=spawnl(P_NOWAIT,cKPgame::ClientExecutableFileName,cKPgame::ClientExecutableFileName,"",NULL);
      return 0;
  }
  int StartSettings(void*)
  {
 -    ProcessID=spawnl(P_NOWAIT,cKPgame::SettingsExecutableFileName,cKPgame::SettingsExecutableFileName,"",NULL);
 +    if (cleanupWait() != 0) +        return 1;
 +    processID=spawnl(P_NOWAIT,cKPgame::SettingsExecutableFileName,cKPgame::SettingsExecutableFileName,"",NULL);
      return 0;
  }
  int LaunchSpringExecutable(int Difficulty)
  {
 -
 -    // Check that Spring isn't already running
 -    #ifdef __WIN32__
 -        HANDLE ProcessHandle;
 -        ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION,false,ProcessID);
 -        if(ProcessHandle!=NULL)
 -        {
 -            // Spring is already running
 -            return 2;
 -        }
 -    #else
 -	    if (waitpid(ProcessID, NULL, WNOHANG) >= 0) {
 -		    // Spring is already running
 -            return 2;
 -        }
 -    #endif
 +    // Check that Spring isn't already running +    if (cleanupWait() != 0) +        return 2;
      KPLFillModSpecific();
 @@ -101,26 +127,36 @@ int LaunchSpringExecutable(int Difficulty)      #ifdef __WIN32__
          Sleep(500);
 -    #else
 -        sleep(1);
      #endif
 + +    free(game->ModOptions);
 +    for(int p=0;p<32;++p)
 +        free(game->players[p]);
 +    free(game->players);
 +    free(game);
 + +    const char *scriptName = game->ScriptFileName; +#ifndef __WIN32__ +    char fullName[256]; +    if (getcwd(fullName, sizeof(fullName) - strlen(game->ExecutableFileName) - 1) == NULL) { +        fprintf(stderr, "Current working directory too large\n"); +        return 1; +    } +    strcat(fullName, "/"); +    strcat(fullName, game->ScriptFileName); +    scriptName = fullName; +#endif      // Running Spring
      //ShellExecute(NULL,"open",game->ExecutableFileName,game->ScriptFileName,NULL,SW_SHOWNORMAL);
 -    ProcessID=spawnl(P_NOWAIT,cKPgame::ExecutableFileName,game->ExecutableFileName,game->ScriptFileName,NULL);
 -
 +    processID=spawnl(P_NOWAIT,cKPgame::ExecutableFileName,game->ExecutableFileName,scriptName,NULL);
 +      // Check that Spring has run
 -    #ifdef __WIN32__
 -        ProcessHandle=OpenProcess(PROCESS_QUERY_INFORMATION,false,ProcessID);
 -        if(ProcessHandle==NULL)
 -        {
 -            return 1;
 -        }
 -    #else
 -	    if (waitpid(ProcessID, NULL, WNOHANG) < 0) {
 -            return 1;
 -        }
 -    #endif
 +    if (processID == -1) { +        perror("spawnl"); +        processID = 0; +        return 1; +    }
      //Application->Terminate();
      return 0;
 diff --git a/KPL_Start.h b/KPL_Start.h index 8c19a6f..1db2cf7 100644 --- a/KPL_Start.h +++ b/KPL_Start.h @@ -6,14 +6,19 @@  #define __declspec(x)
  #endif
  //---------------------------------------------------------------------------
 -extern "C" __declspec(dllexport) int StartSpectator(void*);
 -extern "C" __declspec(dllexport) int StartEasy(void*);
 -extern "C" __declspec(dllexport) int StartMedium(void*);
 -extern "C" __declspec(dllexport) int StartHard(void*);
 -extern "C" __declspec(dllexport) int StartVeryHard(void*);
 -extern "C" __declspec(dllexport) int StartMultiPlayer(void*);
 -extern "C" __declspec(dllexport) int StartSettings(void*);
 -extern "C" __declspec(dllexport) int LaunchSpringExecutable(int Difficulty);
 -
 +#ifdef __cplusplus +extern "C" { +#endif +	__declspec(dllexport) int StartSpectator(void*);
 +	__declspec(dllexport) int StartEasy(void*);
 +	__declspec(dllexport) int StartMedium(void*);
 +	__declspec(dllexport) int StartHard(void*);
 +	__declspec(dllexport) int StartVeryHard(void*);
 +	__declspec(dllexport) int StartMultiPlayer(void*);
 +	__declspec(dllexport) int StartSettings(void*);
 +	__declspec(dllexport) int LaunchSpringExecutable(int Difficulty);
 +#ifdef __cplusplus +} +#endif
  //---------------------------------------------------------------------------
  #endif
 | 
