From 34e1023596c61c4dfd6279cde1f97b318e04e3fd Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 1 Jan 2012 22:55:57 +0300 Subject: Add process execute functions. --- src/CMakeLists.txt | 2 + src/Makefile.am | 2 + src/utils/process.cpp | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/utils/process.h | 29 +++++++++ 4 files changed, 204 insertions(+) create mode 100644 src/utils/process.cpp create mode 100644 src/utils/process.h (limited to 'src') 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 . + */ + +#include "utils/process.h" + +#include +#include +#include + +#include + +#include "debug.h" + +#include "localconsts.h" + +const int timeOut = 10; + +#ifdef WIN32 + +#include + +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 +#include + +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 . + */ + +#ifndef UTILS_PROCESS_H +#define UTILS_PROCESS_H + +#include + +int execFile(std::string pathName, std::string name, + std::string arg1, std::string arg2, int waitTime = 0); + +#endif // UTILS_PROCESS_H -- cgit v1.2.3-60-g2f50