4 #include <msp/fs/dir.h>
5 #include <msp/io/console.h>
6 #include <msp/io/file.h>
7 #include <msp/io/print.h>
8 #include <msp/time/units.h>
9 #include "externaltask.h"
14 ExternalTask::ExternalTask(const Arguments &a, const FS::Path &wd):
19 stdout_dest(PASSTHROUGH),
20 stderr_dest(PASSTHROUGH),
24 throw invalid_argument("ExternalTask::ExternalTask");
27 ExternalTask::~ExternalTask()
32 string ExternalTask::get_command() const
35 for(vector<string>::const_iterator i=argv.begin(); i!=argv.end(); ++i)
40 for(string::const_iterator j=i->begin(); j!=i->end(); ++j)
42 if(*j=='"' || *j=='\'' || *j==' ' || *j=='\\' || *j=='&')
51 void ExternalTask::start()
53 IO::File *devnull = 0;
57 process = new Process;
59 if(stdout_dest==IGNORE || stderr_dest==IGNORE)
61 devnull = new IO::File("/dev/null", IO::M_WRITE);
62 if(stdout_dest==IGNORE)
63 process->redirect_cout(*devnull);
64 if(stderr_dest==IGNORE)
65 process->redirect_cerr(*devnull);
68 if(stdout_dest==CAPTURE || stderr_dest==CAPTURE)
70 capture_pipe = new IO::Pipe;
71 if(stdout_dest==CAPTURE)
72 process->redirect_cout(*capture_pipe);
73 if(stderr_dest==CAPTURE)
74 process->redirect_cerr(*capture_pipe);
78 process->set_working_directory(work_dir);
80 Process::Arguments args(argv.begin()+1, argv.end());
81 process->execute(argv.front(), args);
83 capture_pipe->set_mode(IO::M_READ);
88 Task::Status ExternalTask::check()
90 return do_wait(false);
93 Task::Status ExternalTask::wait()
98 Task::Status ExternalTask::do_wait(bool block)
102 if(process->wait(block))
104 exit_code = process->get_exit_code();
109 // Do this after waiting to avoid a race condition
110 while(capture_pipe && IO::poll(*capture_pipe, IO::P_INPUT, Time::zero))
113 unsigned len = capture_pipe->read(buf, sizeof(buf));
115 output.append(buf, len);
123 signal_finished.emit(!exit_code);
126 return exit_code ? ERROR : SUCCESS;
129 void ExternalTask::set_stdout(Destination d)
134 void ExternalTask::set_stderr(Destination d)
139 string ExternalTask::run_and_capture_output(const Arguments &argv, const FS::Path &wd)
141 ExternalTask task(argv, wd);
142 task.set_stdout(CAPTURE);
143 task.set_stderr(IGNORE);
145 if(task.wait()!=SUCCESS)
146 throw runtime_error(format("%s failed", argv.front()));
147 return task.get_output();