diff options
author | Andrei Karas <akaras@inbox.ru> | 2012-01-01 22:55:57 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2012-01-04 20:43:13 +0300 |
commit | 34e1023596c61c4dfd6279cde1f97b318e04e3fd (patch) | |
tree | 4e9598d97fa4d8cd90003bd7f5d306e44b488305 /src/utils/process.cpp | |
parent | e2b133ffa97e0bf4c3bf44099705ca671d787c4c (diff) | |
download | manaverse-34e1023596c61c4dfd6279cde1f97b318e04e3fd.tar.gz manaverse-34e1023596c61c4dfd6279cde1f97b318e04e3fd.tar.bz2 manaverse-34e1023596c61c4dfd6279cde1f97b318e04e3fd.tar.xz manaverse-34e1023596c61c4dfd6279cde1f97b318e04e3fd.zip |
Add process execute functions.
Diffstat (limited to 'src/utils/process.cpp')
-rw-r--r-- | src/utils/process.cpp | 171 |
1 files changed, 171 insertions, 0 deletions
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 |