From 9fb83a2435b62a0cbede106292715c4609314b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Franch?= Date: Tue, 6 Oct 2026 01:40:35 +0200 Subject: [PATCH] feat(libSceNet): implement sceNetResolverGetError Co-Authored-By: Claude --- core/libs/prx/libSceNet/Export.cpp | 22 ++++++++++++++++++---- core/libs/tests/GuestSceNet.cpp | 15 +++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/core/libs/prx/libSceNet/Export.cpp b/core/libs/prx/libSceNet/Export.cpp index c5a55aa7f..4e00b3034 100644 --- a/core/libs/prx/libSceNet/Export.cpp +++ b/core/libs/prx/libSceNet/Export.cpp @@ -202,7 +202,7 @@ std::set g_epolls; std::map> g_epoll_socks; std::set g_epoll_aborted; std::set g_pools; -std::set g_resolvers; +std::map g_resolvers; int g_next_sock = 32; int g_next_epoll = 0x4000; int g_next_pool = 1; @@ -219,6 +219,12 @@ int fail(int err) { return NET_ERROR_BASE | err; } +void set_resolver_error(int rid, int error) { + std::lock_guard lk(g_mutex); + const auto resolver = g_resolvers.find(rid); + if (resolver != g_resolvers.end()) resolver->second = error; +} + void log_soft(const char* func, const char* what) { static std::mutex mtx; static std::map hits; @@ -859,7 +865,7 @@ int APS5_VABI sceNetResolverCreate(const char* name, int memid, int flags) { (void)flags; std::lock_guard lk(g_mutex); const int id = g_next_resolver++; - g_resolvers.insert(id); + g_resolvers[id] = 0; return id; } @@ -885,11 +891,13 @@ int APS5_VABI sceNetResolverStartNtoa(int rid, const char* hostname, void* addr, if (result != 0) { *errno_slot() = result == EAI_AGAIN ? NET_ETIMEDOUT : NET_ENOENT; log_soft(__func__, "host DNS lookup failed"); + set_resolver_error(rid, NET_ERROR_RESOLVER_ENODNS); return NET_ERROR_RESOLVER_ENODNS; } const auto* address = reinterpret_cast(results->ai_addr); std::memcpy(addr, &address->sin_addr, sizeof(address->sin_addr)); ::freeaddrinfo(results); + set_resolver_error(rid, 0); return 0; } @@ -911,13 +919,19 @@ int APS5_VABI sceNetResolverStartAton(int rid, const void* addr, char* hostname, if (result != 0) { *errno_slot() = result == EAI_AGAIN ? NET_ETIMEDOUT : NET_ENOENT; log_soft(__func__, "host reverse DNS lookup failed"); + set_resolver_error(rid, NET_ERROR_RESOLVER_ENODNS); return NET_ERROR_RESOLVER_ENODNS; } + set_resolver_error(rid, 0); return 0; } -int APS5_VABI sceNetResolverGetError(void) { - NotImplemented_nid_no_patch(__func__); +int APS5_VABI sceNetResolverGetError(int rid, int* status) { + if (!status) return fail(NET_EINVAL); + std::lock_guard lk(g_mutex); + const auto resolver = g_resolvers.find(rid); + if (resolver == g_resolvers.end()) return fail(NET_EBADF); + *status = resolver->second; return 0; } diff --git a/core/libs/tests/GuestSceNet.cpp b/core/libs/tests/GuestSceNet.cpp index 48fcdcea1..5237bfe9a 100644 --- a/core/libs/tests/GuestSceNet.cpp +++ b/core/libs/tests/GuestSceNet.cpp @@ -29,6 +29,7 @@ int APS5_VABI sceNetEpollDestroy(int); int APS5_VABI sceNetResolverCreate(const char*, int, int); int APS5_VABI sceNetResolverStartNtoa(int, const char*, void*, int, int, int); int APS5_VABI sceNetResolverDestroy(int); +int APS5_VABI sceNetResolverGetError(int, int*); int APS5_VABI sceNetCtlGetState(int*); int APS5_VABI sceNetInetPton(int, const char*, void*); const char* APS5_VABI sceNetInetNtop(int, const void*, char*, std::uint32_t); @@ -109,10 +110,24 @@ int main() { const int resolver = sceNetResolverCreate("guest-sce-net", 0, 0); Require(resolver >= 0); + int resolver_error = -1; + Require(sceNetResolverGetError(resolver, &resolver_error) == 0 && resolver_error == 0); std::array ipv4{}; + Require(sceNetResolverStartNtoa(resolver, "guest-sce-net.invalid", ipv4.data(), 5000000, 1, 0) == + static_cast(0x804101E1)); + Require(sceNetResolverGetError(resolver, &resolver_error) == 0 && + resolver_error == static_cast(0x804101E1)); + Require(sceNetResolverStartNtoa(resolver, nullptr, ipv4.data(), 5000000, 1, 0) == static_cast(0x80410116)); + Require(sceNetResolverGetError(resolver, &resolver_error) == 0 && + resolver_error == static_cast(0x804101E1)); Require(sceNetResolverStartNtoa(resolver, "localhost", ipv4.data(), 5000000, 1, 0) == 0); Require(ipv4[0] == 127); + Require(sceNetResolverGetError(resolver, &resolver_error) == 0 && resolver_error == 0); + Require(sceNetResolverGetError(resolver, nullptr) == static_cast(0x80410116) && *sceNetErrnoLoc() == 22); Require(sceNetResolverDestroy(resolver) == 0); + resolver_error = -1; + Require(sceNetResolverGetError(resolver, &resolver_error) == static_cast(0x80410109) && + *sceNetErrnoLoc() == 9 && resolver_error == -1); std::array ipv6{}; Require(sceNetInetPton(28, "::1", ipv6.data()) == 1);