From fc24e168da60e543a18767bfcf600c848bba0d90 Mon Sep 17 00:00:00 2001 From: arunmu Date: Tue, 15 Mar 2016 11:35:07 +0530 Subject: [PATCH] First commit of subprocess-cpp --- main | Bin 0 -> 68592 bytes main.cc | 9 + s.py | 3 + script.sh | 2 + subprocess.hpp | 541 +++++++++++++++++++++++++++++++++++++++++++++ test/test.cc | 42 ++++ test/test_split | Bin 0 -> 31148 bytes test/test_split.cc | 42 ++++ 8 files changed, 639 insertions(+) create mode 100755 main create mode 100755 main.cc create mode 100644 s.py create mode 100755 script.sh create mode 100755 subprocess.hpp create mode 100644 test/test.cc create mode 100755 test/test_split create mode 100644 test/test_split.cc diff --git a/main b/main new file mode 100755 index 0000000000000000000000000000000000000000..103c9100c1d5a54f69176162dc4111762be325a6 GIT binary patch literal 68592 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
-Jr*AfV;$sH8|Chnp&lzm&GdMkJaQG&JEe_7U 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { + #include + #include + #include + #include +} + +namespace subprocess { + +// Max buffer size allocated on stack for read error +// from pipe +static const size_t SP_MAX_ERR_BUF_SIZ = 1024; + +// Exception Classes +class CalledProcessError: public std::runtime_error +{ +public: + CalledProcessError(const std::string& error_msg): + std::runtime_error(error_msg) + {} +}; + + + +class OSError: public std::runtime_error +{ +public: + OSError(const std::string& err_msg, int err_code): + std::runtime_error( err_msg + " : " + std::strerror(err_code) ) + {} +}; + +//-------------------------------------------------------------------- + +namespace util +{ + std::vector + split(const std::string& str, const std::string& delims=" \t") + { + std::vector res; + size_t init = 0; + + while (true) { + auto pos = str.find_first_of(delims, init); + if (pos == std::string::npos) { + res.emplace_back(str.substr(init, str.length())); + break; + } + res.emplace_back(str.substr(init, pos - init)); + pos++; + init = pos; + } + + return res; + } + + std::string join(const std::vector& vec, + const std::string& sep = " ") + { + std::string res; + for (auto& elem : vec) res.append(elem + sep); + res.erase(--res.end()); + return res; + } + + void set_clo_on_exec(int fd, bool set = true) + { + int flags = fcntl(fd, F_GETFL, 0); + if (set) flags |= FD_CLOEXEC; + else flags &= ~FD_CLOEXEC; + //TODO: should check for errors + fcntl(fd, F_SETFL, flags); + } + + std::pair pipe_cloexec() + { + int pipe_fds[2]; + int res = pipe(pipe_fds); + if (res) { + throw OSError("pipe failure", errno); + } + + set_clo_on_exec(pipe_fds[0]); + set_clo_on_exec(pipe_fds[1]); + + return std::make_pair(pipe_fds[0], pipe_fds[1]); + } + + + int write_n(int fd, const char* buf, size_t length) + { + int nwritten = 0; + while (nwritten < length) { + int written = write(fd, buf + nwritten, length - nwritten); + if (written == -1) return -1; + nwritten += written; + } + return nwritten; + } + + int read_atmost_n(int fd, char* buf, size_t read_upto) + { + int rbytes = 0; + int eintr_cnter = 0; + + while (1) { + int read_bytes = read(fd, buf, read_upto); + if (read_bytes == -1) { + if (errno == EINTR) { + if (eintr_cnter >= 50) return -1; + eintr_cnter++; + continue; + } + return -1; + } + if (read_bytes == 0) return rbytes; + + rbytes += read_bytes; + } + return rbytes; + } + + int wait_for_child_exit(int pid) + { + int status; + int ret = -1; + while (1) { + ret = waitpid(pid, &status, WNOHANG); + if (ret == -1) break; + if (ret == 0) continue; + return pid; + } + + return ret; + } + + +}; // end namespace util + + +// Popen Arguments +struct bufsiz { int bufsiz; }; +struct defer_spawn { bool defer; }; + +struct string_arg +{ + string_arg(const char* arg): arg_value(arg) {} + string_arg(std::string&& arg): arg_value(std::move(arg)) {} + string_arg(std::string arg): arg_value(std::move(arg)) {} + std::string arg_value; +}; + +struct executable: string_arg +{ + template + executable(T&& arg): string_arg(std::forward(arg)) {} +}; + +struct cwd: string_arg +{ + template + cwd(T&& arg): string_arg(std::forward(arg)) {} +}; + +struct environment +{ + environment(std::map&& env): + env_(std::move(env)) {} + environment(const std::map& env): + env_(env) {} + std::map env_; +}; + +enum IOTYPE { + STDIN = 0, + STDOUT, + STDERR, + PIPE, +}; + +struct input +{ + input(int fd): rd_ch_(fd) {} + + input(const char* filename) { + int fd = open(filename, O_RDONLY); + if (fd == -1) throw OSError("File not found: ", errno); + rd_ch_ = fd; + } + input(IOTYPE typ) { + assert (typ == PIPE); + std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec(); + } + + int rd_ch_ = -1; + int wr_ch_ = -1; +}; + +struct output +{ + output(int fd): wr_ch_(fd) {} + + output(const char* filename) { + int fd = open(filename, O_APPEND | O_CREAT | O_RDWR, 0640); + if (fd == -1) throw OSError("File not found: ", errno); + wr_ch_ = fd; + } + output(IOTYPE typ) { + assert (typ == PIPE); + std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec(); + } + + int rd_ch_ = -1; + int wr_ch_ = -1; +}; + +struct error { + error(int fd): err_ch_(fd) {} + + error(const char* filename) { + int fd = open(filename, O_RDWR|O_APPEND); + if (fd == -1) throw OSError("File not found: ", errno); + err_ch_ = fd; + } + + int err_ch_ = -1; +}; + +// ~~~~ End Popen Args ~~~~ + +// Fwd Decl. +class Popen; + +namespace detail { + +struct ArgumentDeducer +{ + ArgumentDeducer(Popen* p): popen_(p) {} + + template + void set_options(T&& arg) + { + set_option(std::forward(arg)); + } + + template + void set_options(T&& farg, Args&&... rem_args) + { + set_option(std::forward(farg)); + set_options(std::forward(rem_args)...); + } + + void set_option(executable&& exe); + + void set_option(cwd&& cwdir); + + void set_option(bufsiz&& bsiz); + + void set_option(environment&& env); + + void set_option(defer_spawn&& defer); + + void set_option(input&& inp); + + void set_option(output&& out); + + void set_option(error&& err); + +private: + Popen* popen_ = nullptr; +}; + +}; // end namespace detail + + +class Popen +{ +public: + friend class detail::ArgumentDeducer; + + template + Popen(const std::string& cmd_args, Args&& ...args): + args_(cmd_args) + { + vargs_ = util::split(cmd_args); + init_args(std::forward(args)...); + + if (!defer_process_start_) execute_process(); + } + + template + Popen(std::initializer_list cmd_args, Args&& ...args) + { + vargs_.insert(vargs_.end(), cmd_args.begin(), cmd_args.end()); + init_args(std::forward(args)...); + if (!defer_process_start_) execute_process(); + } + + void start_process() throw (CalledProcessError, OSError) + { + // The process was started/tried to be started + // in the constructor itself. + // For explicitly calling this API to start the + // process, 'defer_spawn' argument must be set to + // true in the constructor. + if (!defer_process_start_) { + assert (0); + return; + } + execute_process(); + } + +private: + template + void init_args(Args&&... args); + void populate_c_argv(); + void execute_process() throw (CalledProcessError, OSError); + +private: + bool defer_process_start_ = false; + int bufsiz_ = 0; + std::string exe_name_; + std::string cwd_; + std::map env_; + + FILE* input_ = nullptr; + FILE* output_ = nullptr; + FILE* error_ = nullptr; + + // Pipes for communicating with child + + // Emulates stdin + int write_to_child_ = -1; // Parent owned descriptor + int read_from_parent_ = -1; // Child owned descriptor + + // Emulates stdout + int write_to_parent_ = -1; // Child owned descriptor + int read_from_child_ = -1; // Parent owned descriptor + + // Emulates stderr + int err_write_ = -1; // Write error to parent (Child owned) + int err_read_ = -1; // Read error from child (Parent owned) + + // Command in string format + std::string args_; + // Comamnd provided as sequence + std::vector vargs_; + std::vector cargv_; + + // Pid of the child process + int child_pid_ = -1; +}; + +template <> +void Popen::init_args() { + populate_c_argv(); +} + +template +void Popen::init_args(Args&&... args) +{ + detail::ArgumentDeducer argd(this); + argd.set_options(std::forward(args)...); +} + +void Popen::populate_c_argv() +{ + cargv_.reserve(vargs_.size()); + for (auto& arg : vargs_) cargv_.push_back(&arg[0]); +} + + +void Popen::execute_process() throw (CalledProcessError, OSError) +{ + int err_rd_pipe, err_wr_pipe; + int sys_ret = -1; + + std::tie(err_rd_pipe, err_wr_pipe) = util::pipe_cloexec(); + + if (!exe_name_.length()) { + exe_name_ = vargs_[0]; + } + + child_pid_ = fork(); + + if (child_pid_ < 0) { + close (err_rd_pipe); + close (err_wr_pipe); + throw OSError("fork failed", errno); + } + + if (child_pid_ == 0) {/* Child Part of Code */ + try { + // Close descriptors belonging to parent + if (write_to_child_ != -1) close(write_to_child_); + if (read_from_child_ != -1) close(read_from_child_); + if (err_read_ != -1) close(err_read_); + close(err_rd_pipe); + + // Make the child owned descriptors as the + // stdin, stdout and stderr for the child process + auto _dup2_ = [](int fd, int to_fd) { + if (fd == to_fd) { + // dup2 syscall does not reset the + // CLOEXEC flag if the descriptors + // provided to it are same. + // But, we need to reset the CLOEXEC + // flag as the provided descriptors + // are now going to be the standard + // input, output and error + util::set_clo_on_exec(fd, false); + } else if(fd != -1) { + int res = dup2(fd, to_fd); + if (res == -1) throw OSError("dup2 failed", errno); + } + }; + + // Create the standard streams + _dup2_(read_from_parent_, 0); // Input stream + _dup2_(write_to_parent_, 1); // Output stream + _dup2_(err_write_, 2); // Error stream + + // Close the extra sockets + if (read_from_parent_ != -1 && read_from_parent_ > 2) close(read_from_parent_); + if (write_to_parent_ != -1 && write_to_parent_ > 2) close(write_to_parent_); + if (err_write_ != -1 && err_write_ > 2) close(err_write_); + + // Close all the inherited fd's except the error write pipe + // TODO: Check for the option + int max_fd = sysconf(_SC_OPEN_MAX); + if (max_fd == -1) throw OSError("sysconf failed", errno); + for (int i = 3; i < max_fd; i++) { + if (i == err_wr_pipe) continue; + close(i); + } + + // Change the working directory if provided + if (cwd_.length()) { + sys_ret = chdir(cwd_.c_str()); + if (sys_ret == -1) throw OSError("chdir failed", errno); + } + + // Replace the current image with the executable + if (env_.size()) { + for (auto& kv : env_) setenv(kv.first.c_str(), kv.second.c_str(), 1); + sys_ret = execvp(exe_name_.c_str(), cargv_.data()); + } else { + sys_ret = execvp(exe_name_.c_str(), cargv_.data()); + } + if (sys_ret == -1) throw OSError("execve failed", errno); + + } catch (const OSError& exp) { + // Just write the exception message + // TODO: Give back stack trace ? + std::string err_msg(exp.what()); + //ATTN: Can we do something on error here ? + util::write_n(err_wr_pipe, err_msg.c_str(), err_msg.length()); + close(err_wr_pipe); + } + + // Calling application would not get this + // exit failure + exit (EXIT_FAILURE); + } else { // Parent code + // Close the err_wr_pipe + // Else get stuck forever!! + close (err_wr_pipe); + // Read the error from child if at all + char err_buf[SP_MAX_ERR_BUF_SIZ] = {0,}; + int read_bytes = util::read_atmost_n(err_rd_pipe, err_buf, SP_MAX_ERR_BUF_SIZ); + + close(err_rd_pipe); + + if (read_bytes || strlen(err_buf)) { + // Call waitpid to reap the child process + // waitpid suspends the calling process until the + // child terminates. + sys_ret = util::wait_for_child_exit(child_pid_); + // If the child could not be reaped successfully + // raise that error instead of child error + if (sys_ret == -1) throw OSError("child exit", errno); + + // Throw whatever information we have about child failure + throw CalledProcessError(err_buf); + } + } +} + + +namespace detail { + + void ArgumentDeducer::set_option(executable&& exe) { + popen_->exe_name_ = std::move(exe.arg_value); + } + + void ArgumentDeducer::set_option(cwd&& cwdir) { + popen_->cwd_ = std::move(cwdir.arg_value); + } + + void ArgumentDeducer::set_option(bufsiz&& bsiz) { + popen_->bufsiz_ = bsiz.bufsiz; + } + + void ArgumentDeducer::set_option(environment&& env) { + popen_->env_ = std::move(env.env_); + } + + void ArgumentDeducer::set_option(defer_spawn&& defer) { + popen_->defer_process_start_ = defer.defer; + } + + void ArgumentDeducer::set_option(input&& inp) { + popen_->read_from_parent_ = inp.rd_ch_; + if (inp.wr_ch_ != -1) popen_->write_to_child_ = inp.wr_ch_; + } + + void ArgumentDeducer::set_option(output&& out) { + popen_->write_to_parent_ = out.wr_ch_; + if (out.rd_ch_ != -1) popen_->read_from_child_ = out.rd_ch_; + } + + void ArgumentDeducer::set_option(error&& err) { + } + + +}; // end namespace detail + + +}; diff --git a/test/test.cc b/test/test.cc new file mode 100644 index 0000000..9cd453a --- /dev/null +++ b/test/test.cc @@ -0,0 +1,42 @@ +#include +#include + +struct bufsize { int siz_; }; +struct executable { std::string exe_; }; + +class Ex { +public: + template + Ex(Args&&... args) { + set_options(std::forward(args)...); + } + + template + void set_options(T&& arg) { + set_option(std::forward(arg)); + } + + template + void set_options(T&& first, Args&&... rem_args) { + set_option(std::forward(first)); + set_options(std::forward(rem_args)...); + } + + void set_option(bufsize&& bufs) { + std::cout << "bufsize opt" << std::endl; + bufsiz_ = bufs.siz_; + } + void set_option(executable&& exe) { + std::cout << "exe opt" << std::endl; + exe_name_ = std::move(exe.exe_); + } + +private: + int bufsiz_ = 0; + std::string exe_name_; +}; + +int main() { + Ex e(bufsize{1}, executable{"finger"}); + return 0; +} diff --git a/test/test_split b/test/test_split new file mode 100755 index 0000000000000000000000000000000000000000..5736605bda8eeb44d80ce635e5911a6b7a644ec9 GIT binary patch literal 31148 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 literal 0 HcmV?d00001 diff --git a/test/test_split.cc b/test/test_split.cc new file mode 100644 index 0000000..4de56c2 --- /dev/null +++ b/test/test_split.cc @@ -0,0 +1,42 @@ +#include +#include +#include + +std::vector +split(const std::string& str, const std::string& delims=" \t") +{ + std::vector res; + size_t init = 0; + + while (true) { + auto pos = str.find_first_of(delims, init); + if (pos == std::string::npos) { + res.emplace_back(str.substr(init, str.length())); + break; + } + res.emplace_back(str.substr(init, pos - init)); + pos++; + init = pos; + } + + return res; +} + +std::string join(const std::vector& vec) +{ + std::string res; + for (auto& elem : vec) { + res.append(elem + " "); + } + res.erase(--res.end()); + return res; +} + +int main() { + + auto vec = split ("a b c"); + for (auto elem : vec) { std::cout << elem << std::endl; } + + std::cout << join(vec).length() << std::endl; + return 0; +}