]> git.localhorst.tv Git - blank.git/commitdiff
allow cloned env with child processes
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 21 Nov 2016 16:42:45 +0000 (17:42 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 21 Nov 2016 16:42:45 +0000 (17:42 +0100)
src/app/Process.hpp
src/app/proc.cpp
tst/app/ProcessTest.cpp
tst/app/ProcessTest.hpp
tst/integration/TestInstance.cpp

index 6f5a5ae6f429806a3a9001885cecd26092c017f7..732fd2f4ac413c49eef56234bc1daf1569d57843 100644 (file)
@@ -16,7 +16,12 @@ public:
 
 public:
        /// launch process executing the file at given path with
-       /// given arguments and environment
+       /// given arguments and environment of parent process
+       Process(
+               const std::string &path,
+               const Arguments &args);
+       /// launch process executing the file at given path with
+       /// given arguments and given environment
        Process(
                const std::string &path,
                const Arguments &args,
index 876eefc0527aaf110d215a3c0ec683c1cae6c966..dff8dee525fcb8957034e939b91f70fccd9618e8 100644 (file)
@@ -23,11 +23,16 @@ namespace blank {
 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();
 
@@ -63,11 +68,18 @@ struct Process::Impl {
 };
 
 
+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)) {
 
 }
 
@@ -112,22 +124,29 @@ int Process::Join() {
        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) {
@@ -222,7 +241,11 @@ Process::Impl::Impl(
                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);
 
index a5d2cc5bad573478534e8daccaf193a88f3d3988..a16bfb31f42db442e76729a53c24c620ebb00048 100644 (file)
@@ -25,7 +25,7 @@ void ProcessTest::testExit() {
 #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",
@@ -33,7 +33,7 @@ void ProcessTest::testExit() {
        }
 
        {
-               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",
@@ -45,13 +45,13 @@ void ProcessTest::testExit() {
 
 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);
@@ -90,7 +90,7 @@ void ProcessTest::testStream() {
        {
                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",
@@ -116,5 +116,32 @@ void ProcessTest::testStream() {
 #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
+}
+
 }
 }
index 972fbe5092e506b4d62d923baa5e6db2c75b5bf8..95217e3bb48e084c1de79e49d6d2eaaaab78f553 100644 (file)
@@ -14,6 +14,7 @@ CPPUNIT_TEST_SUITE(ProcessTest);
 
 CPPUNIT_TEST(testExit);
 CPPUNIT_TEST(testStream);
+CPPUNIT_TEST(testEnv);
 
 CPPUNIT_TEST_SUITE_END();
 
@@ -23,6 +24,7 @@ public:
 
        void testExit();
        void testStream();
+       void testEnv();
 
 };
 
index 495ba6cdd413d602b0034895b06386d381843c03..270c09ca88a2e1ab8920dc50661fc763c0bf8883 100644 (file)
@@ -28,10 +28,7 @@ Process::Arguments combine_args(const TempDir &dir, const Process::Arguments &in
 
 TestInstance::TestInstance(const Process::Arguments &args, bool cmd)
 : dir()
-, proc(
-       "./blank" BLANK_SUFFIX,
-       combine_args(dir, args, cmd),
-       { })
+, proc("./blank" BLANK_SUFFIX, combine_args(dir, args, cmd))
 , conn()
 , out_buf()
 , err_buf()