--- /dev/null
+#include <cstdlib>
+#include <sys/wait.h>
+#include <msp/fs/dir.h>
+#include <msp/io/print.h>
+#include "externaltask.h"
+
+using namespace std;
+using namespace Msp;
+
+ExternalTask::ExternalTask(const vector<string> &argv, const FS::Path &work_dir):
+ pid(-1),
+ exit_code(-1)
+{
+ if((pid = fork()))
+ {
+ if(pid==-1)
+ exit_code = 1;
+ else
+ exit_code = 0;
+ }
+ else
+ {
+ vector<const char *> cargv(argv.size()+1);
+ for(unsigned i=0; i<argv.size(); ++i)
+ cargv[i] = argv[i].c_str();
+ cargv.back() = 0;
+
+ if(!work_dir.empty())
+ FS::chdir(work_dir);
+ execvp(cargv.front(), const_cast<char *const *>(&cargv.front()));
+ IO::print("Couldn't execute %s\n", argv.front());
+ exit(1);
+ }
+}
+
+Task::Status ExternalTask::check()
+{
+ if(pid>0)
+ {
+ 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;
+
+ signal_finished.emit(!exit_code);
+ }
+ else
+ return RUNNING;
+ }
+
+ return exit_code ? ERROR : SUCCESS;
+}