From: Philipp Gesang Date: Tue, 2 Jan 2018 16:10:13 +0000 (+0100) Subject: add pipestream ctor overload for vectors of string X-Git-Tag: v2.10~1^2~15 X-Git-Url: http://developer.intra2net.com/git/?p=libi2ncommon;a=commitdiff_plain;h=c2c29997544756bf70a3104fd4527550a4cc4bcf add pipestream ctor overload for vectors of string Add definitions that make passing a vector equivalent to passing a char**, i. e. take the execve() path. --- diff --git a/src/pipestream.cpp b/src/pipestream.cpp index ebcc6c2..cd9347a 100644 --- a/src/pipestream.cpp +++ b/src/pipestream.cpp @@ -100,6 +100,11 @@ std::string capture_exec (const std::string &command, ExecResult &res) std::string capture_exec (const char *const *command, ExecResult &res) { return capture_exec(command, res); } +std::string capture_exec (const std::vector &command, ExecResult &res) +{ + return capture_exec &>(command, res); +} + #define PIPE_CTOR_FAIL(where) \ do { \ throw EXCEPTION (pipestream_error, \ @@ -197,6 +202,25 @@ inpipebuf::inpipebuf(const char *const *command) setg (&buffer, &buffer, &buffer); } +inpipebuf::inpipebuf(const std::vector &command) + : pipe (NULL) /* brr: shadowing global ident */ + , status_set (NULL) + , exit_status (NULL) +{ + if (command.empty ()) { + PIPE_CTOR_FAIL("command"); + } + + const boost::shared_array argv = mk_argv (command); + if (!argv) { + PIPE_CTOR_FAIL("malloc"); + } + + this->pipe = this->init_without_shell (argv.get ()); + + setg (&buffer, &buffer, &buffer); +} + inpipebuf::inpipebuf(const std::string& command) { status_set = NULL; diff --git a/src/pipestream.hxx b/src/pipestream.hxx index 6f83006..d13f312 100644 --- a/src/pipestream.hxx +++ b/src/pipestream.hxx @@ -33,6 +33,7 @@ on this file might be covered by the GNU General Public License. #include #include #include +#include struct ExecResult { @@ -55,6 +56,7 @@ typedef struct ExecResult ExecResult; std::string capture_exec(const std::string& command, ExecResult &rescode); std::string capture_exec(const char *const *command, ExecResult &rescode); +std::string capture_exec(const std::vector& command, ExecResult &rescode); inline std::string capture_exec (const std::string &command) { @@ -68,6 +70,12 @@ inline std::string capture_exec(const char *const *command) return capture_exec(command,r); } +inline std::string capture_exec(const std::vector& command) +{ + ExecResult r; + return capture_exec(command,r); +} + /** @brief runs command and provides buffered input for it through pipe * * opens pipe to command using popen; exit status available after destruction @@ -91,6 +99,7 @@ protected: public: inpipebuf(const std::string& command); inpipebuf(const char *const *command); + inpipebuf(const std::vector &command); ~inpipebuf(); @@ -117,6 +126,10 @@ public: : std::istream(&buf), buf(command) {} + inpipestream(const std::vector &command) + : std::istream(&buf), buf(command) + {} + void store_exit_status(bool *_status_set, int *_exit_status) { buf.store_exit_status(_status_set, _exit_status); } }; diff --git a/test/test_pipestream.cpp b/test/test_pipestream.cpp index a58c89a..cf806c4 100644 --- a/test/test_pipestream.cpp +++ b/test/test_pipestream.cpp @@ -27,7 +27,6 @@ #define BOOST_TEST_DYN_LINK #include -#include #include "stringfunc.hxx" #include "pipestream.hxx" @@ -51,6 +50,19 @@ BOOST_AUTO_TEST_SUITE(pipestream) BOOST_CHECK_EQUAL(result.size (), ENOUGH_ZEROS); } + BOOST_AUTO_TEST_CASE(abspath_zeros_shell_ok_result) + { + ExecResult exres; + const std::string result = + capture_exec (I2n::join_string (zero_bytes_argv, " "), + exres); + + BOOST_CHECK(exres.normal_exit); + BOOST_CHECK_EQUAL(exres.return_code, 0); + BOOST_CHECK(!exres.terminated_by_signal); + BOOST_CHECK_EQUAL(result.size (), ENOUGH_ZEROS); + } + BOOST_AUTO_TEST_CASE(abspath_zeros_noshell_ok) { const std::string result = capture_exec (zero_bytes_argv); @@ -58,6 +70,32 @@ BOOST_AUTO_TEST_SUITE(pipestream) BOOST_CHECK_EQUAL(result.size (), ENOUGH_ZEROS); } + BOOST_AUTO_TEST_CASE(abspath_zeros_noshell_ok_strvec) + { + std::vector argvec; + const char *const *argp = zero_bytes_argv; + const char * cur = NULL; + + while ((cur = *argp++) != NULL) { + argvec.push_back (std::string (cur)); + } + + const std::string result = capture_exec (argvec); + + BOOST_CHECK_EQUAL(result.size (), ENOUGH_ZEROS); + } + + BOOST_AUTO_TEST_CASE(abspath_zeros_noshell_ok_result) + { + ExecResult exres; + const std::string result = capture_exec (zero_bytes_argv, exres); + + BOOST_CHECK(exres.normal_exit); + BOOST_CHECK_EQUAL(exres.return_code, 0); + BOOST_CHECK(!exres.terminated_by_signal); + BOOST_CHECK_EQUAL(result.size (), ENOUGH_ZEROS); + } + BOOST_AUTO_TEST_SUITE_END() /* [pipestream->read] */ BOOST_AUTO_TEST_SUITE_END() /* [pipestream] */