AnyPS5/core/libs/tests/GuestKernelSys.cpp

59 lines
2.5 KiB
C++

#include "prx/libc/include/general/VabiMacros.hpp"
#include <chrono>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <source_location>
#include <string>
extern "C" {
std::int64_t APS5_VABI readlink_nid_postfix(const char*, char*, std::size_t);
int* APS5_VABI __error_nid_postfix();
}
void Require(bool condition, std::source_location location = std::source_location::current()) {
if (!condition) {
std::fprintf(stderr, "Kernel sys check failed at line %u (guest errno %d)\n", location.line(), *__error_nid_postfix());
std::abort();
}
}
int Error() {
return *__error_nid_postfix();
}
int main() {
const auto root = std::filesystem::path("anyps5-kernel-sys-test-" +
std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()));
Require(std::filesystem::create_directory(root));
const auto file = (root / "file.txt").string();
std::ofstream(file).put('x');
char buffer[64];
Require(readlink_nid_postfix(file.c_str(), buffer, sizeof(buffer)) == -1 && Error() == 22);
Require(readlink_nid_postfix(root.string().c_str(), buffer, sizeof(buffer)) == -1 && Error() == 22);
Require(readlink_nid_postfix((root / "missing").string().c_str(), buffer, sizeof(buffer)) == -1 && Error() == 2);
Require(readlink_nid_postfix("", buffer, sizeof(buffer)) == -1 && Error() == 2);
Require(readlink_nid_postfix(nullptr, buffer, sizeof(buffer)) == -1 && Error() == 14);
std::error_code error;
const auto link = (root / "link").string();
std::filesystem::create_symlink("sub/target.txt", link, error);
if (!error) {
std::memset(buffer, '#', sizeof(buffer));
Require(readlink_nid_postfix(link.c_str(), buffer, sizeof(buffer)) == 14);
Require(std::memcmp(buffer, "sub/target.txt", 14) == 0 && buffer[14] == '#');
std::memset(buffer, '#', sizeof(buffer));
Require(readlink_nid_postfix(link.c_str(), buffer, 3) == 3);
Require(std::memcmp(buffer, "sub", 3) == 0 && buffer[3] == '#');
Require(readlink_nid_postfix(link.c_str(), nullptr, 0) == 0);
Require(readlink_nid_postfix(link.c_str(), nullptr, sizeof(buffer)) == -1 && Error() == 14);
Require(readlink_nid_postfix((root / "LINK").string().c_str(), buffer, sizeof(buffer)) == 14);
} else {
std::fprintf(stderr, "symbolic links unavailable: the link cases not tested\n");
}
std::filesystem::remove_all(root);
return 0;
}