summaryrefslogtreecommitdiff
path: root/src/sysExec.cpp
diff options
context:
space:
mode:
authorMarkus Grüneis <gimpf@gimpf.org>2010-02-04 00:14:52 +0000
committerMarkus Grüneis <gimpf@gimpf.org>2010-02-04 00:14:52 +0000
commit7a0759d434d06305d7e602bd5debf9d01b92bbd1 (patch)
tree07ae46cbc86f4595ac6250b847fd3d60954e8d69 /src/sysExec.cpp
parentfixed build on windows (version.h) (diff)
win32 support for sysExec, sysExec.hpp arch-specific files introduced
Diffstat (limited to 'src/sysExec.cpp')
-rw-r--r--src/sysExec.cpp130
1 files changed, 7 insertions, 123 deletions
diff --git a/src/sysExec.cpp b/src/sysExec.cpp
index 07615e6..6e291d9 100644
--- a/src/sysExec.cpp
+++ b/src/sysExec.cpp
@@ -38,15 +38,13 @@
#include "log.h"
#include "anytunError.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include <sys/select.h>
-#include <stdlib.h>
-#include <string.h>
-#include <cstring>
+//use system specific signal handler
+#ifndef _MSC_VER
+#include "sysExec.hpp"
+#else
+ #include "win32/sysExec.hpp"
+#endif
+
SysExec::SysExec(std::string const& script) : script_(script),closed_(false),return_code_(0)
{
@@ -68,121 +66,7 @@ SysExec::SysExec(std::string const& script, StringVector const& args, StringList
doExec( script, args, env);
}
-SysExec::~SysExec()
-{
- if(!closed_)
- close(pipefd_);
-}
-
-void SysExec::doExec(std::string const& script, StringVector const& args, StringList const& env)
-{
- int pipefd[2];
- if(pipe(pipefd) == -1) {
- cLog.msg(Log::PRIO_ERROR) << "executing script '" << script << "' pipe() error: " << AnytunErrno(errno);
- return;
- }
-
- pid_ = fork();
- if(pid_ == -1) {
- cLog.msg(Log::PRIO_ERROR) << "executing script '" << script << "' fork() error: " << AnytunErrno(errno);
- return;
- }
-
- if(pid_) {
- close(pipefd[1]);
- pipefd_=pipefd[0];
- // parent exits here, call waitForScript to cleanup up zombie
- return;
- }
- // child code, exec the script
- int fd;
- for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors
- if(fd != pipefd[1]) close(fd);
-
- fd = open("/dev/null",O_RDWR); // stdin
- if(fd == -1)
- cLog.msg(Log::PRIO_WARNING) << "can't open stdin";
- else {
- if(dup(fd) == -1) // stdout
- cLog.msg(Log::PRIO_WARNING) << "can't open stdout";
- if(dup(fd) == -1) // stderr
- cLog.msg(Log::PRIO_WARNING) << "can't open stderr";
- }
-
- char** argv = new char*[args.size() + 2];
- argv[0] = new char[script.size() + 1];
- std::strcpy(argv[0], script.c_str());
- for(unsigned int i=0; i<args.size(); ++i) {
- argv[i+1] = new char[args[i].size() + 1];
- std::strcpy(argv[i+1], args[i].c_str());
- }
- argv[args.size() + 1] = NULL;
-
- char** evp;
- evp = new char*[env.size() + 1];
- unsigned int i = 0;
- for(StringList::const_iterator it = env.begin(); it != env.end(); ++it) {
- evp[i] = new char[it->size() + 1];
- std::strcpy(evp[i], it->c_str());
- ++i;
- }
- evp[env.size()] = NULL;
-
- execve(script.c_str(), argv, evp);
- // if execve returns, an error occurred, but logging doesn't work
- // because we closed all file descriptors, so just write errno to
- // pipe and call exit
- int err = errno;
- int ret = write(pipefd[1], (void*)(&err), sizeof(err));
- if(ret != sizeof(errno))
- exit(-2);
- exit(-1);
-}
-
-int SysExec::waitForScript()
-{
- int status = 0;
- waitpid(pid_, &status, 0);
-
- fd_set rfds;
- FD_ZERO(&rfds);
- FD_SET(pipefd_, &rfds);
- struct timeval tv = { 0 , 0 };
- if(select(pipefd_+1, &rfds, NULL, NULL, &tv) == 1) {
- int err = 0;
- if(read(pipefd_, (void*)(&err), sizeof(err)) >= static_cast<int>(sizeof(err))) {
- cLog.msg(Log::PRIO_NOTICE) << "script '" << script_ << "' exec() error: " << AnytunErrno(err);
- close(pipefd_);
- return_code_ = -1;
- return return_code_;
- }
- }
-
- close(pipefd_);
- closed_ = true;
- return_code_ = status;
-
- return return_code_;
-}
-
int SysExec::getReturnCode() const
{
return return_code_;
}
-
-void SysExec::waitAndDestroy(SysExec*& s)
-{
- if(!s)
- return;
-
- s->waitForScript();
- if(WIFEXITED(s->return_code_))
- cLog.msg(Log::PRIO_NOTICE) << "script '" << s->script_ << "' returned " << WEXITSTATUS(s->return_code_);
- else if(WIFSIGNALED(s->return_code_))
- cLog.msg(Log::PRIO_NOTICE) << "script '" << s->script_ << "' terminated after signal " << WTERMSIG(s->return_code_);
- else
- cLog.msg(Log::PRIO_ERROR) << "executing script '" << s->script_ << "': unknown error";
-
- delete(s);
- s = NULL;
-}