struct Process::Impl {
Impl(
- const string &path_in,
+ const string &path,
const Arguments &args,
- const Environment &env);
+ char *const env[]);
~Impl();
+ static Impl *EnvHelper(
+ const string &path,
+ const Arguments &args,
+ const Environment &env);
+
size_t WriteIn(const void *buffer, size_t max_len);
void CloseIn();
};
+Process::Process(
+ const string &path,
+ const Arguments &args)
+: impl(new Impl(path, args, nullptr)) {
+
+}
+
Process::Process(
const string &path,
const Arguments &args,
const Environment &env)
-: impl(new Impl(path, args, env)) {
+: impl(Impl::EnvHelper(path, args, env)) {
}
return impl->Join();
}
+Process::Impl *Process::Impl::EnvHelper(
+ const string &path,
+ const Arguments &args,
+ const Environment &env
+) {
+ char *envp[env.size() + 1];
+ for (size_t i = 0; i < env.size(); ++i) {
+ envp[i] = const_cast<char *>(env[i].c_str());
+ }
+ envp[env.size()] = nullptr;
+ return new Impl(path, args, envp);
+}
Process::Impl::Impl(
const string &path_in,
const Arguments &args,
- const Environment &env)
+ char *const envp[])
: joined(false)
, status(0)
, in_closed(false)
, out_closed(false)
, err_closed(false) {
const char *path = path_in.c_str();
- char *envp[env.size() + 1];
- for (size_t i = 0; i < env.size(); ++i) {
- envp[i] = const_cast<char *>(env[i].c_str());
- }
- envp[env.size()] = nullptr;
#ifdef _WIN32
string cmdline;
for (const auto &arg : args) {
close(fd_err[0]);
close(fd_err[1]);
- execve(path, argv, envp);
+ if (envp) {
+ execve(path, argv, envp);
+ } else {
+ execv(path, argv);
+ }
// if execve returns, something bad happened
exit(EXIT_FAILURE);
#else
{
- Process proc("/usr/bin/env", { "env", "true" }, { });
+ Process proc("/usr/bin/env", { "env", "true" });
int status = proc.Join();
CPPUNIT_ASSERT_EQUAL_MESSAGE(
"exit status of true assumed 0",
}
{
- Process proc("/usr/bin/env", { "env", "false" }, { });
+ Process proc("/usr/bin/env", { "env", "false" });
int status = proc.Join();
CPPUNIT_ASSERT_EQUAL_MESSAGE(
"exit status of false assumed 1",
void ProcessTest::testStream() {
#ifdef __WIN32
-# error "TODO: implemente Process tests for windows"
+# error "TODO: implement Process tests for windows"
#else
{
const string test_input("hello, world");
const string expected_output("hello, world\n");
- Process proc("/usr/bin/env", { "env", "echo", test_input.c_str() }, { });
+ Process proc("/usr/bin/env", { "env", "echo", test_input.c_str() });
char buffer[expected_output.length() + 1];
size_t len = proc.ReadOut(buffer, sizeof(buffer));
const string output(buffer, len);
{
const string test_input("dog");
const string expected_output("dog");
- Process proc("/usr/bin/env", { "env", "cat" }, { });
+ Process proc("/usr/bin/env", { "env", "cat" });
size_t len = proc.WriteIn(test_input.c_str(), test_input.size());
CPPUNIT_ASSERT_EQUAL_MESSAGE(
"unexpected length of input to cat",
#endif
}
+
+void ProcessTest::testEnv() {
+#ifdef __WIN32
+# error "TODO: implement Process tests for windows"
+#else
+ {
+ const string test_input("Hello, environment");
+ const string expected_output("Hello, environment\n");
+ Process proc("/usr/bin/env", { "env", "sh", "-c", "echo $BLANK_ENV_TEST" }, { "BLANK_ENV_TEST=" + test_input });
+ char buffer[expected_output.length() + 1];
+ size_t len = proc.ReadOut(buffer, sizeof(buffer));
+ const string output(buffer, len);
+ int status = proc.Join();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "exit status of echo assumed 0",
+ 0, status);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected length of echo output",
+ expected_output.size(), len);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "unexpected error output of echo",
+ expected_output, output);
+ }
+
+#endif
+}
+
}
}