diff options
-rw-r--r-- | manaplus.cbp | 2 | ||||
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/utils/process.cpp | 171 | ||||
-rw-r--r-- | src/utils/process.h | 29 |
5 files changed, 206 insertions, 0 deletions
diff --git a/manaplus.cbp b/manaplus.cbp index c888239c3..87be5de7a 100644 --- a/manaplus.cbp +++ b/manaplus.cbp @@ -670,6 +670,8 @@ <Unit filename="src\utils\mutex.h" />
<Unit filename="src\utils\paths.cpp" />
<Unit filename="src\utils\paths.h" />
+ <Unit filename="src\utils\process.cpp" />
+ <Unit filename="src\utils\process.h" />
<Unit filename="src\utils\sha256.cpp" />
<Unit filename="src\utils\sha256.h" />
<Unit filename="src\utils\specialfolder.cpp" />
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7ec0c8a19..b7005b144 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -450,6 +450,8 @@ SET(SRCS utils/mathutils.h utils/paths.cpp utils/paths.h + utils/process.cpp + utils/process.h utils/stringutils.cpp utils/stringutils.h utils/mutex.h diff --git a/src/Makefile.am b/src/Makefile.am index c1db3e92b..527893598 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -457,6 +457,8 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \ utils/mkdir.h \ utils/paths.cpp \ utils/paths.h \ + utils/process.cpp \ + utils/process.h \ utils/specialfolder.cpp \ utils/specialfolder.h \ utils/stringutils.cpp \ diff --git a/src/utils/process.cpp b/src/utils/process.cpp new file mode 100644 index 000000000..94967f8cc --- /dev/null +++ b/src/utils/process.cpp @@ -0,0 +1,171 @@ +/* + * The ManaPlus Client + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "utils/process.h" + +#include <string.h> +#include <cstdarg> +#include <cstdio> + +#include <stdlib.h> + +#include "debug.h" + +#include "localconsts.h" + +const int timeOut = 10; + +#ifdef WIN32 + +#include <windows.h> + +int execFile(std::string pathName, std::string name, + std::string arg1, std::string arg2, int waitTime) +{ + if (!waitTime) + waitTime = timeOut; + + STARTUPINFO siStartupInfo; + PROCESS_INFORMATION piProcessInfo; + memset(&siStartupInfo, 0, sizeof(siStartupInfo)); + memset(&piProcessInfo, 0, sizeof(piProcessInfo)); + siStartupInfo.cb = sizeof(siStartupInfo); + DWORD ret = -1; + std::string args(pathName + " " + arg1); + if (!arg2.empty()) + args += " " + arg2; + + if (CreateProcess(pathName.c_str(), (char*)args.c_str(), 0, 0, false, + CREATE_DEFAULT_ERROR_MODE, 0, 0, &siStartupInfo, + &piProcessInfo) != false) + { + if (!WaitForSingleObject(piProcessInfo.hProcess, timeOut * 1000)) + { + if (GetExitCodeProcess(piProcessInfo.hProcess, &ret)) + { + CloseHandle(piProcessInfo.hProcess); + CloseHandle(piProcessInfo.hThread); + return ret; + } + } + TerminateProcess(piProcessInfo.hProcess, -1); + } + + CloseHandle(piProcessInfo.hProcess); + CloseHandle(piProcessInfo.hThread); + return -1; +} + +#elif defined(__APPLE__) + +int execFile(std::string pathName, std::string name, + std::string arg1, std::string arg2, int waitTime) +{ + return -1; +} + +#elif defined __linux__ || defined __linux + +#include <sys/types.h> +#include <sys/wait.h> + +int execFile(std::string pathName, std::string name, + std::string arg1, std::string arg2, int waitTime) +{ + pid_t mon_pid; + int status; + + if (!waitTime) + waitTime = timeOut; + + if ((mon_pid = fork()) == -1) + { // fork error + return -1; + } + else if (!mon_pid) + { // monitoring child + pid_t pid; + if ((pid = fork()) == -1) + { // fork error + return -1; + } + else if (!pid) + { // work child + if (arg2.empty()) + { + execl(pathName.c_str(), name.c_str(), + arg1.c_str(), (char *)nullptr); + } + else + { + execl(pathName.c_str(), name.c_str(), + arg1.c_str(), arg2.c_str(), (char *)nullptr); + } + exit(0); + } + + // monitoring process + pid_t sleep_pid; + if ((sleep_pid = fork()) == -1) + { // fork error + return -1; + } + else if (!sleep_pid) + { // sleep pid + sleep (timeOut); +// printf ("time out\n"); + exit(-1); + } + + // monitoring process + pid_t exited_pid = wait(&status); + int ret = -1; + if (exited_pid == pid) + { + kill(sleep_pid, SIGKILL); + if (WIFEXITED(status)) + ret = WEXITSTATUS(status); + } + else + { + kill(pid, SIGKILL); + ret = -1; + } + wait(nullptr); + exit(ret); + } + + // monitoring parent + waitpid(mon_pid, &status, 0); + if (WIFEXITED(status)) + return WEXITSTATUS(status); + + return -1; +} + +#else + +int execFile(std::string pathName, std::string name, + std::string arg1, std::string arg2, int waitTime) +{ + return -1; +} + +#endif diff --git a/src/utils/process.h b/src/utils/process.h new file mode 100644 index 000000000..27a73ba20 --- /dev/null +++ b/src/utils/process.h @@ -0,0 +1,29 @@ +/* + * The ManaPlus Client + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef UTILS_PROCESS_H +#define UTILS_PROCESS_H + +#include <string> + +int execFile(std::string pathName, std::string name, + std::string arg1, std::string arg2, int waitTime = 0); + +#endif // UTILS_PROCESS_H |