execAndWait: Capture stdout

Change-Id: I142841a56058b73670bee0456a324ffb17539f95
diff --git a/src/utils/exec.cpp b/src/utils/exec.cpp
index f8e8a9a..1d45a3f 100644
--- a/src/utils/exec.cpp
+++ b/src/utils/exec.cpp
@@ -12,7 +12,7 @@
 #include "log.h"
 #include "system_vars.h"
 
-void velia::utils::execAndWait(
+std::string velia::utils::execAndWait(
         velia::Log logger,
         const std::string& absolutePath,
         std::initializer_list<std::string> args,
@@ -21,6 +21,7 @@
 {
     namespace bp = boost::process;
     bp::pipe stdinPipe;
+    bp::ipstream stdoutStream;
     bp::ipstream stderrStream;
 
     auto onExecSetup = [opts] (const auto&) {
@@ -43,7 +44,7 @@
     bp::child c(
             absolutePath,
             boost::process::args=std::move(args),
-            bp::std_in < stdinPipe, bp::std_out > bp::null, bp::std_err > stderrStream,
+            bp::std_in < stdinPipe, bp::std_out > stdoutStream, bp::std_err > stderrStream,
             bp::extend::on_exec_setup=onExecSetup);
 
     stdinPipe.write(std_in.data(), std_in.size());
@@ -59,4 +60,7 @@
 
         throw std::runtime_error(absolutePath + " returned non-zero exit code " + std::to_string(c.exit_code()));
     }
+
+    std::istreambuf_iterator<char> begin(stdoutStream), end;
+    return {begin, end};
 }
diff --git a/src/utils/exec.h b/src/utils/exec.h
index 80292b7..6384b9d 100644
--- a/src/utils/exec.h
+++ b/src/utils/exec.h
@@ -12,16 +12,18 @@
 
 namespace velia::utils {
 /**
- * Spawns a new process with an executable specified by `absolutePath` and waits until it returns. stdout is thrown
- * away. Throws if the program has a non-zero exit code with a message containing the stderr of the process.
+ * Spawns a new process with an executable specified by `absolutePath` and waits until it returns. The return value is
+ * the stdout of the process. Throws if the program has a non-zero exit code with a message containing the stderr of the
+ * process.
  *
  * @param logger Logger to use.
  * @param absolutePath Full path to the excutable.
  * @param args Arguments to pass to the program. Can be {} if no arguments should be passed.
  * @param std_in stdin input fo the program.
+ * @return stdout of the command
  */
 enum class ExecOptions {
     DropRoot
 };
-void execAndWait(velia::Log logger, const std::string& absolutePath, std::initializer_list<std::string> args, std::string_view std_in, const std::set<ExecOptions> opts = {});
+std::string execAndWait(velia::Log logger, const std::string& absolutePath, std::initializer_list<std::string> args, std::string_view std_in, const std::set<ExecOptions> opts = {});
 }