diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/system/TARGETS | 18 | ||||
-rw-r--r-- | src/buildtool/system/system.cpp | 23 | ||||
-rw-r--r-- | src/buildtool/system/system.hpp | 10 | ||||
-rw-r--r-- | src/buildtool/system/system_command.hpp | 12 |
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 |