From d02f93dca1c4857b36bc090f0b5ca7f3f510b174 Mon Sep 17 00:00:00 2001 From: StoneDC <19905433+StoneDC@users.noreply.github.com> Date: Wed, 28 Oct 2026 21:15:27 +0800 Subject: [PATCH] feat(relinker): optionally skip the autorun exit prompt --- core/relinker/cli/src/Autorun.cpp | 8 +++- core/relinker/cli/tests/AutorunExitTests.cpp | 45 ++++++++++++++++++++ docs/dev/ENVIRONMENT.md | 1 + 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/core/relinker/cli/src/Autorun.cpp b/core/relinker/cli/src/Autorun.cpp index e6e6defd69..ff35b4b139 100644 --- a/core/relinker/cli/src/Autorun.cpp +++ b/core/relinker/cli/src/Autorun.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -68,8 +69,11 @@ int Autorun(const std::string& absPath, bool toWindows) { std::cout << "\nRaw exit code: " << rawCode << "; Unpacked: " << exitCode << '\n'; #endif - std::cout << "\nPress Enter to exit...\n"; - std::cin.ignore(std::numeric_limits::max(), '\n'); + const char* noPause = std::getenv("ANYPS5_AUTORUN_NO_PAUSE"); + if (!noPause || std::string_view(noPause) != "1") { + std::cout << "\nPress Enter to exit...\n"; + std::cin.ignore(std::numeric_limits::max(), '\n'); + } return exitCode; } diff --git a/core/relinker/cli/tests/AutorunExitTests.cpp b/core/relinker/cli/tests/AutorunExitTests.cpp index 798fb129db..dc1a6e0090 100644 --- a/core/relinker/cli/tests/AutorunExitTests.cpp +++ b/core/relinker/cli/tests/AutorunExitTests.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include #ifndef _WIN32 @@ -19,6 +21,26 @@ namespace { +void SetNoPause(const char* value) { +#ifdef _WIN32 + if (_putenv_s("ANYPS5_AUTORUN_NO_PAUSE", value ? value : "") != 0) throw std::runtime_error("Cannot set autorun environment"); +#else + if ((value ? setenv("ANYPS5_AUTORUN_NO_PAUSE", value, 1) : unsetenv("ANYPS5_AUTORUN_NO_PAUSE")) != 0) + throw std::runtime_error("Cannot set autorun environment"); +#endif +} + +class EnvironmentGuard { +public: + EnvironmentGuard() { + if (const auto* value = std::getenv("ANYPS5_AUTORUN_NO_PAUSE")) saved = value; + SetNoPause(nullptr); + } + ~EnvironmentGuard() { SetNoPause(saved ? saved->c_str() : nullptr); } +private: + std::optional saved; +}; + std::filesystem::path ExecutablePath(const char* argument) { #ifdef _WIN32 static_cast(argument); @@ -55,6 +77,7 @@ int main(int, char* argv[]) { #endif }; #endif + const EnvironmentGuard environment; std::istringstream input("\n\n\n"); auto* savedInput = std::cin.rdbuf(input.rdbuf()); int result = 0; @@ -66,6 +89,28 @@ int main(int, char* argv[]) { std::filesystem::create_symlink(executable, child); const auto changed = changeTime(executable); #endif + for (const char* value : {"1", "0", "yes", ""}) { + SetNoPause(value); + std::istringstream pending("\nremaining"); + auto* originalInput = std::cin.rdbuf(pending.rdbuf()); + std::ostringstream output; + auto* originalOutput = std::cout.rdbuf(output.rdbuf()); + int code; + try { + code = Cli::Autorun(child.string(), true); + } catch (...) { + std::cin.rdbuf(originalInput); + std::cout.rdbuf(originalOutput); + throw; + } + std::cin.rdbuf(originalInput); + std::cout.rdbuf(originalOutput); + const bool skipped = std::string(value) == "1"; + if (code != 42 || (pending.tellg() == 0) != skipped || + (output.str().find("Press Enter") == std::string::npos) != skipped) + throw std::runtime_error("Autorun pause option changed the exit code, input position or prompt"); + } + SetNoPause(nullptr); std::vector suffixes{""}; #ifndef _WIN32 suffixes.insert(suffixes.end(), {" $HOME", " $(printf substituted)", " `printf substituted`", diff --git a/docs/dev/ENVIRONMENT.md b/docs/dev/ENVIRONMENT.md index 05678c738d..19f1cdf62b 100644 --- a/docs/dev/ENVIRONMENT.md +++ b/docs/dev/ENVIRONMENT.md @@ -20,6 +20,7 @@ The code reads environment names through `getenv`, `IsEnvironmentSet`, `kibSetti | Name | Kind | Source | Default | Description | |------|------|--------|---------|-------------| +| `ANYPS5_AUTORUN_NO_PAUSE` | string | `core/relinker/cli/src/Autorun.cpp` | | exactly `1` skips the exit prompt and stdin read after autorun; unset, empty and other values keep the prompt | | `ANYPS5_GUEST_MODULE_ARGS` | string | `core/relinker/elfpatcher/tests/GuestModuleArgsHost.cpp` | | path of the file the module-argument fixture appends its events to | ### core/shader