From 18686a79edb02162a72c7f2ffeea945e1c40ee3b Mon Sep 17 00:00:00 2001 From: arunmu Date: Wed, 16 Mar 2016 12:12:46 +0530 Subject: [PATCH] communicate implemented - test case not working though --- main | Bin 68128 -> 97060 bytes subprocess.hpp | 147 ++++++++++++++++++++++++++++++++++------ test/test_subprocess.cc | 10 ++- 3 files changed, 131 insertions(+), 26 deletions(-) diff --git a/main b/main index 6b3a534d930a2e4bc883873b62b2ca487070987e..f1114b00c8a44957c27e803f2cd2e8f39c8c6641 100755 GIT binary patch literal 97060 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 delta 14455 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 #include #include +#include #include #include @@ -20,13 +21,14 @@ extern "C" { namespace subprocess { -using Buffer = std::vector; -using OutBuffer = std::vector; -using ErrBuffer = std::vector; +using Buffer = std::vector; +using OutBuffer = std::vector; +using ErrBuffer = std::vector; // Max buffer size allocated on stack for read error // from pipe static const size_t SP_MAX_ERR_BUF_SIZ = 1024; +static const size_t DEFAULT_BUF_CAP_BYTES = 8192; // Exception Classes class CalledProcessError: public std::runtime_error @@ -320,12 +322,24 @@ public: {} void operator=(const Communication&) = delete; public: - int send(const uint8_t* msg, size_t length); + int send(const char* msg, size_t length); int send(const Buffer& msg); - int send(Buffer&& msg); + + std::pair communicate(const char* msg, size_t length); + std::pair communicate(const Buffer& msg) + { return communicate(msg.data(), msg.size()); } + + void set_out_buf_cap(size_t cap) { out_buf_cap_ = cap; } + void set_err_buf_cap(size_t cap) { err_buf_cap_ = cap; } + +private: + std::pair communicate_threaded( + const char* msg, size_t length); private: Streams* stream_; + size_t out_buf_cap_ = DEFAULT_BUF_CAP_BYTES; + size_t err_buf_cap_ = DEFAULT_BUF_CAP_BYTES; }; class Streams @@ -372,15 +386,22 @@ public: void output(FILE* fp) { output_.reset(fp, fclose); } void error(FILE* fp) { error_.reset(fp, fclose); } + void set_out_buf_cap(size_t cap) { comm_.set_out_buf_cap(cap); } + void set_err_buf_cap(size_t cap) { comm_.set_err_buf_cap(cap); } + public: /* Communication forwarding API's */ - int send(const uint8_t* msg, size_t length) + int send(const char* msg, size_t length) { return comm_.send(msg, length); } int send(const Buffer& msg) { return comm_.send(msg); } - int send(Buffer&& msg) - { return comm_.send(std::move(msg)); } + std::pair communicate(const char* msg, size_t length) + { return comm_.communicate(msg, length); } + + std::pair communicate(const Buffer& msg) + { return comm_.communicate(msg); } + public:// Yes they are public @@ -441,22 +462,21 @@ public: int pid() const noexcept { return child_pid_; } - void set_out_buf_cap(); + void set_out_buf_cap(size_t cap) { stream_.set_out_buf_cap(cap); } - void set_err_buf_cap(); + void set_err_buf_cap(size_t cap) { stream_.set_err_buf_cap(cap); } - int send(const uint8_t* msg, size_t length) + int send(const char* msg, size_t length) { return stream_.send(msg, length); } int send(const Buffer& msg) { return stream_.send(msg); } - int send(Buffer&& msg) - { return stream_.send(std::move(msg)); } + std::pair communicate(const char* msg, size_t length) + { return stream_.communicate(msg, length); } - void communicate(const char* msg, size_t length, bool finish = false); - void communicate(const Buffer& msg, bool finish = false); - void communicate(Buffer&& msg, bool finish = false); + std::pair communicate(const Buffer& msg) + { return stream_.communicate(msg); } private: template @@ -729,10 +749,10 @@ namespace detail { } } - int Communication::send(const uint8_t* msg, size_t length) + int Communication::send(const char* msg, size_t length) { if (stream_->input() == nullptr) return -1; - return std::fwrite(msg, sizeof(uint8_t), length, stream_->input()); + return std::fwrite(msg, sizeof(char), length, stream_->input()); } int Communication::send(const Buffer& msg) @@ -740,9 +760,96 @@ namespace detail { return send(msg.data(), msg.size()); } - int Communication::send(Buffer&& msg) + std::pair + Communication::communicate(const char* msg, size_t length) { - return send(msg.data(), msg.size()); + // Optimization from subprocess.py + // If we are using one pipe, or no pipe + // at all, using select() or threads is unnecessary. + auto hndls = {stream_->input(), stream_->output(), stream_->error()}; + int count = std::count(std::begin(hndls), std::end(hndls), nullptr); + + if (count >= 2) { + OutBuffer obuf; + ErrBuffer ebuf; + if (stream_->input()) { + if (msg) { + int wbytes = std::fwrite(msg, sizeof(char), length, stream_->input()); + if (wbytes < length) { + if (errno != EPIPE && errno != EINVAL) { + throw OSError("fwrite error", errno); + } + } + } + // Close the input stream + stream_->input_.reset(); + } else if (stream_->output()) { + // Read till EOF + // ATTN: This could be blocking, if the process + // at the other end screws up, we get screwed up as well + obuf.resize(out_buf_cap_); + int rbytes = util::read_atmost_n(fileno(stream_->output()), + (char*)obuf.data(), obuf.size()); + if (rbytes == -1) { + throw OSError("read to obuf failed", errno); + } + // Close the output stream + stream_->output_.reset(); + } else if (stream_->error()) { + // Same screwness applies here as well + ebuf.resize(err_buf_cap_); + int rbytes = util::read_atmost_n(fileno(stream_->error()), + (char*)ebuf.data(), ebuf.size()); + if (rbytes == -1) { + throw OSError("read to ebuf failed", errno); + } + // Close the error stream + stream_->error_.reset(); + } + return std::make_pair(obuf, ebuf); + } + + return communicate_threaded(msg, length); + } + + + std::pair + Communication::communicate_threaded(const char* msg, size_t length) + { + OutBuffer obuf; + ErrBuffer ebuf; + + std::vector bg_threads; + + if (stream_->output()) { + obuf.resize(out_buf_cap_); + bg_threads.push_back(std::thread( + util::read_atmost_n, fileno(stream_->output()), + (char*)obuf.data(), obuf.size())); + } + if (stream_->error()) { + ebuf.resize(err_buf_cap_); + bg_threads.push_back(std::thread( + util::read_atmost_n, fileno(stream_->error()), + (char*)ebuf.data(), ebuf.size())); + } + if (stream_->input()) { + if (msg) { + int wbytes = std::fwrite(msg, sizeof(char), length, stream_->input()); + if (wbytes < length) { + if (errno != EPIPE && errno != EINVAL) { + for (auto& t: bg_threads) t.join(); + throw OSError("fwrite error", errno); + } + } + } + stream_->input_.reset(); + } + + // Wait for the threads to finish + for(auto& thr : bg_threads) thr.join(); + + return std::make_pair(obuf, ebuf); } }; // end namespace detail diff --git a/test/test_subprocess.cc b/test/test_subprocess.cc index dcffb27..0183e1c 100755 --- a/test/test_subprocess.cc +++ b/test/test_subprocess.cc @@ -6,12 +6,10 @@ using namespace subprocess; void test_input() { auto p = Popen({"grep", "f"}, output{PIPE}, input{PIPE}); - const char* msg = "one\ntwo\nfour\n"; - std::fwrite(msg, 1, strlen(msg), p.input()); - fclose (p.input()); - - std::vector rbuf(128); - std::fread(rbuf.data(), 1, 128, p.output()); + const char* msg = "one\two\three\four\five\n"; + p.send(msg, strlen(msg)); + auto res = p.communicate(nullptr, 0); + std::cout << res.first.data() << std::endl; } int main() {