From 658c46ea8ef6d7022cb8c8e06565ebce12842d0b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 8 Oct 2014 23:08:16 +0300 Subject: [PATCH] Rewrite ExternalTask to use Msp::Process --- source/externaltask.cpp | 98 ++++++++++++++++++----------------------- source/externaltask.h | 5 ++- 2 files changed, 45 insertions(+), 58 deletions(-) diff --git a/source/externaltask.cpp b/source/externaltask.cpp index 643831e..3cc8eca 100644 --- a/source/externaltask.cpp +++ b/source/externaltask.cpp @@ -11,15 +11,18 @@ using namespace std; using namespace Msp; -ExternalTask::ExternalTask(const vector &a, const FS::Path &wd): +ExternalTask::ExternalTask(const Arguments &a, const FS::Path &wd): argv(a), work_dir(wd), - pid(-1), + process(0), exit_code(-1), stdout_dest(PASSTHROUGH), stderr_dest(PASSTHROUGH), capture_pipe(0) -{ } +{ + if(argv.empty()) + throw invalid_argument("ExternalTask::ExternalTask"); +} ExternalTask::~ExternalTask() { @@ -47,49 +50,39 @@ string ExternalTask::get_command() const void ExternalTask::start() { - if(stdout_dest==CAPTURE || stderr_dest==CAPTURE) - capture_pipe = new IO::Pipe; + IO::File *devnull = 0; prepare(); - if((pid = fork())) + process = new Process; + + if(stdout_dest==IGNORE || stderr_dest==IGNORE) { - if(pid==-1) - exit_code = 1026; - else - exit_code = 0; + devnull = new IO::File("/dev/null", IO::M_WRITE); + if(stdout_dest==IGNORE) + process->redirect_cout(*devnull); + if(stderr_dest==IGNORE) + process->redirect_cerr(*devnull); } - else + + if(stdout_dest==CAPTURE || stderr_dest==CAPTURE) { - vector cargv(argv.size()+1); - for(unsigned i=0; iredirect_cout(*capture_pipe); + if(stderr_dest==CAPTURE) + process->redirect_cerr(*capture_pipe); + } - if(stdout_dest==IGNORE || stderr_dest==IGNORE) - { - IO::File devnull("/dev/null", IO::M_WRITE); - if(stdout_dest==IGNORE) - IO::cout.redirect(devnull); - if(stderr_dest==IGNORE) - IO::cerr.redirect(devnull); - } + if(!work_dir.empty()) + process->set_working_directory(work_dir); - if(capture_pipe) - { - if(stdout_dest==CAPTURE) - IO::cout.redirect(*capture_pipe); - if(stderr_dest==CAPTURE) - IO::cerr.redirect(*capture_pipe); - delete capture_pipe; - } + Process::Arguments args(argv.begin()+1, argv.end()); + process->execute(argv.front(), args); + if(capture_pipe) + capture_pipe->set_mode(IO::M_READ); - if(!work_dir.empty()) - FS::chdir(work_dir); - execvp(cargv.front(), const_cast(&cargv.front())); - IO::print("Couldn't execute %s\n", argv.front()); - exit(1); - } + delete devnull; } Task::Status ExternalTask::check() @@ -104,34 +97,27 @@ Task::Status ExternalTask::wait() Task::Status ExternalTask::do_wait(bool block) { - if(pid>0) + if(process) { - int status; - if(waitpid(pid, &status, (block ? 0 : WNOHANG))==pid) + if(process->wait(block)) { - if(WIFEXITED(status)) - exit_code = WEXITSTATUS(status); - else if(WIFSIGNALED(status)) - exit_code = 256+WTERMSIG(status); - else - exit_code = 1025; - pid = 0; + exit_code = process->get_exit_code(); + delete process; + process = 0; } // Do this after waiting to avoid a race condition - if(capture_pipe) + while(capture_pipe && IO::poll(*capture_pipe, IO::P_INPUT, Time::zero)) { - while(IO::poll(*capture_pipe, IO::P_INPUT, Time::zero)) - { - char buf[1024]; - unsigned len = capture_pipe->read(buf, sizeof(buf)); + char buf[1024]; + unsigned len = capture_pipe->read(buf, sizeof(buf)); + if(len) output.append(buf, len); - if(len0) + if(process) return RUNNING; else signal_finished.emit(!exit_code); diff --git a/source/externaltask.h b/source/externaltask.h index cb8464b..992df5c 100644 --- a/source/externaltask.h +++ b/source/externaltask.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include "task.h" @@ -22,12 +23,12 @@ public: IGNORE //< Redirect the stream to oblivion }; - typedef std::vector Arguments; + typedef Msp::Process::Arguments Arguments; private: Arguments argv; Msp::FS::Path work_dir; - int pid; + Msp::Process *process; int exit_code; Destination stdout_dest; Destination stderr_dest; -- 2.45.2