-// Copyright (C) 2019-2022 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2024 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
#include <fmt/core.h>
+#include <cstring>
#include <optional>
#include <stdexcept>
#include <string>
using ErrorBase::ErrorBase;
};
+// Call a libc-style function (returns 0 on success and sets errno) and throw
+// Fatal on error.
+#define CHECK_LIB_CALL(function, ...) \
+ { \
+ int _result = function(__VA_ARGS__); \
+ if (_result != 0) { \
+ throw core::Fatal(FMT(#function " failed: {}", strerror(_result))); \
+ } \
+ }
+
} // namespace core
{
LOG("Executing {}", util::format_argv_for_logging(argv));
- int result;
- posix_spawn_file_actions_t file_actions;
- if ((result = posix_spawn_file_actions_init(&file_actions))) {
- throw core::Fatal(
- FMT("posix_spawn_file_actions_init failed: {}", strerror(result)));
- }
+ posix_spawn_file_actions_t fa;
- if ((result = posix_spawn_file_actions_adddup2(
- &file_actions, *fd_out, STDOUT_FILENO))
- || (result = posix_spawn_file_actions_addclose(&file_actions, *fd_out))
- || (result = posix_spawn_file_actions_adddup2(
- &file_actions, *fd_err, STDERR_FILENO))
- || (result = posix_spawn_file_actions_addclose(&file_actions, *fd_err))) {
- throw core::Fatal(FMT("posix_spawn_file_actions_addclose/dup2 failed: {}",
- strerror(result)));
- }
+ CHECK_LIB_CALL(posix_spawn_file_actions_init, &fa);
+ CHECK_LIB_CALL(posix_spawn_file_actions_adddup2, &fa, *fd_out, STDOUT_FILENO);
+ CHECK_LIB_CALL(posix_spawn_file_actions_addclose, &fa, *fd_out);
+ CHECK_LIB_CALL(posix_spawn_file_actions_adddup2, &fa, *fd_err, STDERR_FILENO);
+ CHECK_LIB_CALL(posix_spawn_file_actions_addclose, &fa, *fd_err);
+ int result;
{
SignalHandlerBlocker signal_handler_blocker;
pid_t pid;
extern char** environ;
- result = posix_spawn(&pid,
- argv[0],
- &file_actions,
- nullptr,
- const_cast<char* const*>(argv),
- environ);
- if (!result) {
+ result = posix_spawn(
+ &pid, argv[0], &fa, nullptr, const_cast<char* const*>(argv), environ);
+ if (result == 0) {
ctx.compiler_pid = pid;
}
}
- posix_spawn_file_actions_destroy(&file_actions);
+ posix_spawn_file_actions_destroy(&fa);
fd_out.close();
fd_err.close();
- if (result) {
+ if (result != 0) {
return -1;
}
}
}
- auto argv = args.to_argv();
+ auto arg_vector = args.to_argv();
+ auto argv = const_cast<char* const*>(arg_vector.data());
LOG("Executing compiler check command {}",
- util::format_argv_for_logging(argv.data()));
+ util::format_argv_for_logging(argv));
#ifdef _WIN32
PROCESS_INFORMATION pi;
if (using_cmd_exe) {
win32args = adjusted_command; // quoted
} else {
- win32args = util::format_argv_as_win32_command_string(argv.data(), sh);
+ win32args = util::format_argv_as_win32_command_string(argv, sh);
}
BOOL ret = CreateProcess(path.c_str(),
const_cast<char*>(win32args.c_str()),
throw core::Fatal(FMT("pipe failed: {}", strerror(errno)));
}
- int result;
- posix_spawn_file_actions_t file_actions;
- if ((result = posix_spawn_file_actions_init(&file_actions))) {
- throw core::Fatal(
- FMT("posix_spawn_file_actions_init failed: {}", strerror(result)));
- }
+ posix_spawn_file_actions_t fa;
- if ((result = posix_spawn_file_actions_addclose(&file_actions, pipefd[0]))
- || (result = posix_spawn_file_actions_addclose(&file_actions, 0))
- || (result =
- posix_spawn_file_actions_adddup2(&file_actions, pipefd[1], 1))
- || (result =
- posix_spawn_file_actions_adddup2(&file_actions, pipefd[1], 2))) {
- throw core::Fatal(FMT("posix_spawn_file_actions_addclose/dup2 failed: {}",
- strerror(result)));
- }
+ CHECK_LIB_CALL(posix_spawn_file_actions_init, &fa);
+ CHECK_LIB_CALL(posix_spawn_file_actions_init, &fa);
+ CHECK_LIB_CALL(posix_spawn_file_actions_addclose, &fa, pipefd[0]);
+ CHECK_LIB_CALL(posix_spawn_file_actions_addclose, &fa, 0);
+ CHECK_LIB_CALL(posix_spawn_file_actions_adddup2, &fa, pipefd[1], 1);
+ CHECK_LIB_CALL(posix_spawn_file_actions_adddup2, &fa, pipefd[1], 2);
pid_t pid;
extern char** environ;
- result = posix_spawnp(&pid,
- argv[0],
- &file_actions,
- nullptr,
- const_cast<char* const*>(argv.data()),
- environ);
-
- posix_spawn_file_actions_destroy(&file_actions);
+ int result = posix_spawnp(
+ &pid, argv[0], &fa, nullptr, const_cast<char* const*>(argv), environ);
+
+ posix_spawn_file_actions_destroy(&fa);
close(pipefd[1]);
const auto hash_result = hash.hash_fd(pipefd[0]);
}
close(pipefd[0]);
- if (result) {
+ if (result != 0) {
LOG("posix_spawnp failed: {}", strerror(errno));
return false;
}