diff options
author | 2010-08-21 09:44:08 +0100 | |
---|---|---|
committer | 2010-08-21 14:58:18 +0100 | |
commit | 0288242e1f934eb360013e541a904e177d1b3373 (patch) | |
tree | dfecaa03d1ff5a536adf7e1e8b7dbabbc931d684 | |
parent | a4733b02576a1b82cd65e64696faff97eaee5355 (diff) | |
download | paludis-0288242e1f934eb360013e541a904e177d1b3373.tar.gz paludis-0288242e1f934eb360013e541a904e177d1b3373.tar.xz |
ProcessCommand(string)
-rw-r--r-- | paludis/util/process.cc | 65 | ||||
-rw-r--r-- | paludis/util/process.hh | 5 | ||||
-rw-r--r-- | paludis/util/process_TEST.cc | 15 |
3 files changed, 67 insertions, 18 deletions
diff --git a/paludis/util/process.cc b/paludis/util/process.cc index 25fe95ca9..117720525 100644 --- a/paludis/util/process.cc +++ b/paludis/util/process.cc @@ -55,21 +55,28 @@ namespace paludis struct Imp<ProcessCommand> { std::vector<std::string> args; + std::string args_string; - Imp(std::vector<std::string> && i) : - args(i) + Imp(std::vector<std::string> && i, const std::string & s) : + args(i), + args_string(s) { } }; } ProcessCommand::ProcessCommand(const std::initializer_list<std::string> & i) : - Pimp<ProcessCommand>(std::vector<std::string>(i)) + Pimp<ProcessCommand>(std::vector<std::string>(i), "") +{ +} + +ProcessCommand::ProcessCommand(const std::string & s) : + Pimp<ProcessCommand>(std::vector<std::string>(), s) { } ProcessCommand::ProcessCommand(ProcessCommand && other) : - Pimp<ProcessCommand>(std::move(other._imp->args)) + Pimp<ProcessCommand>(std::move(other._imp->args), other._imp->args_string) { } @@ -84,25 +91,47 @@ ProcessCommand::prepend_args(const std::initializer_list<std::string> & l) void ProcessCommand::exec() { - if (_imp->args.size() < 1) - throw ProcessError("No command specified"); + if (! _imp->args_string.empty()) + { + std::string s; + for (auto v_begin(_imp->args.begin()), v(v_begin), v_end(_imp->args.end()) ; + v != v_end ; ++v) + { + if (v != v_begin) + s.append(" "); + s.append(*v); + } - /* no need to worry about free()ing this lot, since if our execvp fails we - * call _exit() shortly afterwards */ + if (! s.empty()) + s.append(" "); + s.append(_imp->args_string); - char ** argv(new char * [_imp->args.size() + 1]); - argv[_imp->args.size()] = 0; - for (auto v_begin(_imp->args.begin()), v(v_begin), v_end(_imp->args.end()) ; - v != v_end ; ++v) - { - argv[v - v_begin] = new char [v->length() + 1]; - argv[v - v_begin][v->length()] = '\0'; - std::copy(v->begin(), v->end(), argv[v - v_begin]); + execl("/bin/sh", "sh", "-c", s.c_str(), static_cast<char *>(0)); + + throw ProcessError("execl failed"); } + else + { + if (_imp->args.size() < 1) + throw ProcessError("No command specified"); + + /* no need to worry about free()ing this lot, since if our execvp fails we + * call _exit() shortly afterwards */ - execvp(_imp->args[0].c_str(), argv); + char ** argv(new char * [_imp->args.size() + 1]); + argv[_imp->args.size()] = 0; + for (auto v_begin(_imp->args.begin()), v(v_begin), v_end(_imp->args.end()) ; + v != v_end ; ++v) + { + argv[v - v_begin] = new char [v->length() + 1]; + argv[v - v_begin][v->length()] = '\0'; + std::copy(v->begin(), v->end(), argv[v - v_begin]); + } - throw ProcessError("execvp failed"); + execvp(_imp->args[0].c_str(), argv); + + throw ProcessError("execvp failed"); + } } void diff --git a/paludis/util/process.hh b/paludis/util/process.hh index 6703a270b..a1193f16f 100644 --- a/paludis/util/process.hh +++ b/paludis/util/process.hh @@ -55,6 +55,11 @@ namespace paludis **/ explicit ProcessCommand(const std::initializer_list<std::string> &); + /** + * List of arguments, passed to sh -c. + */ + explicit ProcessCommand(const std::string &); + ProcessCommand(ProcessCommand &&); ~ProcessCommand(); diff --git a/paludis/util/process_TEST.cc b/paludis/util/process_TEST.cc index 0686e8c9f..be63e49d1 100644 --- a/paludis/util/process_TEST.cc +++ b/paludis/util/process_TEST.cc @@ -111,6 +111,21 @@ namespace test_cases } } test_grab_stdout; + struct GrabStdoutSingleCommandTest : TestCase + { + GrabStdoutSingleCommandTest() : TestCase("grab stdout single command") { } + + void run() + { + std::stringstream stdout_stream; + Process echo_process(ProcessCommand("echo giant space monkey")); + echo_process.capture_stdout(stdout_stream); + + TEST_CHECK_EQUAL(echo_process.run().wait(), 0); + TEST_CHECK_EQUAL(stdout_stream.str(), "giant space monkey\n"); + } + } test_grab_stdout_single_command; + struct GrabStderrTest : TestCase { GrabStderrTest() : TestCase("grab stderr") { } |