fix(relinker): decode autorun exit status for the host

This commit is contained in:
Tomás Ortellado 2026-10-05 09:23:47 -03:00
parent 53dc19cf61
commit 1fa44c7b5c
3 changed files with 60 additions and 5 deletions

View File

@ -125,6 +125,12 @@ endif()
if(BUILD_TESTING)
add_test_executable(autorun_exit_tests
${CMAKE_CURRENT_SOURCE_DIR}/cli/tests/AutorunExitTests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cli/src/Autorun.cpp)
target_include_directories(autorun_exit_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/cli/include)
add_test(NAME autorun_exit_status COMMAND autorun_exit_tests)
set_tests_properties(autorun_exit_status PROPERTIES TIMEOUT 20)
add_test_executable(buffer_bounds_tests
${CMAKE_CURRENT_SOURCE_DIR}/io/tests/BufferBoundsTests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/io/src/ByteReader.cpp

View File

@ -20,12 +20,15 @@ int Autorun(const std::string& absPath, bool toWindows) {
const int rawCode = std::system(cmd.c_str());
int exitCode = rawCode;
if (toWindows) {
std::cout << "\nExit code: " << rawCode << '\n';
} else {
if (rawCode != -1) exitCode = (rawCode >> 8) & 0xFF;
std::cout << "\nRaw exit code: " << rawCode << "; Unpacked: " << exitCode << '\n';
#ifdef _WIN32
std::cout << "\nExit code: " << rawCode << '\n';
#else
if (rawCode != -1) {
const int signal = rawCode & 0x7F;
exitCode = signal ? 128 + signal : (rawCode >> 8) & 0xFF;
}
std::cout << "\nRaw exit code: " << rawCode << "; Unpacked: " << exitCode << '\n';
#endif
std::cout << "\nPress Enter to exit...\n";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

View File

@ -0,0 +1,46 @@
#include <Cli.hpp>
#include <chrono>
#include <csignal>
#include <filesystem>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
int main(int, char* argv[]) {
const auto executable = std::filesystem::absolute(argv[0]);
const auto name = executable.stem().string();
if (name.starts_with("anyps5-autorun-child-")) {
if (name.find("signal") != std::string::npos) std::raise(SIGILL);
return 42;
}
const auto child = std::filesystem::temp_directory_path() / ("anyps5-autorun-child-" +
std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()) + " with spaces" + executable.extension().string());
#ifndef _WIN32
const auto signaled = child.parent_path() / ("anyps5-autorun-child-signal-" + child.filename().string());
#endif
std::istringstream input("\n\n\n");
auto* savedInput = std::cin.rdbuf(input.rdbuf());
int result = 0;
try {
std::filesystem::copy_file(executable, child);
for (const bool windows : {false, true}) {
const int code = Cli::Autorun(child.string(), windows);
if (code != 42) throw std::runtime_error("Autorun changed exit code 42 to " + std::to_string(code));
}
#ifndef _WIN32
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");
#endif
} catch (const std::exception& error) {
std::cerr << error.what() << '\n';
result = 1;
}
std::cin.rdbuf(savedInput);
std::filesystem::remove(child);
#ifndef _WIN32
std::filesystem::remove(signaled);
#endif
return result;
}