diff --git a/common/include/villas/popen.hpp b/common/include/villas/popen.hpp index 8bd3d51c6..fcc69567e 100644 --- a/common/include/villas/popen.hpp +++ b/common/include/villas/popen.hpp @@ -56,19 +56,14 @@ public: int close(); void kill(int signal = SIGINT); - std::istream &cin() + int getFdIn() { - return *(input.stream); + return fd_in; } - std::ostream &cout() + int getFdOut() { - return *(output.stream); - } - - int getFd() - { - return input.buffer->fd(); + return fd_out; } pid_t getPid() const @@ -84,6 +79,34 @@ protected: bool shell; pid_t pid; + int fd_in, fd_out; +}; + +class PopenStream : public Popen { + +public: + PopenStream(const std::string &cmd, + const arg_list &args = arg_list(), + const env_map &env = env_map(), + const std::string &wd = std::string(), + bool shell = false); + ~PopenStream(); + + std::istream &cin() + { + return *(input.stream); + } + + std::ostream &cout() + { + return *(output.stream); + } + + void open(); + int close(); + +protected: + struct { std::unique_ptr stream; std::unique_ptr buffer; @@ -99,7 +122,7 @@ protected: } /* namespace villas */ template -std::istream &operator>>(villas::utils::Popen &po, T &value) +std::istream &operator>>(villas::utils::PopenStream &po, T &value) { return *(po.input.stream) >> value; } diff --git a/common/lib/popen.cpp b/common/lib/popen.cpp index 41d782839..50cf26268 100644 --- a/common/lib/popen.cpp +++ b/common/lib/popen.cpp @@ -87,11 +87,8 @@ void Popen::open() if (ret) goto clean_inpipe_out; - input.buffer = std::make_unique(outpipe[READ], std::ios_base::in); - output.buffer = std::make_unique(inpipe[WRITE], std::ios_base::out); - - input.stream = std::make_unique(input.buffer.get()); - output.stream = std::make_unique(output.buffer.get()); + fd_in = outpipe[READ]; + fd_out = inpipe[WRITE]; pid = fork(); if (pid == -1) @@ -180,13 +177,47 @@ int Popen::close() } while (pid == -1 && errno == EINTR); } + return pid == -1 ? -1 : pstat; +} + + +PopenStream::PopenStream(const std::string &cmd, + const arg_list &args, + const env_map &env, + const std::string &wd, + bool sh) : + Popen(cmd, args, env, wd, sh) +{ + open(); +} + +PopenStream::~PopenStream() +{ + close(); +} + +void PopenStream::open() +{ + Popen::open(); + + input.buffer = std::make_unique(fd_in, std::ios_base::in); + output.buffer = std::make_unique(fd_out, std::ios_base::out); + + input.stream = std::make_unique(input.buffer.get()); + output.stream = std::make_unique(output.buffer.get()); +} + +int PopenStream::close() +{ + int ret = Popen::close(); + input.stream.reset(); output.stream.reset(); input.buffer.reset(); output.buffer.reset(); - return pid == -1 ? -1 : pstat; + return ret; } } /* namespace utils */