#include "prx/libc/include/general/VabiMacros.hpp" #include #include #include #include struct ResourceLimit { std::int64_t rlim_cur; std::int64_t rlim_max; }; extern "C" { int APS5_VABI getrlimit_nid_postfix(int, ResourceLimit*); int APS5_VABI setrlimit_nid_postfix(int, const ResourceLimit*); int* APS5_VABI __error_nid_postfix(); } static constexpr int GUEST_EFAULT = 14; static constexpr int GUEST_EINVAL = 22; static constexpr int GUEST_RLIMIT_DATA = 2; static constexpr int GUEST_RLIMIT_NOFILE = 8; static constexpr int GUEST_RLIM_NLIMITS = 15; static constexpr std::int64_t GUEST_RLIM_INFINITY = std::numeric_limits::max(); static void Require(bool value) { if (!value) std::abort(); } static bool Throws(int resource, const ResourceLimit& limit) { try { setrlimit_nid_postfix(resource, &limit); } catch (const std::runtime_error&) { return true; } return false; } static void RequireError(int resource, const ResourceLimit* limit, int error) { *__error_nid_postfix() = 0; Require(setrlimit_nid_postfix(resource, limit) == -1); Require(*__error_nid_postfix() == error); } int main() { const ResourceLimit infinity{GUEST_RLIM_INFINITY, GUEST_RLIM_INFINITY}; RequireError(-1, nullptr, GUEST_EFAULT); RequireError(GUEST_RLIM_NLIMITS, nullptr, GUEST_EFAULT); RequireError(-1, &infinity, GUEST_EINVAL); RequireError(GUEST_RLIM_NLIMITS, &infinity, GUEST_EINVAL); ResourceLimit current{}; Require(getrlimit_nid_postfix(GUEST_RLIMIT_DATA, ¤t) == 0); *__error_nid_postfix() = 13; Require(setrlimit_nid_postfix(GUEST_RLIMIT_DATA, ¤t) == 0); Require(*__error_nid_postfix() == 13); if (current.rlim_cur > 0) { const ResourceLimit changed{current.rlim_cur - 1, current.rlim_max}; Require(Throws(GUEST_RLIMIT_DATA, changed)); } const ResourceLimit softAboveHard{GUEST_RLIM_INFINITY, current.rlim_max}; if (current.rlim_cur == current.rlim_max) Require(setrlimit_nid_postfix(GUEST_RLIMIT_DATA, &softAboveHard) == 0); else Require(Throws(GUEST_RLIMIT_DATA, softAboveHard)); const ResourceLimit negative{-1, -2}; if (current.rlim_cur == GUEST_RLIM_INFINITY && current.rlim_max == GUEST_RLIM_INFINITY) Require(setrlimit_nid_postfix(GUEST_RLIMIT_DATA, &negative) == 0); else Require(Throws(GUEST_RLIMIT_DATA, negative)); Require(Throws(GUEST_RLIMIT_NOFILE, infinity)); return 0; }