*
* Example:
*
- * SubProcess cat("cat", true, true);
+ * SubProcess cat("cat", SubProcess::PIPE, SubProcess::PIPE);
* if (cat.spawn() != 0) {
* std::cerr << "cat failed: " << cat.err() << std::endl;
* return false;
class SubProcess {
public:
- SubProcess(const char *cmd, bool pipe_stdin = false, bool pipe_stdout = false,
- bool pipe_stderr = false);
+ enum std_fd_op{
+ KEEP,
+ CLOSE,
+ PIPE
+ };
+public:
+ SubProcess(const char *cmd,
+ std_fd_op stdin_op = CLOSE,
+ std_fd_op stdout_op = CLOSE,
+ std_fd_op stderr_op = CLOSE);
virtual ~SubProcess();
void add_cmd_args(const char *arg, ...);
protected:
std::string cmd;
std::vector<std::string> cmd_args;
- bool pipe_stdin;
- bool pipe_stdout;
- bool pipe_stderr;
+ std_fd_op stdin_op;
+ std_fd_op stdout_op;
+ std_fd_op stderr_op;
int stdin_pipe_out_fd;
int stdout_pipe_in_fd;
int stderr_pipe_in_fd;
class SubProcessTimed : public SubProcess {
public:
- SubProcessTimed(const char *cmd, bool pipe_stdin = false,
- bool pipe_stdout = false, bool pipe_stderr = false,
+ SubProcessTimed(const char *cmd, std_fd_op stdin_op = CLOSE,
+ std_fd_op stdout_op = CLOSE, std_fd_op stderr_op = CLOSE,
int timeout = 0, int sigkill = SIGKILL);
protected:
int sigkill;
};
-SubProcess::SubProcess(const char *cmd_, bool use_stdin, bool use_stdout, bool use_stderr) :
+SubProcess::SubProcess(const char *cmd_, std_fd_op stdin_op_, std_fd_op stdout_op_, std_fd_op stderr_op_) :
cmd(cmd_),
cmd_args(),
- pipe_stdin(use_stdin),
- pipe_stdout(use_stdout),
- pipe_stderr(use_stderr),
+ stdin_op(stdin_op_),
+ stdout_op(stdout_op_),
+ stderr_op(stderr_op_),
stdin_pipe_out_fd(-1),
stdout_pipe_in_fd(-1),
stderr_pipe_in_fd(-1),
int SubProcess::get_stdin() const {
assert(is_spawned());
- assert(pipe_stdin);
+ assert(stdin_op == PIPE);
return stdin_pipe_out_fd;
}
int SubProcess::get_stdout() const {
assert(is_spawned());
- assert(pipe_stdout);
+ assert(stdout_op == PIPE);
return stdout_pipe_in_fd;
}
int SubProcess::get_stderr() const {
assert(is_spawned());
- assert(pipe_stderr);
+ assert(stderr_op == PIPE);
return stderr_pipe_in_fd;
}
void SubProcess::close_stdin() {
assert(is_spawned());
- assert(pipe_stdin);
+ assert(stdin_op == PIPE);
close(stdin_pipe_out_fd);
}
void SubProcess::close_stdout() {
assert(is_spawned());
- assert(pipe_stdout);
+ assert(stdout_op == PIPE);
close(stdout_pipe_in_fd);
}
void SubProcess::close_stderr() {
assert(is_spawned());
- assert(pipe_stderr);
+ assert(stderr_op == PIPE);
close(stderr_pipe_in_fd);
}
int ret = 0;
- if ((pipe_stdin && ::pipe(ipipe) == -1) ||
- (pipe_stdout && ::pipe(opipe) == -1) ||
- (pipe_stderr && ::pipe(epipe) == -1)) {
+ if ((stdin_op == PIPE && ::pipe(ipipe) == -1) ||
+ (stdout_op == PIPE && ::pipe(opipe) == -1) ||
+ (stderr_op == PIPE && ::pipe(epipe) == -1)) {
ret = -errno;
errstr << "pipe failed: " << cpp_strerror(errno);
goto fail;
if (maxfd == -1)
maxfd = 16384;
for (int fd = 0; fd <= maxfd; fd++) {
- if (fd == STDIN_FILENO && pipe_stdin)
+ if (fd == STDIN_FILENO && stdin_op != CLOSE)
continue;
- if (fd == STDOUT_FILENO && pipe_stdout)
+ if (fd == STDOUT_FILENO && stdout_op != CLOSE)
continue;
- if (fd == STDERR_FILENO && pipe_stderr)
+ if (fd == STDERR_FILENO && stderr_op != CLOSE)
continue;
::close(fd);
}
return EXIT_FAILURE;
}
-SubProcessTimed::SubProcessTimed(const char *cmd, bool pipe_stdin,
- bool pipe_stdout, bool pipe_stderr,
+SubProcessTimed::SubProcessTimed(const char *cmd, std_fd_op stdin_op,
+ std_fd_op stdout_op, std_fd_op stderr_op,
int timeout_, int sigkill_) :
- SubProcess(cmd, pipe_stdin, pipe_stdout, pipe_stderr),
+ SubProcess(cmd, stdin_op, stdout_op, stderr_op),
timeout(timeout_),
sigkill(sigkill_) {
}