X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fexternaltask.cpp;h=e4dfdc2ef9566122042d6ad430595acb1488f6b0;hb=HEAD;hp=33ffcebc4622889eaed085e371cc19fbb8a348df;hpb=7c2db9e2b91da953701be233336c5bfa1f3c4af0;p=builder.git diff --git a/source/externaltask.cpp b/source/externaltask.cpp deleted file mode 100644 index 33ffceb..0000000 --- a/source/externaltask.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "externaltask.h" - -using namespace std; -using namespace Msp; - -ExternalTask::ExternalTask(const Arguments &a, const FS::Path &wd): - argv(a), - work_dir(wd), - process(0), - exit_code(-1), - stdin_action(PASSTHROUGH), - stdout_action(PASSTHROUGH), - stderr_action(PASSTHROUGH), - capture_pipe(0) -{ - if(argv.empty()) - throw invalid_argument("ExternalTask::ExternalTask"); -} - -ExternalTask::~ExternalTask() -{ - delete capture_pipe; -} - -string ExternalTask::get_command() const -{ - string cmd; - for(const string &a: argv) - { - if(!cmd.empty()) - cmd += ' '; - - for(char c: a) - { - if(c=='"' || c=='\'' || c==' ' || c=='\\' || c=='&') - cmd += '\\'; - cmd += c; - } - } - - if(stdin_action==REDIRECT) - { - cmd += " <"; - cmd += stdin_file.str(); - } - - if(stdout_action==REDIRECT) - { - cmd += " >"; - cmd += stdout_file.str(); - } - - return cmd; -} - -void ExternalTask::start() -{ - IO::File *devnull = 0; - IO::File *infile = 0; - IO::File *outfile = 0; - - prepare(); - - process = new Process; - - if(stdin_action==IGNORE || stdout_action==IGNORE || stderr_action==IGNORE) - { -#ifdef _WIN32 - devnull = new IO::File("nul", IO::M_RDWR); -#else - devnull = new IO::File("/dev/null", IO::M_RDWR); -#endif - if(stdin_action==IGNORE) - process->redirect_cin(*devnull); - if(stdout_action==IGNORE) - process->redirect_cout(*devnull); - if(stderr_action==IGNORE) - process->redirect_cerr(*devnull); - } - - if(stdout_action==REDIRECT) - { - outfile = new IO::File((work_dir/stdout_file).str(), IO::M_WRITE); - process->redirect_cout(*outfile); - } - - if(stdout_action==CAPTURE || stderr_action==CAPTURE) - { - capture_pipe = new IO::Pipe; - if(stdout_action==CAPTURE) - process->redirect_cout(*capture_pipe); - if(stderr_action==CAPTURE) - process->redirect_cerr(*capture_pipe); - } - - if(stdin_action==REDIRECT) - { - infile = new IO::File((work_dir/stdin_file).str()); - process->redirect_cin(*infile); - } - - if(!work_dir.empty()) - process->set_working_directory(work_dir); - - Process::Arguments args(argv.begin()+1, argv.end()); - process->execute(argv.front(), args); - if(capture_pipe) - capture_pipe->set_mode(IO::M_READ); - - delete devnull; - delete infile; - delete outfile; -} - -Task::Status ExternalTask::check() -{ - return do_wait(false); -} - -Task::Status ExternalTask::wait() -{ - return do_wait(true); -} - -Task::Status ExternalTask::do_wait(bool block) -{ - while(process) - { - if(process->wait(block && !capture_pipe)) - { - exit_code = process->get_exit_code(); - delete process; - process = 0; - } - - // Do this after waiting to avoid a race condition - while(capture_pipe && IO::poll(*capture_pipe, IO::P_INPUT, 10*Time::msec)) - { - char buf[1024]; - unsigned len = capture_pipe->read(buf, sizeof(buf)); - if(len) - output.append(buf, len); - else - break; - } - - if(process) - { - if(!block) - return RUNNING; - } - else - signal_finished.emit(!exit_code); - } - - return exit_code ? ERROR : SUCCESS; -} - -void ExternalTask::set_stdin(const FS::Path &f) -{ - stdin_action = REDIRECT; - stdin_file = f; -} - -void ExternalTask::set_stdout(StreamAction a) -{ - if(a==REDIRECT) - throw invalid_argument("ExternalTask::set_stdout"); - stdout_action = a; -} - -void ExternalTask::set_stdout(const FS::Path &f) -{ - stdout_action = REDIRECT; - stdout_file = f; -} - -void ExternalTask::set_stderr(StreamAction a) -{ - if(a==REDIRECT) - throw invalid_argument("ExternalTask::set_stdout"); - stderr_action = a; -} - -string ExternalTask::run_and_capture_output(const Arguments &argv, const FS::Path &wd, bool capture_stderr) -{ - ExternalTask task(argv, wd); - task.stdin_action = IGNORE; - task.set_stdout(CAPTURE); - task.set_stderr(capture_stderr ? CAPTURE : IGNORE); - task.start(); - if(task.wait()!=SUCCESS) - throw runtime_error(format("%s failed", argv.front())); - return task.get_output(); -}