feat(system): handle console exit through runtime shutdown
This commit is contained in:
parent
79edb20f17
commit
2920c7f04c
|
|
@ -104,6 +104,18 @@ endforeach()
|
|||
add_custom_target(libs DEPENDS ${PATCHED_OUTPUTS})
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_executable(guest_system_exit_tests tests/GuestSystemExit.cpp)
|
||||
target_include_directories(guest_system_exit_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_system_exit_tests PRIVATE libSceSystemService libc)
|
||||
configure_windows_unwind(guest_system_exit_tests)
|
||||
add_test(NAME guest_system_exit_parameters COMMAND guest_system_exit_tests)
|
||||
add_test(NAME guest_system_exit COMMAND guest_system_exit_tests --exit)
|
||||
set_tests_properties(guest_system_exit PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "Guest shutdown and atexit completed")
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_system_exit guest_system_exit_parameters PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
add_executable(guest_character_tests tests/GuestCharacter.cpp)
|
||||
target_include_directories(guest_character_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_character_tests PRIVATE libc)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,24 @@
|
|||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include "prx/libc/include/Shutdown.hpp"
|
||||
#include "SceTypes.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
#include "prx/libSceSystemService/SystemService.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI sceSystemServiceLoadExec(const char* path, const char* const* arguments) {
|
||||
if (!path || !*path) return SYSTEM_SERVICE_ERROR_PARAMETER;
|
||||
if (std::strcmp(path, "exit") != 0) {
|
||||
NotImplemented_nid_no_patch("sceSystemServiceLoadExec: executable replacement");
|
||||
}
|
||||
(void)arguments;
|
||||
LibcRunShutdown_nid_postfix();
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
int APS5_VABI sceSystemServiceDisableNoticeScreenSkipFlagAutoSet(void) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include "prx/libc/include/Shutdown.hpp"
|
||||
#include "prx/libSceSystemService/SystemService.hpp"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
extern "C" int APS5_VABI sceSystemServiceLoadExec(const char*, const char* const*);
|
||||
namespace {
|
||||
bool cleaned = false;
|
||||
void Cleanup() { cleaned = true; }
|
||||
void VerifyExit() {
|
||||
if (!cleaned) std::_Exit(1);
|
||||
std::puts("Guest shutdown and atexit completed");
|
||||
}
|
||||
void Require(bool value) { if (!value) std::abort(); }
|
||||
}
|
||||
int main(int argc, char**) {
|
||||
if (argc > 1) {
|
||||
LibcRegisterShutdown_nid_postfix(Cleanup);
|
||||
Require(std::atexit(VerifyExit) == 0);
|
||||
sceSystemServiceLoadExec("exit", nullptr);
|
||||
return 2;
|
||||
}
|
||||
Require(sceSystemServiceLoadExec(nullptr, nullptr) == SYSTEM_SERVICE_ERROR_PARAMETER);
|
||||
Require(sceSystemServiceLoadExec("", nullptr) == SYSTEM_SERVICE_ERROR_PARAMETER);
|
||||
bool rejected = false;
|
||||
try { sceSystemServiceLoadExec("/app0/another.bin", nullptr); }
|
||||
catch (const std::runtime_error&) { rejected = true; }
|
||||
Require(rejected);
|
||||
}
|
||||
|
|
@ -391,3 +391,20 @@ Latest unchanged-game startup resolves ftello and stops at `JoBqSQt1yyA`
|
|||
shows it requests the console's `exit` operation from its quit path. This is
|
||||
source evidence only; the guest entry point still has not executed and no frame
|
||||
has been rendered.
|
||||
|
||||
## Follow-up: console exit request
|
||||
|
||||
Implemented sceSystemServiceLoadExec for the `exit` operation through the shared
|
||||
runtime shutdown callbacks followed by normal process exit. Null/empty paths
|
||||
return the existing system-service parameter error. Replacing the process with
|
||||
another executable remains explicitly unsupported and raises the runtime's
|
||||
existing not-implemented diagnostic; it does not report a successful launch.
|
||||
|
||||
An isolated CTest process verifies that shutdown callbacks execute before
|
||||
atexit handlers and that the service does not return after requesting exit.
|
||||
A separate test checks invalid arguments and executable-replacement rejection.
|
||||
All twenty-three tests pass and libraries rebuild.
|
||||
|
||||
The unchanged game resolves sceSystemServiceLoadExec and now stops at
|
||||
`gkWgn0p1AfU` (`freopen`). This does not establish that the game has executed
|
||||
its quit path: guest entry-point execution and rendered output remain unverified.
|
||||
|
|
|
|||
Loading…
Reference in New Issue