From 48aaec50f8dfbc9deb68f9dd2fceef7c79755d23 Mon Sep 17 00:00:00 2001 From: lorkydey <57268822+Lorkydey@users.noreply.github.com> Date: Wed, 14 Oct 2026 16:15:21 +0200 Subject: [PATCH] fix(relinker): propagate POSIX autorun failures --- core/relinker/cli/src/Autorun.cpp | 9 +++++--- core/relinker/cli/tests/AutorunExitTests.cpp | 24 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/core/relinker/cli/src/Autorun.cpp b/core/relinker/cli/src/Autorun.cpp index 7030a03da8..aa54150b47 100644 --- a/core/relinker/cli/src/Autorun.cpp +++ b/core/relinker/cli/src/Autorun.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -59,10 +60,12 @@ int Autorun(const std::string& absPath, bool toWindows) { cmd += '\''; rawCode = std::system(cmd.c_str()); - if (rawCode != -1) { - const int signal = rawCode & 0x7F; - exitCode = signal ? 128 + signal : (rawCode >> 8) & 0xFF; + if (rawCode == -1) { + const int runError = errno; + throw Domain::RelinkerException("Cannot run or wait for the output executable: " + absPath + " (error " + std::to_string(runError) + ")"); } + const int signal = rawCode & 0x7F; + exitCode = signal ? 128 + signal : (rawCode >> 8) & 0xFF; std::cout << "\nRaw exit code: " << rawCode << "; Unpacked: " << exitCode << '\n'; #endif diff --git a/core/relinker/cli/tests/AutorunExitTests.cpp b/core/relinker/cli/tests/AutorunExitTests.cpp index 4890de71de..c4883221a5 100644 --- a/core/relinker/cli/tests/AutorunExitTests.cpp +++ b/core/relinker/cli/tests/AutorunExitTests.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -42,6 +44,28 @@ int main(int, char* argv[]) { } } #ifndef _WIN32 + const auto savedHandler = std::signal(SIGCHLD, SIG_IGN); + if (savedHandler == SIG_ERR) throw std::runtime_error("Cannot ignore SIGCHLD for the autorun failure test"); + try { + for (const bool windows : {false, true}) { + bool rejected = false; + try { + Cli::Autorun(child.string(), windows); + } catch (const Domain::RelinkerException& error) { + const std::string message = error.what(); + if (message.find(child.string()) == std::string::npos || + message.find("(error " + std::to_string(ECHILD) + ")") == std::string::npos) + throw std::runtime_error("Autorun lost the failed wait's path or ECHILD error: " + message); + rejected = true; + } + if (!rejected) throw std::runtime_error("Autorun reported success after losing the child exit status"); + } + } catch (...) { + std::signal(SIGCHLD, savedHandler); + throw; + } + if (std::signal(SIGCHLD, savedHandler) == SIG_ERR) + throw std::runtime_error("Cannot restore SIGCHLD after the autorun failure test"); std::filesystem::rename(child, signaled); const int code = Cli::Autorun(signaled.string(), false); if (code != 128 + SIGILL) throw std::runtime_error("Autorun lost the child signal");