From fa0a978ae129f0f04b9d336e9a3d71489fe519e8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 11 Oct 2008 22:32:32 +0200 Subject: Benutzte den FdManager f?r Ausgaben von Programmen im Posix-Backend --- src/Common/Backends/SystemBackendPosix.cpp | 57 ++++++++++++++++++++++++------ src/Common/Backends/SystemBackendPosix.h | 7 +++- src/Net/FdManager.cpp | 2 ++ 3 files changed, 55 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Common/Backends/SystemBackendPosix.cpp b/src/Common/Backends/SystemBackendPosix.cpp index 267e82e..62067c2 100644 --- a/src/Common/Backends/SystemBackendPosix.cpp +++ b/src/Common/Backends/SystemBackendPosix.cpp @@ -18,6 +18,7 @@ */ #include "SystemBackendPosix.h" +#include #include #include @@ -39,7 +40,9 @@ namespace Backends { SystemBackendPosix SystemBackendPosix::backend; std::map > SystemBackendPosix::processes; -std::map, int> > SystemBackendPosix::processesWithOutput; +std::map > SystemBackendPosix::processesWithOutput; +std::map SystemBackendPosix::processesWOHandles; +std::map SystemBackendPosix::processesWOOutput; void SystemBackendPosix::setChildHandler() { @@ -117,20 +120,24 @@ void SystemBackendPosix::childHandler(int) { processes.erase(it); } else { - std::map, int> >::iterator it2 = processesWithOutput.find(pid); + std::map >::iterator it2 = processesWithOutput.find(pid); if(it2 != processesWithOutput.end()) { char buffer[1024]; ssize_t n; - std::string output; + std::string &output = processesWOOutput[pid]; + int handle = processesWOHandles[pid]; - while((n = read(it2->second.second, buffer, sizeof(buffer))) > 0) + while((n = read(handle, buffer, sizeof(buffer))) > 0) output += std::string(buffer, n); - close(it2->second.second); + Net::FdManager::getFdManager()->unregisterFd(handle); + close(handle); - it2->second.first(status, output); + it2->second(status, output); processesWithOutput.erase(it2); + processesWOHandles.erase(pid); + processesWOOutput.erase(pid); } } } @@ -138,6 +145,28 @@ void SystemBackendPosix::childHandler(int) { 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::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); + } +} + std::pair SystemBackendPosix::makeArgs(const std::string &filename, const std::vector &argv, const std::vector &env) { char **argvp, **envp; @@ -215,10 +244,13 @@ bool SystemBackendPosix::execWithOutput(const sigc::slotregisterFd(pipeHandles[0], sigc::bind(sigc::ptr_fun(&SystemBackendPosix::outputHandler), pid), POLLIN); + } dup2(saveStdout, STDOUT_FILENO); // restore old stdout close(saveStdout); diff --git a/src/Common/Backends/SystemBackendPosix.h b/src/Common/Backends/SystemBackendPosix.h index b7f364a..59dd2d8 100644 --- a/src/Common/Backends/SystemBackendPosix.h +++ b/src/Common/Backends/SystemBackendPosix.h @@ -38,12 +38,17 @@ class SystemBackendPosix : public SystemBackend { private: static SystemBackendPosix backend; static std::map > processes; - static std::map, int> > processesWithOutput; + + static std::map > processesWithOutput; + static std::map processesWOHandles; + static std::map processesWOOutput; static void setChildHandler(); static void childHandler(int); + static void outputHandler(short events, pid_t pid); + static std::pair makeArgs(const std::string &filename, const std::vector &argv, const std::vector &env); static void destroyArgs(std::pair args); diff --git a/src/Net/FdManager.cpp b/src/Net/FdManager.cpp index f58a32e..5ff6647 100644 --- a/src/Net/FdManager.cpp +++ b/src/Net/FdManager.cpp @@ -100,6 +100,8 @@ void FdManager::interrupt() { } void FdManager::run() { + readInterrupt(); + size_t count = pollfds.size(); struct pollfd *fdarray = new struct pollfd[count]; -- cgit v1.2.3