aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-21 09:44:08 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-21 14:58:18 +0100
commit0288242e1f934eb360013e541a904e177d1b3373 (patch)
treedfecaa03d1ff5a536adf7e1e8b7dbabbc931d684
parenta4733b02576a1b82cd65e64696faff97eaee5355 (diff)
downloadpaludis-0288242e1f934eb360013e541a904e177d1b3373.tar.gz
paludis-0288242e1f934eb360013e541a904e177d1b3373.tar.xz
ProcessCommand(string)
-rw-r--r--paludis/util/process.cc65
-rw-r--r--paludis/util/process.hh5
-rw-r--r--paludis/util/process_TEST.cc15
3 files changed, 67 insertions, 18 deletions
diff --git a/paludis/util/process.cc b/paludis/util/process.cc
index 25fe95c..1177205 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 6703a27..a1193f1 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 0686e8c..be63e49 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") { }