diff --git a/core/libs/prx/libSceNet/Export.cpp b/core/libs/prx/libSceNet/Export.cpp index ce94422d82..9bed366baf 100644 --- a/core/libs/prx/libSceNet/Export.cpp +++ b/core/libs/prx/libSceNet/Export.cpp @@ -1464,11 +1464,18 @@ int APS5_VABI sceNetSetsockopt(int s, int level, int optname, const void* optval int APS5_VABI sceNetGetsockopt(int s, int level, int optname, void* optval, uint32_t* optlen) { Sock socket; + bool found = false; { std::lock_guard lk(g_mutex); auto it = g_socks.find(s); - if (it == g_socks.end()) return fail(NET_EBADF); - socket = it->second; + if (it != g_socks.end()) { + socket = it->second; + found = true; + } + } + if (!found) { + if (!GuestSocketIsOpen_nid_no_patch(s)) return fail(NET_EBADF); + return getsockopt_nid_postfix(s, level, optname, optval, optlen) == 0 ? 0 : fail(*__error_nid_postfix()); } if (optval == nullptr || optlen == nullptr) return fail(NET_EINVAL); if (level == NET_SOL_SOCKET && optname == NET_SO_PROTOCOL) { diff --git a/core/libs/tests/GuestSceNet.cpp b/core/libs/tests/GuestSceNet.cpp index 67ef1daf4a..b24b03ec3e 100644 --- a/core/libs/tests/GuestSceNet.cpp +++ b/core/libs/tests/GuestSceNet.cpp @@ -1508,6 +1508,27 @@ static void CheckCloseKernelSocket() { Require(Failed(sceNetSocketClose(kernel), 9)); } +static void CheckKernelSocketGetOption() { + const int kernel = socket_nid_postfix(2, 1, 0); + Require(kernel >= 0); + const int requested = 65536; + Require(sceNetSetsockopt(kernel, 0xffff, 0x1001, &requested, sizeof(requested)) == 0); + int value = 0; + std::uint32_t size = sizeof(value); + Require(sceNetGetsockopt(kernel, 0xffff, 0x1001, &value, &size) == 0 && size == sizeof(value) && value > 0); + int expected = 0; + std::uint32_t expectedSize = sizeof(expected); + Require(getsockopt_nid_postfix(kernel, 0xffff, 0x1001, &expected, &expectedSize) == 0 && value == expected); + const int one = 1; + Require(sceNetSetsockopt(kernel, 6, 1, &one, sizeof(one)) == 0); + value = 0; + size = sizeof(value); + Require(sceNetGetsockopt(kernel, 6, 1, &value, &size) == 0 && value != 0); + Require(Failed(sceNetGetsockopt(kernel, 1234, 1, &value, &size), 22)); + Require(close_nid_postfix(kernel) == 0); + Require(Failed(sceNetGetsockopt(kernel, 0xffff, 0x1001, &value, &size), 9)); +} + static std::array RequireSockInfo(int socket, int type, int flags, const std::array& local, const std::array& remote) { std::array records; @@ -1897,6 +1918,7 @@ int main() { } CheckDatagramDisconnect(); CheckCloseKernelSocket(); + CheckKernelSocketGetOption(); CheckSockInfo(); CheckSockInfo6();