std::string capture_exec (const char *const *command, ExecResult &res)
{ return capture_exec<const char *const *>(command, res); }
+std::string capture_exec (const std::vector<std::string> &command, ExecResult &res)
+{
+ return capture_exec<const std::vector<std::string> &>(command, res);
+}
+
#define PIPE_CTOR_FAIL(where) \
do { \
throw EXCEPTION (pipestream_error, \
setg (&buffer, &buffer, &buffer);
}
+inpipebuf::inpipebuf(const std::vector<std::string> &command)
+ : pipe (NULL) /* brr: shadowing global ident */
+ , status_set (NULL)
+ , exit_status (NULL)
+{
+ if (command.empty ()) {
+ PIPE_CTOR_FAIL("command");
+ }
+
+ const boost::shared_array <char *> 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;
#include <streambuf>
#include <istream>
#include <ostream>
+#include <vector>
struct 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<std::string>& command, ExecResult &rescode);
inline std::string capture_exec (const std::string &command)
{
return capture_exec(command,r);
}
+inline std::string capture_exec(const std::vector<std::string>& 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
public:
inpipebuf(const std::string& command);
inpipebuf(const char *const *command);
+ inpipebuf(const std::vector<std::string> &command);
~inpipebuf();
: std::istream(&buf), buf(command)
{}
+ inpipestream(const std::vector<std::string> &command)
+ : std::istream(&buf), buf(command)
+ {}
+
void store_exit_status(bool *_status_set, int *_exit_status)
{ buf.store_exit_status(_status_set, _exit_status); }
};
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
-#include <boost/algorithm/string/replace.hpp>
#include "stringfunc.hxx"
#include "pipestream.hxx"
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);
BOOST_CHECK_EQUAL(result.size (), ENOUGH_ZEROS);
}
+ BOOST_AUTO_TEST_CASE(abspath_zeros_noshell_ok_strvec)
+ {
+ std::vector<std::string> 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] */