X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fexternaltask.cpp;h=37a36d39150da641b3a39e91d5c0fb866576af02;hb=d1f9551e05c9d341149eb490e05b1465d3d6b711;hp=257d1318fb22a42d31a5e2ed04e95424cb0a80ae;hpb=4b075b4a7ed921be62740c302edeebcd8b06ca29;p=builder.git diff --git a/source/externaltask.cpp b/source/externaltask.cpp index 257d131..37a36d3 100644 --- a/source/externaltask.cpp +++ b/source/externaltask.cpp @@ -1,11 +1,9 @@ #include -#include -#include #include #include #include #include -#include +#include #include "externaltask.h" using namespace std; @@ -13,12 +11,7 @@ using namespace Msp; ExternalTask::ExternalTask(const Arguments &a, const FS::Path &wd): argv(a), - work_dir(wd), - process(0), - exit_code(-1), - stdout_action(PASSTHROUGH), - stderr_action(PASSTHROUGH), - capture_pipe(0) + work_dir(wd) { if(argv.empty()) throw invalid_argument("ExternalTask::ExternalTask"); @@ -32,20 +25,20 @@ ExternalTask::~ExternalTask() string ExternalTask::get_command() const { string cmd; - for(vector::const_iterator i=argv.begin(); i!=argv.end(); ++i) + for(const string &a: argv) { - if(i!=argv.begin()) + if(!cmd.empty()) cmd += ' '; - for(string::const_iterator j=i->begin(); j!=i->end(); ++j) + for(char c: a) { - if(*j=='"' || *j=='\'' || *j==' ' || *j=='\\' || *j=='&') + if(c=='"' || c=='\'' || c==' ' || c=='\\' || c=='&') cmd += '\\'; - cmd += *j; + cmd += c; } } - if(!stdin_file.empty()) + if(stdin_action==REDIRECT) { cmd += " <"; cmd += stdin_file.str(); @@ -70,9 +63,15 @@ void ExternalTask::start() process = new Process; - if(stdout_action==IGNORE || stderr_action==IGNORE) + if(stdin_action==IGNORE || stdout_action==IGNORE || stderr_action==IGNORE) { - devnull = new IO::File("/dev/null", IO::M_WRITE); +#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) @@ -94,7 +93,7 @@ void ExternalTask::start() process->redirect_cerr(*capture_pipe); } - if(!stdin_file.empty()) + if(stdin_action==REDIRECT) { infile = new IO::File((work_dir/stdin_file).str()); process->redirect_cin(*infile); @@ -125,9 +124,9 @@ Task::Status ExternalTask::wait() Task::Status ExternalTask::do_wait(bool block) { - if(process) + while(process) { - if(process->wait(block)) + if(process->wait(block && !capture_pipe)) { exit_code = process->get_exit_code(); delete process; @@ -135,7 +134,7 @@ Task::Status ExternalTask::do_wait(bool block) } // Do this after waiting to avoid a race condition - while(capture_pipe && IO::poll(*capture_pipe, IO::P_INPUT, Time::zero)) + while(capture_pipe && IO::poll(*capture_pipe, IO::P_INPUT, 10*Time::msec)) { char buf[1024]; unsigned len = capture_pipe->read(buf, sizeof(buf)); @@ -146,7 +145,10 @@ Task::Status ExternalTask::do_wait(bool block) } if(process) - return RUNNING; + { + if(!block) + return RUNNING; + } else signal_finished.emit(!exit_code); } @@ -156,6 +158,7 @@ Task::Status ExternalTask::do_wait(bool block) void ExternalTask::set_stdin(const FS::Path &f) { + stdin_action = REDIRECT; stdin_file = f; } @@ -179,11 +182,12 @@ void ExternalTask::set_stderr(StreamAction a) stderr_action = a; } -string ExternalTask::run_and_capture_output(const Arguments &argv, const FS::Path &wd) +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(IGNORE); + task.set_stderr(capture_stderr ? CAPTURE : IGNORE); task.start(); if(task.wait()!=SUCCESS) throw runtime_error(format("%s failed", argv.front()));