diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/modules/SystemBackendPosix/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/modules/SystemBackendPosix/SystemBackendPosix.cpp | 247 | ||||
-rw-r--r-- | src/modules/SystemBackendPosix/SystemBackendPosix.h | 43 |
3 files changed, 41 insertions, 254 deletions
diff --git a/src/modules/SystemBackendPosix/CMakeLists.txt b/src/modules/SystemBackendPosix/CMakeLists.txt new file mode 100644 index 0000000..02b0ef6 --- /dev/null +++ b/src/modules/SystemBackendPosix/CMakeLists.txt @@ -0,0 +1,5 @@ +include_directories(${INCLUDES}) + +add_library(SystemBackendPosix MODULE + SystemBackendPosix.cpp +) diff --git a/src/modules/SystemBackendPosix/SystemBackendPosix.cpp b/src/modules/SystemBackendPosix/SystemBackendPosix.cpp index 4969c6d..a215c86 100644 --- a/src/modules/SystemBackendPosix/SystemBackendPosix.cpp +++ b/src/modules/SystemBackendPosix/SystemBackendPosix.cpp @@ -19,57 +19,38 @@ #include "SystemBackendPosix.h" -#include <Net/FdManager.h> -#include <Common/ActionManager.h> +#include <Net/ThreadManager.h> -#include <cstdio> -#include <cstdlib> -#include <cstring> -#include <sstream> - -#include <fcntl.h> -#include <signal.h> -#include <spawn.h> -#include <sys/wait.h> -#include <unistd.h> - -#define init SystemBackendPosix_LTX_init -#define deinit SystemBackendPosix_LTX_deinit +#include <stdio.h> +#include <stdlib.h> namespace Mad { namespace Modules { -SystemBackendPosix *SystemBackendPosix::backend = 0; - -std::map<pid_t, boost::function1<void, int> > SystemBackendPosix::processes; -std::map<pid_t, boost::function2<void, int, const std::string&> > SystemBackendPosix::processesWithOutput; -std::map<pid_t, int> SystemBackendPosix::processesWOHandles; -std::map<pid_t, std::string > SystemBackendPosix::processesWOOutput; +boost::shared_ptr<SystemBackendPosix> SystemBackendPosix::backend; +bool SystemBackendPosix::getFSInfo(std::vector<Common::SystemManager::FSInfo> *fsInfo) { + Net::ThreadManager::get()->detach(); -void SystemBackendPosix::setChildHandler() { - struct sigaction action; + FILE *pipe = popen("/bin/df -P -k", "r"); + if(!pipe) + return false; - action.sa_handler = childHandler; - sigemptyset(&action.sa_mask); - action.sa_flags = 0; - - sigaction(SIGCHLD, &action, 0); -} + char buffer[1024]; + std::string output; -SystemBackendPosix::~SystemBackendPosix() { - struct sigaction action; + while(!feof(pipe)) { + if(fgets(buffer, sizeof(buffer), pipe) != 0) + output += buffer; + } - action.sa_handler = SIG_DFL; - sigemptyset(&action.sa_mask); - action.sa_flags = 0; + pclose(pipe); - sigaction(SIGCHLD, &action, 0); -} + if(!fsInfo) + return true; + fsInfo->clear(); -void SystemBackendPosix::fsInfoCallback(int, const std::string &output, const boost::function1<void, const std::vector<Common::SystemManager::FSInfo>& > &callback) { - std::vector<Common::SystemManager::FSInfo> ret; std::istringstream stream(output); std::string str; @@ -87,210 +68,40 @@ void SystemBackendPosix::fsInfoCallback(int, const std::string &output, const bo info.fsName = fsName; info.mountedOn = mountedOn; - ret.push_back(info); + fsInfo->push_back(info); } delete [] fsName; delete [] mountedOn; } - callback(ret); -} - -bool SystemBackendPosix::getFSInfo(const boost::function1<void, const std::vector<Common::SystemManager::FSInfo>& > &callback) { - std::vector<std::string> argv; - - argv.push_back("/bin/df"); - argv.push_back("-P"); - argv.push_back("-k"); - - return execWithOutput(boost::bind(&SystemBackendPosix::fsInfoCallback, this, _1, _2, callback), "/bin/df", argv); -} - - -void SystemBackendPosix::childHandler(int) { - int status; - pid_t pid; - - while((pid = waitpid(-1, &status, WNOHANG)) > 0) { - std::map<pid_t, boost::function1<void, int> >::iterator it = processes.find(pid); - - if(it != processes.end()) { - Common::ActionManager::get()->add(boost::bind(it->second, status)); - processes.erase(it); - } - else { - std::map<pid_t, boost::function2<void, int, const std::string&> >::iterator it2 = processesWithOutput.find(pid); - - if(it2 != processesWithOutput.end()) { - char buffer[1024]; - ssize_t n; - std::string &output = processesWOOutput[pid]; - int handle = processesWOHandles[pid]; - - while((n = read(handle, buffer, sizeof(buffer))) > 0) - output += std::string(buffer, n); - - //Net::FdManager::get()->unregisterFd(handle); - //close(handle); - - //Common::ActionManager::get()->add(boost::bind(it2->second, status, output)); - processesWithOutput.erase(it2); - processesWOHandles.erase(pid); - processesWOOutput.erase(pid); - } - } - } - - setChildHandler(); -} - -void SystemBackendPosix::outputHandler(short events, pid_t pid) { - char buf[1024]; - - if(events & POLLIN) { - sigset_t set, oldset; - sigemptyset(&set); - sigaddset(&set, SIGCHLD); - sigprocmask(SIG_BLOCK, &set, &oldset); - - ssize_t ret; - - std::map<pid_t, int>::iterator handle = processesWOHandles.find(pid); - if(handle == processesWOHandles.end()) - return; - - while((ret = read(handle->second, buf, sizeof(buf))) > 0) - processesWOOutput[pid] += std::string(buf, ret); - - sigprocmask(SIG_SETMASK, &oldset, 0); - } + return true; } -std::pair<char**, char**> SystemBackendPosix::makeArgs(const std::string &filename, const std::vector<std::string> &argv, const std::vector<std::string> &env) { - char **argvp, **envp; - - if(argv.empty()) { - argvp = new char*[2]; - - argvp[0] = strdup(filename.c_str()); - argvp[1] = 0; - } - else { - argvp = new char*[argv.size() + 1]; - - for(size_t s = 0; s < argv.size(); ++s) { - argvp[s] = strdup(argv[s].c_str()); - } - - argvp[argv.size()] = 0; - } - - if(env.empty()) { - envp = environ; - } - else { - envp = new char*[env.size() + 1]; - - for(size_t s = 0; s < env.size(); ++s) { - envp[0] = strdup(env[s].c_str()); - } - - envp[env.size()] = 0; - } +bool SystemBackendPosix::shutdown() { + Net::ThreadManager::get()->detach(); - return std::make_pair(argvp, envp); + return (system("/sbin/halt") == 0); } -void SystemBackendPosix::destroyArgs(std::pair<char**, char**> args) { - for(char **p = args.first; *p != 0; ++p) - std::free(*p); +bool SystemBackendPosix::reboot() { + Net::ThreadManager::get()->detach(); - delete [] args.first; - - if(args.second != environ) { - for(char **p = args.second; *p != 0; ++p) - std::free(*p); - - delete [] args.second; - } + return (system("/sbin/reboot") == 0); } -bool SystemBackendPosix::exec(const boost::function1<void, int> &resultHandler, const std::string &filename, const std::vector<std::string> &argv, const std::vector<std::string> &env) { - pid_t pid; - std::pair<char**, char**> args = makeArgs(filename, argv, env); - - sigset_t set, oldset; - sigemptyset(&set); - sigaddset(&set, SIGCHLD); - sigprocmask(SIG_BLOCK, &set, &oldset); - - bool ret = (posix_spawnp(&pid, filename.c_str(), 0, 0, args.first, args.second) == 0); - - if(ret) - processes.insert(std::make_pair(pid, resultHandler)); - - sigprocmask(SIG_SETMASK, &oldset, 0); - - destroyArgs(args); - - return ret; } - -bool SystemBackendPosix::execWithOutput(const boost::function2<void, int, const std::string&> &resultHandler, const std::string &filename, const std::vector<std::string> &argv, const std::vector<std::string> &env) { - pid_t pid; - std::pair<char**, char**> args = makeArgs(filename, argv, env); - - int saveStdout = dup(STDOUT_FILENO); - int pipeHandles[2]; - - pipe(pipeHandles); - - fcntl(pipeHandles[0], F_SETFD, FD_CLOEXEC); - - int flags = fcntl(pipeHandles[0], F_GETFL, 0); - fcntl(pipeHandles[0], F_SETFL, flags | O_NONBLOCK); - - sigset_t set, oldset; - sigemptyset(&set); - sigaddset(&set, SIGCHLD); - sigprocmask(SIG_BLOCK, &set, &oldset); - - dup2(pipeHandles[1], STDOUT_FILENO); // set the new pipe as stdout - close(pipeHandles[1]); - - bool ret = (posix_spawnp(&pid, filename.c_str(), 0, 0, args.first, args.second) == 0); - - if(ret) { - processesWithOutput.insert(std::make_pair(pid, resultHandler)); - processesWOHandles.insert(std::make_pair(pid, pipeHandles[0])); - processesWOOutput.insert(std::make_pair(pid, std::string())); - - Net::FdManager::get()->registerFd(pipeHandles[0], boost::bind(&SystemBackendPosix::outputHandler, _1, pid), POLLIN); - } - - dup2(saveStdout, STDOUT_FILENO); // restore old stdout - close(saveStdout); - - sigprocmask(SIG_SETMASK, &oldset, 0); - - destroyArgs(args); - - return ret; } -} -} extern "C" { -void init() { +void SystemBackendPosix_init() { Mad::Modules::SystemBackendPosix::registerBackend(); } -void deinit() { +void SystemBackendPosix_deinit() { Mad::Modules::SystemBackendPosix::unregisterBackend(); } } - diff --git a/src/modules/SystemBackendPosix/SystemBackendPosix.h b/src/modules/SystemBackendPosix/SystemBackendPosix.h index 6d9b65f..2ec026d 100644 --- a/src/modules/SystemBackendPosix/SystemBackendPosix.h +++ b/src/modules/SystemBackendPosix/SystemBackendPosix.h @@ -33,37 +33,15 @@ namespace Mad { namespace Modules { -// TODO SystemBackendPosix doesn't work !!! - -class SystemBackendPosix : private Common::SystemBackend { +class SystemBackendPosix : public Common::SystemBackend { private: - static SystemBackendPosix *backend; - static std::map<pid_t, boost::function1<void, int> > processes; - - static std::map<pid_t, boost::function2<void, int, const std::string&> > processesWithOutput; - static std::map<pid_t, int> processesWOHandles; - static std::map<pid_t, std::string > processesWOOutput; - - static void setChildHandler(); - - static void childHandler(int); - - static void outputHandler(short events, pid_t pid); - - static std::pair<char**, char**> makeArgs(const std::string &filename, const std::vector<std::string> &argv, const std::vector<std::string> &env); - static void destroyArgs(std::pair<char**, char**> args); - - SystemBackendPosix() { - setChildHandler(); - } - - void fsInfoCallback(int, const std::string &output, const boost::function1<void, const std::vector<Common::SystemManager::FSInfo>& > &callback); + static boost::shared_ptr<SystemBackendPosix> backend; protected: - virtual bool getFSInfo(const boost::function1<void, const std::vector<Common::SystemManager::FSInfo>& > &callback); + virtual bool getFSInfo(std::vector<Common::SystemManager::FSInfo> *fsInfo); - virtual bool shutdown(const boost::function0<void> &callback) {return exec(boost::bind(callback), "/sbin/halt");} - virtual bool reboot(const boost::function0<void> &callback) {return exec(boost::bind(callback), "/sbin/reboot");} + virtual bool shutdown(); + virtual bool reboot(); public: ~SystemBackendPosix(); @@ -72,7 +50,7 @@ class SystemBackendPosix : private Common::SystemBackend { if(backend) return; - backend = new SystemBackendPosix(); + backend.reset(new SystemBackendPosix()); Common::SystemManager::get()->registerBackend(backend); } @@ -81,15 +59,8 @@ class SystemBackendPosix : private Common::SystemBackend { return; Common::SystemManager::get()->unregisterBackend(backend); - delete backend; - backend = 0; + backend.reset(); } - - static bool exec(const boost::function1<void, int> &resultHandler, const std::string &filename, const std::vector<std::string> &argv = std::vector<std::string>(), - const std::vector<std::string> &env = std::vector<std::string>()); - - static bool execWithOutput(const boost::function2<void, int, const std::string&> &resultHandler, const std::string &filename, const std::vector<std::string> &argv = std::vector<std::string>(), - const std::vector<std::string> &env = std::vector<std::string>()); }; } |