]> git.tdb.fi Git - builder.git/blobdiff - source/externaltask.h
Support redirecting ExternalTask's stdin/stdout from/to a file
[builder.git] / source / externaltask.h
index 3028e74ddb998ae1db611a05285c3f2d7d635be5..00465f3af4f3ba501952f1a7bf29ce149d04865a 100644 (file)
@@ -3,20 +3,76 @@
 
 #include <string>
 #include <vector>
+#include <msp/core/process.h>
 #include <msp/fs/path.h>
+#include <msp/io/pipe.h>
 #include "task.h"
 
+/**
+Runs an external command.  A zero exit status is translated to a SUCCESS status
+for the task, and anything else is treated as an error.  Output can optionally
+be captured.
+*/
 class ExternalTask: public Task
 {
+public:
+       enum StreamAction
+       {
+               PASSTHROUGH,  //< Do not touch the stream
+               CAPTURE,      //< Capture the stream
+               REDIRECT,     //< Redirect the stream to/from a file
+               IGNORE        //< Redirect the stream to oblivion
+       };
+
+       typedef Msp::Process::Arguments Arguments;
+
 private:
-       int pid;
+       Arguments argv;
+       Msp::FS::Path work_dir;
+       Msp::Process *process;
        int exit_code;
+       Msp::FS::Path stdin_file;
+       StreamAction stdout_action;
+       Msp::FS::Path stdout_file;
+       StreamAction stderr_action;
+       Msp::IO::Pipe *capture_pipe;
+       std::string output;
 
 public:
-       ExternalTask(const std::vector<std::string> &, const Msp::FS::Path &);
+       /** Creates an ExternalTask with an argument array and an optional working
+       directory.  The first element of the argument array should be the command
+       name.  If the working directory is not specified, no chdir is done. */
+       ExternalTask(const Arguments &, const Msp::FS::Path & = Msp::FS::Path());
 
+       virtual ~ExternalTask();
+
+       virtual std::string get_command() const;
        virtual void start();
        virtual Status check();
+       virtual Status wait();
+private:
+       Status do_wait(bool);
+
+public:
+       /// Redirect stdin from a file.  Has no effect after the task is started.
+       void set_stdin(const Msp::FS::Path &);
+
+       /// Sets destination for stdout.  Has no effect after the task is started.
+       void set_stdout(StreamAction);
+
+       /// Redirect stdout to a file.  Has no effect after the task is started.
+       void set_stdout(const Msp::FS::Path &);
+
+       /// Sets destination for stderr.  Has no effect after the task is started.
+       void set_stderr(StreamAction);
+
+       /** Returns captured output, if any.  This may be called while the task is
+       still running, but it will always return all output. */
+       const std::string &get_output() const { return output; }
+
+       /** Executes a command and captures its output.  Stderr is ignored, but if
+       the command exits with a nonzero status, an exception is thrown. */
+       static std::string run_and_capture_output(const Arguments &, const Msp::FS::Path & = Msp::FS::Path());
 };
 
 #endif