Files
AnyPS5/core/libs/tests/GuestKernelRename.cpp
T
ps54allandClaude Sonnet 5.5 372e2d4267 test(libkernel): cover the libkernel rename export directly
guest_filesystem_tests links libkernel and libc, both of which define
rename_nid_postfix, so which one it binds to depends on the loader and the
suite passes either way. Resolve the symbol from libkernel.prx explicitly so
the export added for titles that ship their own libc.prx is actually tested.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 23:17:03 +02:00

53 lines
2.4 KiB
C++

#include "prx/libc/include/general/VabiMacros.hpp"
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif
extern "C" {
int* APS5_VABI __error_nid_postfix();
}
using RenameFunction = int (APS5_VABI*)(const char*, const char*);
static RenameFunction LoadKernelRename() {
#ifdef _WIN32
const HMODULE module = LoadLibraryA(KERNEL_PRX_PATH);
return module ? reinterpret_cast<RenameFunction>(reinterpret_cast<void*>(GetProcAddress(module, "rename_nid_postfix"))) : nullptr;
#else
void* module = dlopen(KERNEL_PRX_PATH, RTLD_NOW | RTLD_LOCAL);
return module ? reinterpret_cast<RenameFunction>(dlsym(module, "rename_nid_postfix")) : nullptr;
#endif
}
static void Check(bool value, int line) {
if (!value) {
std::fprintf(stderr, "Kernel rename check failed at line %d (guest errno %d)\n", line, *__error_nid_postfix());
std::abort();
}
}
#define Require(value) Check((value), __LINE__)
int main() {
const RenameFunction rename_nid_postfix = LoadKernelRename();
if (rename_nid_postfix == nullptr) { std::fputs("libkernel does not export rename_nid_postfix\n", stderr); return 1; }
const auto root = std::filesystem::temp_directory_path() / ("aps5-kernel-rename-" +
std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()));
Require(std::filesystem::create_directory(root));
const auto file = root / "file.txt";
const auto renamed = root / "renamed.txt";
{ std::ofstream stream(file); stream << "retained"; }
Require(rename_nid_postfix(file.string().c_str(), renamed.string().c_str()) == 0);
Require(!std::filesystem::exists(file) && std::filesystem::exists(renamed));
Require(rename_nid_postfix(renamed.string().c_str(), renamed.string().c_str()) == 0);
Require(rename_nid_postfix(file.string().c_str(), renamed.string().c_str()) == -1 && *__error_nid_postfix() == 2);
Require(rename_nid_postfix(nullptr, renamed.string().c_str()) == -1 && *__error_nid_postfix() == 14);
Require(rename_nid_postfix(renamed.string().c_str(), nullptr) == -1 && *__error_nid_postfix() == 14);
Require(rename_nid_postfix("", renamed.string().c_str()) == -1 && *__error_nid_postfix() == 2);
Require(rename_nid_postfix(renamed.string().c_str(), "") == -1 && *__error_nid_postfix() == 2);
std::filesystem::remove_all(root);
return 0;
}