Register sockets in the file descriptors table

This commit is contained in:
Marcin Mikołajczyk 2025-07-12 16:11:32 +01:00
parent 71d38669c2
commit 80a6ce0251
4 changed files with 89 additions and 43 deletions

View File

@ -257,6 +257,8 @@ s32 PS4_SYSV_ABI close(s32 fd) {
} }
if (file->type == Core::FileSys::FileType::Regular) { if (file->type == Core::FileSys::FileType::Regular) {
file->f.Close(); file->f.Close();
} else if (file->type == Core::FileSys::FileType::Regular) {
file->socket->Close();
} }
file->is_opened = false; file->is_opened = false;
LOG_INFO(Kernel_Fs, "Closing {}", file->m_guest_name); LOG_INFO(Kernel_Fs, "Closing {}", file->m_guest_name);
@ -294,6 +296,13 @@ s64 PS4_SYSV_ABI write(s32 fd, const void* buf, size_t nbytes) {
return -1; return -1;
} }
return result; return result;
} else if (file->type == Core::FileSys::FileType::Socket) {
s64 result = ::write(file->socket->Native(), buf, nbytes);
if (result < 0) {
ErrSceToPosix(result);
return -1;
}
return result;
} }
return file->f.WriteRaw<u8>(buf, nbytes); return file->f.WriteRaw<u8>(buf, nbytes);
@ -475,6 +484,13 @@ s64 PS4_SYSV_ABI read(s32 fd, void* buf, size_t nbytes) {
return -1; return -1;
} }
return result; return result;
} else if (file->type == Core::FileSys::FileType::Socket) {
s64 result = ::read(file->socket->Native(), buf, nbytes);
if (result < 0) {
ErrSceToPosix(result);
return -1;
}
return result;
} }
return ReadFile(file->f, buf, nbytes); return ReadFile(file->f, buf, nbytes);
} }

View File

@ -216,13 +216,14 @@ s32 PS4_SYSV_ABI posix_getpagesize() {
s32 PS4_SYSV_ABI posix_getsockname(Libraries::Net::OrbisNetId s, s32 PS4_SYSV_ABI posix_getsockname(Libraries::Net::OrbisNetId s,
Libraries::Net::OrbisNetSockaddr* addr, u32* paddrlen) { Libraries::Net::OrbisNetSockaddr* addr, u32* paddrlen) {
LOG_DEBUG(Lib_Net, "s = {}", s); LOG_DEBUG(Lib_Net, "s = {}", s);
auto* netcall = Common::Singleton<Libraries::Net::NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto sock = netcall->FindSocket(s); auto* file = h->GetFile(s);
if (!sock) { if (!file || file->type != Core::FileSys::FileType::Socket) {
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1; return -1;
} }
auto sock = file->socket;
s32 returncode = sock->GetSocketAddress(addr, paddrlen); s32 returncode = sock->GetSocketAddress(addr, paddrlen);
if (returncode >= 0) { if (returncode >= 0) {
LOG_DEBUG(Lib_Net, "return code : {:#x}", (u32)returncode); LOG_DEBUG(Lib_Net, "return code : {:#x}", (u32)returncode);

View File

@ -16,6 +16,7 @@
#include "common/error.h" #include "common/error.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/singleton.h" #include "common/singleton.h"
#include "core/file_sys/fs.h"
#include "core/libraries/error_codes.h" #include "core/libraries/error_codes.h"
#include "core/libraries/libs.h" #include "core/libraries/libs.h"
#include "core/libraries/network/net.h" #include "core/libraries/network/net.h"
@ -761,7 +762,13 @@ int PS4_SYSV_ABI sceNetEpollControl(OrbisNetId epollid, OrbisNetEpollFlag op, Or
} }
#ifdef __linux__ #ifdef __linux__
const auto socket = Common::Singleton<NetInternal>::Instance()->socks[id]; // const auto socket = Common::Singleton<NetInternal>::Instance()->socks[id];
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* file = h->GetFile(id);
if (!file || file->type != Core::FileSys::FileType::Socket) {
return -ORBIS_NET_EBADF;
}
const auto socket = file->socket;
epoll_event native_event = {.events = ConvertEpollEventsIn(event->events), epoll_event native_event = {.events = ConvertEpollEventsIn(event->events),
.data = {.fd = id}}; .data = {.fd = id}};
ASSERT(epoll_ctl(epolls[epollid].epoll_fd, EPOLL_CTL_ADD, socket->Native(), ASSERT(epoll_ctl(epolls[epollid].epoll_fd, EPOLL_CTL_ADD, socket->Native(),

View File

@ -4,6 +4,7 @@
#include <common/assert.h> #include <common/assert.h>
#include <common/logging/log.h> #include <common/logging/log.h>
#include <core/libraries/kernel/kernel.h> #include <core/libraries/kernel/kernel.h>
#include "core/file_sys/fs.h"
#include "common/error.h" #include "common/error.h"
#include "common/singleton.h" #include "common/singleton.h"
#include "net_error.h" #include "net_error.h"
@ -15,13 +16,14 @@ namespace Libraries::Net {
int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) { int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
LOG_WARNING(Lib_Net, "s = {}", s); LOG_WARNING(Lib_Net, "s = {}", s);
auto* netcall = Common::Singleton<NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto sock = netcall->FindSocket(s); auto* file = h->GetFile(s);
if (!sock) { if (!file || file->type != Core::FileSys::FileType::Socket) {
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1; return -1;
} }
auto sock = file->socket;
int returncode = sock->Connect(addr, addrlen); int returncode = sock->Connect(addr, addrlen);
if (returncode >= 0) { if (returncode >= 0) {
return returncode; return returncode;
@ -34,13 +36,14 @@ int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrle
LOG_DEBUG(Lib_Net, "s = {}, addr = {:#x}, addrlen = {}", s, reinterpret_cast<u64>(addr), LOG_DEBUG(Lib_Net, "s = {}, addr = {:#x}, addrlen = {}", s, reinterpret_cast<u64>(addr),
addrlen); addrlen);
auto* netcall = Common::Singleton<NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto sock = netcall->FindSocket(s); auto* file = h->GetFile(s);
if (!sock) { if (!file || file->type != Core::FileSys::FileType::Socket) {
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1; return -1;
} }
auto sock = file->socket;
int returncode = sock->Bind(addr, addrlen); int returncode = sock->Bind(addr, addrlen);
if (returncode >= 0) { if (returncode >= 0) {
return returncode; return returncode;
@ -52,13 +55,14 @@ int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrle
int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) { int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
LOG_WARNING(Lib_Net, "(DUMMY) called"); LOG_WARNING(Lib_Net, "(DUMMY) called");
auto* netcall = Common::Singleton<NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto sock = netcall->FindSocket(s); auto* file = h->GetFile(s);
if (!sock) { if (!file || file->type != Core::FileSys::FileType::Socket) {
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1; return -1;
} }
auto sock = file->socket;
auto new_sock = sock->Accept(addr, paddrlen); auto new_sock = sock->Accept(addr, paddrlen);
if (!new_sock) { if (!new_sock) {
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
@ -66,9 +70,12 @@ int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen)
Common::GetLastErrorMsg()); Common::GetLastErrorMsg());
return -1; return -1;
} }
auto id = ++netcall->next_sock_id; u32 handle = h->CreateHandle();
netcall->socks.emplace(id, new_sock); auto* new_file = h->GetFile(handle);
return id; new_file->is_opened = true;
new_file->type = Core::FileSys::FileType::Socket;
new_file->socket = new_sock;
return handle;
} }
int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, const OrbisNetSockaddr* addr, u32* paddrlen) { int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, const OrbisNetSockaddr* addr, u32* paddrlen) {
LOG_ERROR(Lib_Net, "(STUBBED) called"); LOG_ERROR(Lib_Net, "(STUBBED) called");
@ -77,13 +84,14 @@ int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, const OrbisNetSockaddr* addr, u32
int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) { int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
LOG_WARNING(Lib_Net, "(DUMMY) called"); LOG_WARNING(Lib_Net, "(DUMMY) called");
auto* netcall = Common::Singleton<NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto sock = netcall->FindSocket(s); auto* file = h->GetFile(s);
if (!sock) { if (!file || file->type != Core::FileSys::FileType::Socket) {
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1; return -1;
} }
auto sock = file->socket;
int returncode = sock->GetSocketAddress(addr, paddrlen); int returncode = sock->GetSocketAddress(addr, paddrlen);
if (returncode >= 0) { if (returncode >= 0) {
return returncode; return returncode;
@ -95,13 +103,14 @@ int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* padd
int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) { int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) {
LOG_WARNING(Lib_Net, "(DUMMY) called"); LOG_WARNING(Lib_Net, "(DUMMY) called");
auto* netcall = Common::Singleton<NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto sock = netcall->FindSocket(s); auto* file = h->GetFile(s);
if (!sock) { if (!file || file->type != Core::FileSys::FileType::Socket) {
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1; return -1;
} }
auto sock = file->socket;
int returncode = sock->GetSocketOptions(level, optname, optval, optlen); int returncode = sock->GetSocketOptions(level, optname, optval, optlen);
if (returncode >= 0) { if (returncode >= 0) {
return returncode; return returncode;
@ -113,13 +122,14 @@ int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optv
int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) { int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
LOG_DEBUG(Lib_Net, "s = {}, backlog = {}", s, backlog); LOG_DEBUG(Lib_Net, "s = {}, backlog = {}", s, backlog);
auto* netcall = Common::Singleton<NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto sock = netcall->FindSocket(s); auto* file = h->GetFile(s);
if (!sock) { if (!file || file->type != Core::FileSys::FileType::Socket) {
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1; return -1;
} }
auto sock = file->socket;
int returncode = sock->Listen(backlog); int returncode = sock->Listen(backlog);
if (returncode >= 0) { if (returncode >= 0) {
return returncode; return returncode;
@ -133,13 +143,14 @@ int PS4_SYSV_ABI sys_setsockopt(OrbisNetId s, int level, int optname, const void
u32 optlen) { u32 optlen) {
LOG_WARNING(Lib_Net, "netId = {}", s); LOG_WARNING(Lib_Net, "netId = {}", s);
auto* netcall = Common::Singleton<NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto sock = netcall->FindSocket(s); auto* file = h->GetFile(s);
if (!sock) { if (!file || file->type != Core::FileSys::FileType::Socket) {
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1; return -1;
} }
auto sock = file->socket;
int returncode = sock->SetSocketOptions(level, optname, optval, optlen); int returncode = sock->SetSocketOptions(level, optname, optval, optlen);
LOG_INFO(Lib_Net, "returncode = {}", returncode); LOG_INFO(Lib_Net, "returncode = {}", returncode);
if (returncode >= 0) { if (returncode >= 0) {
@ -181,10 +192,16 @@ int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protoc
default: default:
UNREACHABLE_MSG("Unknown type {}", type); UNREACHABLE_MSG("Unknown type {}", type);
} }
auto* netcall = Common::Singleton<NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto id = ++netcall->next_sock_id; u32 handle = h->CreateHandle();
netcall->socks.emplace(id, sock); auto* file = h->GetFile(handle);
return id; file->is_opened = true;
file->type = Core::FileSys::FileType::Socket;
file->socket = sock;
// auto* netcall = Common::Singleton<NetInternal>::Instance();
// auto id = ++netcall->next_sock_id;
// netcall->socks.emplace(id, sock);
return handle;
} }
int PS4_SYSV_ABI sys_socket(int family, int type, int protocol) { int PS4_SYSV_ABI sys_socket(int family, int type, int protocol) {
return sys_socketex(nullptr, family, type, protocol); return sys_socketex(nullptr, family, type, protocol);
@ -194,16 +211,19 @@ int PS4_SYSV_ABI sys_netabort(OrbisNetId s, int flags) {
return -1; return -1;
} }
int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) { int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
LOG_WARNING(Lib_Net, "(DUMMY) called"); LOG_INFO(Lib_Net, "called, s = {}", s);
auto* netcall = Common::Singleton<NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto sock = netcall->FindSocket(s); auto* file = h->GetFile(s);
if (!sock) { if (!file || file->type != Core::FileSys::FileType::Socket) {
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1; return -1;
} }
auto sock = file->socket;
file->is_opened = false;
int returncode = sock->Close(); int returncode = sock->Close();
h->DeleteHandle(s);
if (returncode >= 0) { if (returncode >= 0) {
return returncode; return returncode;
} }
@ -215,13 +235,14 @@ int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
const OrbisNetSockaddr* addr, u32 addrlen) { const OrbisNetSockaddr* addr, u32 addrlen) {
LOG_WARNING(Lib_Net, "s = {}, len = {}, flags = {:#x}, addrlen = {}", s, len, flags, addrlen); LOG_WARNING(Lib_Net, "s = {}, len = {}, flags = {:#x}, addrlen = {}", s, len, flags, addrlen);
auto* netcall = Common::Singleton<NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto sock = netcall->FindSocket(s); auto* file = h->GetFile(s);
if (!sock) { if (!file || file->type != Core::FileSys::FileType::Socket) {
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1; return -1;
} }
auto sock = file->socket;
int returncode = sock->SendPacket(buf, len, flags, addr, addrlen); int returncode = sock->SendPacket(buf, len, flags, addr, addrlen);
if (returncode >= 0) { if (returncode >= 0) {
return returncode; return returncode;
@ -239,13 +260,14 @@ int PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, Orbis
// LOG_INFO(Lib_Net, "s = {}, buf = {:#x}, len = {}, flags = {:#x}", s, // LOG_INFO(Lib_Net, "s = {}, buf = {:#x}, len = {}, flags = {:#x}", s,
// reinterpret_cast<u64>(buf), len, flags); // reinterpret_cast<u64>(buf), len, flags);
auto* netcall = Common::Singleton<NetInternal>::Instance(); auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto sock = netcall->FindSocket(s); auto* file = h->GetFile(s);
if (!sock) { if (!file || file->type != Core::FileSys::FileType::Socket) {
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF; *Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s); LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
return -1; return -1;
} }
auto sock = file->socket;
int returncode = sock->ReceivePacket(buf, len, flags, addr, paddrlen); int returncode = sock->ReceivePacket(buf, len, flags, addr, paddrlen);
if (returncode >= 0) { if (returncode >= 0) {
return returncode; return returncode;