summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/system/TARGETS18
-rw-r--r--src/buildtool/system/system.cpp23
-rw-r--r--src/buildtool/system/system.hpp10
-rw-r--r--src/buildtool/system/system_command.hpp12
4 files changed, 56 insertions, 7 deletions
diff --git a/src/buildtool/system/TARGETS b/src/buildtool/system/TARGETS
index c5db3f83..d71245b1 100644
--- a/src/buildtool/system/TARGETS
+++ b/src/buildtool/system/TARGETS
@@ -1,9 +1,23 @@
-{ "system_command":
+{ "system":
+ { "type": ["@", "rules", "CC", "library"]
+ , "arguments_config": ["VALGRIND_BUILD"]
+ , "name": ["system"]
+ , "hdrs": ["system.hpp"]
+ , "srcs": ["system.cpp"]
+ , "local defines":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "VALGRIND_BUILD"}
+ , "then": ["VALGRIND_BUILD"]
+ }
+ , "stage": ["src", "buildtool", "system"]
+ }
+, "system_command":
{ "type": ["@", "rules", "CC", "library"]
, "name": ["system_command"]
, "hdrs": ["system_command.hpp"]
, "deps":
- [ ["src/buildtool/file_system", "file_system_manager"]
+ [ "system"
+ , ["src/buildtool/file_system", "file_system_manager"]
, ["src/buildtool/logging", "logging"]
, ["@", "gsl-lite", "", "gsl-lite"]
]
diff --git a/src/buildtool/system/system.cpp b/src/buildtool/system/system.cpp
new file mode 100644
index 00000000..5f389b9a
--- /dev/null
+++ b/src/buildtool/system/system.cpp
@@ -0,0 +1,23 @@
+#include "src/buildtool/system/system.hpp"
+
+#include <array>
+#include <cstdlib>
+#include <string>
+
+#include <unistd.h>
+
+void System::ExitWithoutCleanup(int exit_code) {
+#ifdef VALGRIND_BUILD
+ // Usually std::_Exit() is the right thing to do in child processes that do
+ // not need to perform any cleanup (static destructors etc.). However,
+ // Valgrind will trace child processes until exec(3) is called or otherwise
+ // complains about leaks. Therefore, exit child processes via execvpe(3) if
+ // VALGRIND_BUILD is defined.
+ auto cmd =
+ std::string{exit_code == EXIT_SUCCESS ? "/bin/true" : "/bin/false"};
+ auto args = std::array<char*, 2>{cmd.data(), nullptr};
+ ::execvpe(args[0], args.data(), nullptr);
+#else
+ std::_Exit(exit_code);
+#endif
+}
diff --git a/src/buildtool/system/system.hpp b/src/buildtool/system/system.hpp
new file mode 100644
index 00000000..2038d5c7
--- /dev/null
+++ b/src/buildtool/system/system.hpp
@@ -0,0 +1,10 @@
+#ifndef INCLUDED_SRC_BUILDTOOL_SYSTEM_SYSTEM_HPP
+#define INCLUDED_SRC_BUILDTOOL_SYSTEM_SYSTEM_HPP
+
+namespace System {
+
+void ExitWithoutCleanup(int exit_code);
+
+}
+
+#endif // INCLUDED_SRC_BUILDTOOL_SYSTEM_SYSTEM_HPP
diff --git a/src/buildtool/system/system_command.hpp b/src/buildtool/system/system_command.hpp
index 53c92f21..da4e7f38 100644
--- a/src/buildtool/system/system_command.hpp
+++ b/src/buildtool/system/system_command.hpp
@@ -4,6 +4,7 @@
#include <array>
#include <cstdio>
#include <cstring> // for strerror()
+#include <iostream>
#include <iterator>
#include <map>
#include <optional>
@@ -17,6 +18,7 @@
#include "gsl-lite/gsl-lite.hpp"
#include "src/buildtool/file_system/file_system_manager.hpp"
#include "src/buildtool/logging/logger.hpp"
+#include "src/buildtool/system/system.hpp"
/// \brief Execute system commands and obtain stdout, stderr and return value.
/// Subsequent commands are context free and are not affected by previous
@@ -172,12 +174,12 @@ class SystemCommand {
::execvpe(*cmd, cmd, envp);
// report error and terminate child process if ::execvp did not exit
- logger_.Emit(LogLevel::Error,
- "Failed to execute '{}' with error: {}",
- *cmd,
- strerror(errno));
+ std::cerr << fmt::format("Failed to execute '{}' with error: {}",
+ *cmd,
+ strerror(errno))
+ << std::endl;
- std::exit(EXIT_FAILURE);
+ System::ExitWithoutCleanup(EXIT_FAILURE);
}
// wait for child to finish and obtain return value