diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index 76bf89b5e32..c5a4f900a04 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -16,7 +16,7 @@ #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" #include "core/libraries/network/net.h" -#include "epoll.h" + #include "net_error.h" #include "sockets.h" @@ -555,13 +555,69 @@ int PS4_SYSV_ABI sceNetEpollAbort() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetEpollControl() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI sceNetEpollControl(OrbisNetId eid, int op, OrbisNetId id, + OrbisNetEpollEvent* event) { + auto* net_epoll = Common::Singleton::Instance(); + auto epoll = net_epoll->FindEpoll(eid); + if (!epoll) { + net_errno = ORBIS_NET_EBADF; + LOG_ERROR(Lib_Net, "epoll id is invalid = {}", eid); + return ORBIS_NET_ERROR_EBADF; + } + if (id == 100) { + UNREACHABLE_MSG("Hitted resolver id not supported"); + } + auto* socket_call = Common::Singleton::Instance(); + auto sock = socket_call->FindSocket(id); + if (!sock) { + net_errno = ORBIS_NET_EBADF; + LOG_ERROR(Lib_Net, "socket id is invalid = {}", id); + return ORBIS_NET_ERROR_EBADF; + } + auto posixSocket = std::dynamic_pointer_cast(sock); + if (!posixSocket) { + net_errno = ORBIS_NET_EBADF; + LOG_ERROR(Lib_Net, "Can't create posix socket"); + return ORBIS_NET_ERROR_EBADF; + } + + switch (op) { + case ORBIS_NET_EPOLL_CTL_ADD: { + int add = epoll->Add(id, posixSocket->sock, event); + if (add == ORBIS_NET_ERROR_EEXIST) { + net_errno = ORBIS_NET_EEXIST; + LOG_ERROR(Lib_Net, "epoll event already added"); + return ORBIS_NET_ERROR_EEXIST; + } + return ORBIS_OK; + } + case ORBIS_NET_EPOLL_CTL_DEL: { + int del = epoll->Del(id, posixSocket->sock, event); + if (del == ORBIS_NET_ERROR_ENOENT) { + net_errno = ORBIS_NET_ENOENT; + LOG_ERROR(Lib_Net, "no epoll event in wait state"); + return ORBIS_NET_ERROR_ENOENT; + } + return ORBIS_OK; + } + case ORBIS_NET_EPOLL_CTL_MOD: { + int mod = epoll->Mod(id, posixSocket->sock, event); + if (mod == ORBIS_NET_ERROR_ENOENT) { + net_errno = ORBIS_NET_ENOENT; + LOG_ERROR(Lib_Net, "no epoll event in wait state"); + return ORBIS_NET_ERROR_ENOENT; + } + return ORBIS_OK; + } + default: + net_errno = ORBIS_NET_EINVAL; + LOG_ERROR(Lib_Net, "Unknown operation = {}", op); + return ORBIS_NET_ERROR_EINVAL; + } } int PS4_SYSV_ABI sceNetEpollCreate(const char* name, int flags) { - LOG_ERROR(Lib_Net, "name = {} flags= {}", std::string(name), flags); + LOG_DEBUG(Lib_Net, "name = {} flags= {}", std::string(name), flags); auto* net_epoll = Common::Singleton::Instance(); auto epoll = std::make_shared(); auto id = ++net_epoll->next_epool_sock_id; @@ -570,7 +626,12 @@ int PS4_SYSV_ABI sceNetEpollCreate(const char* name, int flags) { } int PS4_SYSV_ABI sceNetEpollDestroy(int eid) { - LOG_ERROR(Lib_Net, "(STUBBED) called"); + auto* net_epoll = Common::Singleton::Instance(); + if (net_epoll->EraseEpoll(eid) == 0) { + net_errno = ORBIS_NET_EBADF; + LOG_ERROR(Lib_Net, "Error deleting eid = {}", eid); + return ORBIS_NET_ERROR_EBADF; + } return ORBIS_OK; } diff --git a/src/core/libraries/network/net.h b/src/core/libraries/network/net.h index eb1d0796a17..c40fce7c23c 100644 --- a/src/core/libraries/network/net.h +++ b/src/core/libraries/network/net.h @@ -4,6 +4,7 @@ #pragma once #include "common/types.h" +#include "epoll.h" namespace Core::Loader { class SymbolsResolver; @@ -198,7 +199,8 @@ int PS4_SYSV_ABI sceNetDumpRead(); int PS4_SYSV_ABI sceNetDuplicateIpStart(); int PS4_SYSV_ABI sceNetDuplicateIpStop(); int PS4_SYSV_ABI sceNetEpollAbort(); -int PS4_SYSV_ABI sceNetEpollControl(); +int PS4_SYSV_ABI sceNetEpollControl(OrbisNetId eid, int op, OrbisNetId id, + OrbisNetEpollEvent* event); int PS4_SYSV_ABI sceNetEpollCreate(const char* name, int flags); int PS4_SYSV_ABI sceNetEpollDestroy(int eid); int PS4_SYSV_ABI sceNetEpollWait();