summaryrefslogtreecommitdiff
path: root/KPL_Start.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'KPL_Start.cpp')
-rw-r--r--KPL_Start.cpp114
1 files changed, 75 insertions, 39 deletions
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;