]> git.tdb.fi Git - builder.git/blob - source/externaltask.h
Be more efficient when running commands synchronously
[builder.git] / source / externaltask.h
1 #ifndef EXTERNALTASK_H_
2 #define EXTERNALTASK_H_
3
4 #include <string>
5 #include <vector>
6 #include <msp/fs/path.h>
7 #include <msp/io/pipe.h>
8 #include "task.h"
9
10 /**
11 Runs an external command.  A zero exit status is translated to a SUCCESS status
12 for the task, and anything else is treated as an error.  Output can optionally
13 be captured.
14 */
15 class ExternalTask: public Task
16 {
17 public:
18         enum Destination
19         {
20                 PASSTHROUGH,
21                 CAPTURE,
22                 IGNORE
23         };
24
25         typedef std::vector<std::string> Arguments;
26
27 private:
28         Arguments argv;
29         Msp::FS::Path work_dir;
30         int pid;
31         int exit_code;
32         Destination stdout_dest;
33         Destination stderr_dest;
34         Msp::IO::Pipe *capture_pipe;
35         std::string output;
36
37 public:
38         /** Creates an ExternalTask with an argument array and an optional working
39         directory.  The first element of the argument array should be the command
40         name.  If the working directory is not specified, no chdir is done. */
41         ExternalTask(const Arguments &, const Msp::FS::Path & = Msp::FS::Path());
42
43         virtual ~ExternalTask();
44
45         virtual std::string get_command() const;
46         virtual void start();
47         virtual Status check();
48         Status wait();
49 private:
50         Status do_wait(bool);
51
52 public:
53         void set_stdout(Destination);
54         void set_stderr(Destination);
55         const std::string &get_output() const { return output; }
56
57         /** Executes a command and captures its output.  Stderr is ignored, but if
58         the command exits with a nonzero status, an exception is thrown. */
59         static std::string run_and_capture_output(const Arguments &, const Msp::FS::Path & = Msp::FS::Path());
60 };
61
62 #endif