fix(relinker): propagate POSIX autorun failures

This commit is contained in:
lorkydey committed 2026-10-14 16:17:24 +02:00
1 parent 066b58fa17
commit 48aaec50f8
2 files changed
+30 -3

No files matched your search

+6 -3
View File
@@ -6,6 +6,7 @@
#include <limits>
#include <string>
#include <cstdlib>
#include <cerrno>
#ifdef _WIN32
#include <windows.h>
@@ -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
@@ -1,4 +1,6 @@
#include <Cli.hpp>
#include <domain/Types.hpp>
#include <cerrno>
#include <chrono>
#include <csignal>
#include <filesystem>
@@ -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");