X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fexternaltask.cpp;h=f7ab199b417121712ef3d9a408a58565cc6961d8;hb=HEAD;hp=fea331a72207004e14acd85b5ebfb94fb910a840;hpb=06678c3bb61404c483e4b9c39eaa7e7fb3f40c62;p=builder.git diff --git a/source/externaltask.cpp b/source/externaltask.cpp deleted file mode 100644 index fea331a..0000000 --- a/source/externaltask.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "externaltask.h" - -using namespace std; -using namespace Msp; - -ExternalTask::ExternalTask(const vector &a, const FS::Path &wd): - argv(a), - work_dir(wd), - pid(-1), - exit_code(-1), - stdout_dest(PASSTHROUGH), - stderr_dest(PASSTHROUGH), - capture_pipe(0) -{ } - -ExternalTask::~ExternalTask() -{ - delete capture_pipe; -} - -string ExternalTask::get_command() const -{ - string cmd; - for(vector::const_iterator i=argv.begin(); i!=argv.end(); ++i) - { - if(i!=argv.begin()) - cmd += ' '; - - for(string::const_iterator j=i->begin(); j!=i->end(); ++j) - { - if(*j=='"' || *j=='\'' || *j==' ' || *j=='\\' || *j=='&') - cmd += '\\'; - cmd += *j; - } - } - - return cmd; -} - -void ExternalTask::start() -{ - if(stdout_dest==CAPTURE || stderr_dest==CAPTURE) - capture_pipe = new IO::Pipe; - - if((pid = fork())) - { - if(pid==-1) - exit_code = 1026; - else - exit_code = 0; - } - else - { - vector cargv(argv.size()+1); - for(unsigned i=0; i(&cargv.front())); - IO::print("Couldn't execute %s\n", argv.front()); - exit(1); - } -} - -Task::Status ExternalTask::check() -{ - if(pid>0) - { - // XXX This is sub-optimal, should have support for a blocking wait - int status; - if(waitpid(pid, &status, WNOHANG)==pid) - { - if(WIFEXITED(status)) - exit_code = WEXITSTATUS(status); - else if(WIFSIGNALED(status)) - exit_code = 256+WTERMSIG(status); - else - exit_code = 1025; - pid = 0; - } - - // Do this after waiting to avoid a race condition - if(capture_pipe) - { - while(IO::poll(*capture_pipe, IO::P_INPUT, Time::zero)) - { - char buf[1024]; - unsigned len = capture_pipe->read(buf, sizeof(buf)); - output.append(buf, len); - if(len0) - return RUNNING; - else - signal_finished.emit(!exit_code); - } - - return exit_code ? ERROR : SUCCESS; -} - -void ExternalTask::set_stdout(Destination d) -{ - stdout_dest = d; -} - -void ExternalTask::set_stderr(Destination d) -{ - stderr_dest = d; -} - -string ExternalTask::run_and_capture_output(const Arguments &argv, const FS::Path &wd) -{ - ExternalTask task(argv, wd); - task.set_stdout(CAPTURE); - task.set_stderr(IGNORE); - task.start(); - Task::Status status; - while((status=task.check())==RUNNING) ; - if(status!=SUCCESS) - throw runtime_error(format("%s failed", argv.front())); - return task.get_output(); -}