mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-02 15:32:52 +00:00
Sockets are now files (#3319)
* Socket support for read/write/fstat * Sockets are now files * Fix ssize_t for windows * Return posix error codes in net functions
This commit is contained in:
parent
93767ae31b
commit
26a92d97fa
@ -219,6 +219,18 @@ File* HandleTable::GetFile(int d) {
|
||||
return m_files.at(d);
|
||||
}
|
||||
|
||||
File* HandleTable::GetSocket(int d) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
if (d < 0 || d >= m_files.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto file = m_files.at(d);
|
||||
if (file->type != Core::FileSys::FileType::Socket) {
|
||||
return nullptr;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
File* HandleTable::GetFile(const std::filesystem::path& host_name) {
|
||||
for (auto* file : m_files) {
|
||||
if (file != nullptr && file->m_host_name == host_name) {
|
||||
|
@ -12,6 +12,10 @@
|
||||
#include "common/logging/formatter.h"
|
||||
#include "core/devices/base_device.h"
|
||||
|
||||
namespace Libraries::Net {
|
||||
struct Socket;
|
||||
}
|
||||
|
||||
namespace Core::FileSys {
|
||||
|
||||
class MntPoints {
|
||||
@ -77,6 +81,7 @@ enum class FileType {
|
||||
Regular, // standard file
|
||||
Directory,
|
||||
Device,
|
||||
Socket,
|
||||
};
|
||||
|
||||
struct File {
|
||||
@ -88,7 +93,8 @@ struct File {
|
||||
std::vector<DirEntry> dirents;
|
||||
u32 dirents_index;
|
||||
std::mutex m_mutex;
|
||||
std::shared_ptr<Devices::BaseDevice> device; // only valid for type == Device
|
||||
std::shared_ptr<Devices::BaseDevice> device; // only valid for type == Device
|
||||
std::shared_ptr<Libraries::Net::Socket> socket; // only valid for type == Socket
|
||||
};
|
||||
|
||||
class HandleTable {
|
||||
@ -99,6 +105,7 @@ public:
|
||||
int CreateHandle();
|
||||
void DeleteHandle(int d);
|
||||
File* GetFile(int d);
|
||||
File* GetSocket(int d);
|
||||
File* GetFile(const std::filesystem::path& host_name);
|
||||
int GetFileDescriptor(File* file);
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "core/libraries/kernel/orbis_error.h"
|
||||
#include "core/libraries/kernel/posix_error.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/libraries/network/sockets.h"
|
||||
#include "core/memory.h"
|
||||
#include "kernel.h"
|
||||
|
||||
@ -257,6 +258,8 @@ s32 PS4_SYSV_ABI close(s32 fd) {
|
||||
}
|
||||
if (file->type == Core::FileSys::FileType::Regular) {
|
||||
file->f.Close();
|
||||
} else if (file->type == Core::FileSys::FileType::Socket) {
|
||||
file->socket->Close();
|
||||
}
|
||||
file->is_opened = false;
|
||||
LOG_INFO(Kernel_Fs, "Closing {}", file->m_guest_name);
|
||||
@ -294,6 +297,13 @@ s64 PS4_SYSV_ABI write(s32 fd, const void* buf, size_t nbytes) {
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
} else if (file->type == Core::FileSys::FileType::Socket) {
|
||||
s64 result = file->socket->SendPacket(buf, nbytes, 0, nullptr, 0);
|
||||
if (result < 0) {
|
||||
ErrSceToPosix(result);
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return file->f.WriteRaw<u8>(buf, nbytes);
|
||||
@ -475,6 +485,13 @@ s64 PS4_SYSV_ABI read(s32 fd, void* buf, size_t nbytes) {
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
} else if (file->type == Core::FileSys::FileType::Socket) {
|
||||
s64 result = file->socket->ReceivePacket(buf, nbytes, 0, nullptr, 0);
|
||||
if (result < 0) {
|
||||
ErrSceToPosix(result);
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return ReadFile(file->f, buf, nbytes);
|
||||
}
|
||||
@ -667,6 +684,14 @@ s32 PS4_SYSV_ABI fstat(s32 fd, OrbisKernelStat* sb) {
|
||||
// TODO incomplete
|
||||
break;
|
||||
}
|
||||
case Core::FileSys::FileType::Socket: {
|
||||
s32 result = file->socket->fstat(sb);
|
||||
if (result < 0) {
|
||||
ErrSceToPosix(result);
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -222,14 +222,15 @@ s32 PS4_SYSV_ABI posix_getpagesize() {
|
||||
|
||||
s32 PS4_SYSV_ABI posix_getsockname(Libraries::Net::OrbisNetId s,
|
||||
Libraries::Net::OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||
auto* netcall = Common::Singleton<Libraries::Net::NetInternal>::Instance();
|
||||
auto sock = netcall->FindSocket(s);
|
||||
if (!sock) {
|
||||
LOG_INFO(Lib_Kernel, "s = {}", s);
|
||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||
auto file = h->GetSocket(s);
|
||||
if (!file) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||
return -1;
|
||||
}
|
||||
s32 returncode = sock->GetSocketAddress(addr, paddrlen);
|
||||
s32 returncode = file->socket->GetSocketAddress(addr, paddrlen);
|
||||
if (returncode >= 0) {
|
||||
LOG_ERROR(Lib_Net, "return code : {:#x}", (u32)returncode);
|
||||
return 0;
|
||||
|
@ -20,6 +20,8 @@ class SymbolsResolver;
|
||||
|
||||
namespace Libraries::Net {
|
||||
|
||||
static int ConvertFamilies(int family);
|
||||
|
||||
enum OrbisNetFamily : u32 {
|
||||
ORBIS_NET_AF_INET = 2,
|
||||
ORBIS_NET_AF_INET6 = 28,
|
||||
|
@ -57,4 +57,9 @@ int P2PSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int P2PSocket::fstat(Libraries::Kernel::OrbisKernelStat* stat) {
|
||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Libraries::Net
|
@ -2,7 +2,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <common/assert.h>
|
||||
#include "common/error.h"
|
||||
#include "core/libraries/kernel/file_system.h"
|
||||
#include "net.h"
|
||||
#ifndef _WIN32
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include "net_error.h"
|
||||
#include "sockets.h"
|
||||
|
||||
@ -142,6 +147,14 @@ static void convertPosixSockaddrToOrbis(sockaddr* src, OrbisNetSockaddr* dst) {
|
||||
memcpy(&dst_in->sin_addr, &src_in->sin_addr, 4);
|
||||
}
|
||||
|
||||
bool PosixSocket::IsValid() const {
|
||||
#ifdef _WIN32
|
||||
return sock != INVALID_SOCKET;
|
||||
#else
|
||||
return sock != -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int PosixSocket::Close() {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
#ifdef _WIN32
|
||||
@ -194,14 +207,17 @@ int PosixSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr*
|
||||
SocketPtr PosixSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
sockaddr addr2;
|
||||
net_socket new_socket = ::accept(sock, &addr2, (socklen_t*)addrlen);
|
||||
socklen_t len = sizeof(addr2);
|
||||
net_socket new_socket = ::accept(sock, &addr2, &len);
|
||||
#ifdef _WIN32
|
||||
if (new_socket != INVALID_SOCKET) {
|
||||
#else
|
||||
if (new_socket >= 0) {
|
||||
#endif
|
||||
convertPosixSockaddrToOrbis(&addr2, addr);
|
||||
*addrlen = sizeof(OrbisNetSockaddrIn);
|
||||
if (addr && addrlen) {
|
||||
convertPosixSockaddrToOrbis(&addr2, addr);
|
||||
*addrlen = sizeof(OrbisNetSockaddrIn);
|
||||
}
|
||||
return std::make_shared<PosixSocket>(new_socket);
|
||||
}
|
||||
return nullptr;
|
||||
@ -211,7 +227,13 @@ int PosixSocket::Connect(const OrbisNetSockaddr* addr, u32 namelen) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
sockaddr addr2;
|
||||
convertOrbisNetSockaddrToPosix(addr, &addr2);
|
||||
return ::connect(sock, &addr2, sizeof(sockaddr_in));
|
||||
int result = 0;
|
||||
do {
|
||||
result = ::connect(sock, &addr2, sizeof(sockaddr_in));
|
||||
LOG_DEBUG(Lib_Net, "raw connect result = {}, errno = {}", result,
|
||||
result == -1 ? Common::GetLastErrorMsg() : "none");
|
||||
} while (result == -1 && (errno == EINTR || errno == EINPROGRESS));
|
||||
return ConvertReturnErrorCode(result);
|
||||
}
|
||||
|
||||
int PosixSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) {
|
||||
@ -394,4 +416,21 @@ int PosixSocket::GetSocketOptions(int level, int optname, void* optval, u32* opt
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PosixSocket::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
|
||||
#ifdef _WIN32
|
||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||
sb->st_mode = 0000777u | 0140000u;
|
||||
return 0;
|
||||
#else
|
||||
struct stat st{};
|
||||
int result = ::fstat(sock, &st);
|
||||
sb->st_mode = 0000777u | 0140000u;
|
||||
sb->st_size = st.st_size;
|
||||
sb->st_blocks = st.st_blocks;
|
||||
sb->st_blksize = st.st_blksize;
|
||||
// sb->st_flags = st.st_flags;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Libraries::Net
|
@ -26,6 +26,10 @@ typedef int net_socket;
|
||||
#include <mutex>
|
||||
#include "net.h"
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
struct OrbisKernelStat;
|
||||
}
|
||||
|
||||
namespace Libraries::Net {
|
||||
|
||||
struct Socket;
|
||||
@ -39,6 +43,7 @@ struct OrbisNetLinger {
|
||||
struct Socket {
|
||||
explicit Socket(int domain, int type, int protocol) {}
|
||||
virtual ~Socket() = default;
|
||||
virtual bool IsValid() const = 0;
|
||||
virtual int Close() = 0;
|
||||
virtual int SetSocketOptions(int level, int optname, const void* optval, u32 optlen) = 0;
|
||||
virtual int GetSocketOptions(int level, int optname, void* optval, u32* optlen) = 0;
|
||||
@ -51,6 +56,7 @@ struct Socket {
|
||||
u32* fromlen) = 0;
|
||||
virtual int Connect(const OrbisNetSockaddr* addr, u32 namelen) = 0;
|
||||
virtual int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) = 0;
|
||||
virtual int fstat(Libraries::Kernel::OrbisKernelStat* stat) = 0;
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
|
||||
@ -71,6 +77,7 @@ struct PosixSocket : public Socket {
|
||||
socket_type = type;
|
||||
}
|
||||
explicit PosixSocket(net_socket sock) : Socket(0, 0, 0), sock(sock) {}
|
||||
bool IsValid() const override;
|
||||
int Close() override;
|
||||
int SetSocketOptions(int level, int optname, const void* optval, u32 optlen) override;
|
||||
int GetSocketOptions(int level, int optname, void* optval, u32* optlen) override;
|
||||
@ -82,10 +89,14 @@ struct PosixSocket : public Socket {
|
||||
SocketPtr Accept(OrbisNetSockaddr* addr, u32* addrlen) override;
|
||||
int Connect(const OrbisNetSockaddr* addr, u32 namelen) override;
|
||||
int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) override;
|
||||
int fstat(Libraries::Kernel::OrbisKernelStat* stat) override;
|
||||
};
|
||||
|
||||
struct P2PSocket : public Socket {
|
||||
explicit P2PSocket(int domain, int type, int protocol) : Socket(domain, type, protocol) {}
|
||||
bool IsValid() const override {
|
||||
return true;
|
||||
}
|
||||
int Close() override;
|
||||
int SetSocketOptions(int level, int optname, const void* optval, u32 optlen) override;
|
||||
int GetSocketOptions(int level, int optname, void* optval, u32* optlen) override;
|
||||
@ -97,25 +108,7 @@ struct P2PSocket : public Socket {
|
||||
SocketPtr Accept(OrbisNetSockaddr* addr, u32* addrlen) override;
|
||||
int Connect(const OrbisNetSockaddr* addr, u32 namelen) override;
|
||||
int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) override;
|
||||
int fstat(Libraries::Kernel::OrbisKernelStat* stat) override;
|
||||
};
|
||||
|
||||
class NetInternal {
|
||||
public:
|
||||
explicit NetInternal() = default;
|
||||
~NetInternal() = default;
|
||||
SocketPtr FindSocket(int sockid) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
const auto it = socks.find(sockid);
|
||||
if (it != socks.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
std::mutex m_mutex;
|
||||
typedef std::map<int, SocketPtr> NetSockets;
|
||||
NetSockets socks;
|
||||
int next_sock_id = 0;
|
||||
};
|
||||
} // namespace Libraries::Net
|
@ -4,22 +4,25 @@
|
||||
#include <common/assert.h>
|
||||
#include <common/logging/log.h>
|
||||
#include <core/libraries/kernel/kernel.h>
|
||||
#include "common/error.h"
|
||||
#include "common/singleton.h"
|
||||
#include "core/file_sys/fs.h"
|
||||
#include "net_error.h"
|
||||
#include "sockets.h"
|
||||
#include "sys_net.h"
|
||||
|
||||
namespace Libraries::Net {
|
||||
|
||||
using FDTable = Common::Singleton<Core::FileSys::HandleTable>;
|
||||
|
||||
int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
|
||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||
auto sock = netcall->FindSocket(s);
|
||||
if (!sock) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||
auto file = FDTable::Instance()->GetSocket(s);
|
||||
if (!file) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||
return -1;
|
||||
}
|
||||
int returncode = sock->Connect(addr, addrlen);
|
||||
int returncode = file->socket->Connect(addr, addrlen);
|
||||
if (returncode >= 0) {
|
||||
return returncode;
|
||||
}
|
||||
@ -28,14 +31,13 @@ int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 add
|
||||
return -1;
|
||||
}
|
||||
int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
|
||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||
auto sock = netcall->FindSocket(s);
|
||||
if (!sock) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||
auto file = FDTable::Instance()->GetSocket(s);
|
||||
if (!file) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||
return -1;
|
||||
}
|
||||
int returncode = sock->Bind(addr, addrlen);
|
||||
int returncode = file->socket->Bind(addr, addrlen);
|
||||
if (returncode >= 0) {
|
||||
return returncode;
|
||||
}
|
||||
@ -44,36 +46,38 @@ int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrle
|
||||
return -1;
|
||||
}
|
||||
int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||
auto sock = netcall->FindSocket(s);
|
||||
if (!sock) {
|
||||
auto file = FDTable::Instance()->GetSocket(s);
|
||||
if (!file) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||
return -1;
|
||||
}
|
||||
auto new_sock = sock->Accept(addr, paddrlen);
|
||||
auto new_sock = file->socket->Accept(addr, paddrlen);
|
||||
if (!new_sock) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||
LOG_ERROR(Lib_Net, "error creating new socket for accepting");
|
||||
LOG_ERROR(Lib_Net, "error creating new socket for accepting: {}",
|
||||
Common::GetLastErrorMsg());
|
||||
return -1;
|
||||
}
|
||||
auto id = ++netcall->next_sock_id;
|
||||
netcall->socks.emplace(id, new_sock);
|
||||
return id;
|
||||
auto fd = FDTable::Instance()->CreateHandle();
|
||||
auto* new_file = FDTable::Instance()->GetFile(fd);
|
||||
new_file->is_opened = true;
|
||||
new_file->type = Core::FileSys::FileType::Socket;
|
||||
new_file->socket = new_sock;
|
||||
return fd;
|
||||
}
|
||||
int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, const OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||
return -1;
|
||||
}
|
||||
int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||
auto sock = netcall->FindSocket(s);
|
||||
if (!sock) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||
auto file = FDTable::Instance()->GetSocket(s);
|
||||
if (!file) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||
return -1;
|
||||
}
|
||||
int returncode = sock->GetSocketAddress(addr, paddrlen);
|
||||
int returncode = file->socket->GetSocketAddress(addr, paddrlen);
|
||||
if (returncode >= 0) {
|
||||
return returncode;
|
||||
}
|
||||
@ -82,14 +86,13 @@ int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* padd
|
||||
return -1;
|
||||
}
|
||||
int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) {
|
||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||
auto sock = netcall->FindSocket(s);
|
||||
if (!sock) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||
auto file = FDTable::Instance()->GetSocket(s);
|
||||
if (!file) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||
return -1;
|
||||
}
|
||||
int returncode = sock->GetSocketOptions(level, optname, optval, optlen);
|
||||
int returncode = file->socket->GetSocketOptions(level, optname, optval, optlen);
|
||||
if (returncode >= 0) {
|
||||
return returncode;
|
||||
}
|
||||
@ -98,14 +101,13 @@ int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optv
|
||||
return -1;
|
||||
}
|
||||
int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
|
||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||
auto sock = netcall->FindSocket(s);
|
||||
if (!sock) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||
auto file = FDTable::Instance()->GetSocket(s);
|
||||
if (!file) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||
return -1;
|
||||
}
|
||||
int returncode = sock->Listen(backlog);
|
||||
int returncode = file->socket->Listen(backlog);
|
||||
if (returncode >= 0) {
|
||||
return returncode;
|
||||
}
|
||||
@ -115,14 +117,13 @@ int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
|
||||
}
|
||||
int PS4_SYSV_ABI sys_setsockopt(OrbisNetId s, int level, int optname, const void* optval,
|
||||
u32 optlen) {
|
||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||
auto sock = netcall->FindSocket(s);
|
||||
if (!sock) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||
auto file = FDTable::Instance()->GetSocket(s);
|
||||
if (!file) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||
return -1;
|
||||
}
|
||||
int returncode = sock->SetSocketOptions(level, optname, optval, optlen);
|
||||
int returncode = file->socket->SetSocketOptions(level, optname, optval, optlen);
|
||||
if (returncode >= 0) {
|
||||
return returncode;
|
||||
}
|
||||
@ -141,24 +142,32 @@ int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protoc
|
||||
LOG_INFO(Lib_Net, "name = {} family = {} type = {} protocol = {}", std::string(name),
|
||||
family, type, protocol);
|
||||
}
|
||||
SocketPtr sock;
|
||||
SocketPtr socket;
|
||||
switch (type) {
|
||||
case ORBIS_NET_SOCK_STREAM:
|
||||
case ORBIS_NET_SOCK_DGRAM:
|
||||
case ORBIS_NET_SOCK_RAW:
|
||||
sock = std::make_shared<PosixSocket>(family, type, protocol);
|
||||
socket = std::make_shared<PosixSocket>(family, type, protocol);
|
||||
break;
|
||||
case ORBIS_NET_SOCK_DGRAM_P2P:
|
||||
case ORBIS_NET_SOCK_STREAM_P2P:
|
||||
sock = std::make_shared<P2PSocket>(family, type, protocol);
|
||||
socket = std::make_shared<P2PSocket>(family, type, protocol);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE_MSG("Unknown type {}", type);
|
||||
}
|
||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||
auto id = ++netcall->next_sock_id;
|
||||
netcall->socks.emplace(id, sock);
|
||||
return id;
|
||||
if (!socket->IsValid()) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EPROTONOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto fd = FDTable::Instance()->CreateHandle();
|
||||
auto* sock = FDTable::Instance()->GetFile(fd);
|
||||
sock->is_opened = true;
|
||||
sock->type = Core::FileSys::FileType::Socket;
|
||||
sock->socket = socket;
|
||||
sock->m_guest_name = name ? name : "anon_sock";
|
||||
return fd;
|
||||
}
|
||||
int PS4_SYSV_ABI sys_socket(int family, int type, int protocol) {
|
||||
return sys_socketex(nullptr, family, type, protocol);
|
||||
@ -168,14 +177,13 @@ int PS4_SYSV_ABI sys_netabort(OrbisNetId s, int flags) {
|
||||
return -1;
|
||||
}
|
||||
int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
|
||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||
auto sock = netcall->FindSocket(s);
|
||||
if (!sock) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||
auto file = FDTable::Instance()->GetSocket(s);
|
||||
if (!file) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||
return -1;
|
||||
}
|
||||
int returncode = sock->Close();
|
||||
int returncode = file->socket->Close();
|
||||
if (returncode >= 0) {
|
||||
return returncode;
|
||||
}
|
||||
@ -185,14 +193,13 @@ int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
|
||||
}
|
||||
int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
||||
const OrbisNetSockaddr* addr, u32 addrlen) {
|
||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||
auto sock = netcall->FindSocket(s);
|
||||
if (!sock) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||
auto file = FDTable::Instance()->GetSocket(s);
|
||||
if (!file) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||
return -1;
|
||||
}
|
||||
int returncode = sock->SendPacket(buf, len, flags, addr, addrlen);
|
||||
int returncode = file->socket->SendPacket(buf, len, flags, addr, addrlen);
|
||||
if (returncode >= 0) {
|
||||
return returncode;
|
||||
}
|
||||
@ -204,16 +211,15 @@ int PS4_SYSV_ABI sys_sendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags)
|
||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||
return -1;
|
||||
}
|
||||
int PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
|
||||
s64 PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
|
||||
u32* paddrlen) {
|
||||
auto* netcall = Common::Singleton<NetInternal>::Instance();
|
||||
auto sock = netcall->FindSocket(s);
|
||||
if (!sock) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_ERROR_EBADF;
|
||||
auto file = FDTable::Instance()->GetSocket(s);
|
||||
if (!file) {
|
||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||
return -1;
|
||||
}
|
||||
int returncode = sock->ReceivePacket(buf, len, flags, addr, paddrlen);
|
||||
int returncode = file->socket->ReceivePacket(buf, len, flags, addr, paddrlen);
|
||||
if (returncode >= 0) {
|
||||
return returncode;
|
||||
}
|
||||
@ -221,7 +227,7 @@ int PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, Orbis
|
||||
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
|
||||
return -1;
|
||||
}
|
||||
int PS4_SYSV_ABI sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) {
|
||||
s64 PS4_SYSV_ABI sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) {
|
||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||
return -1;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ int PS4_SYSV_ABI sys_socketclose(OrbisNetId s);
|
||||
int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
||||
const OrbisNetSockaddr* addr, u32 addrlen);
|
||||
int PS4_SYSV_ABI sys_sendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags);
|
||||
int PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
|
||||
s64 PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
|
||||
u32* paddrlen);
|
||||
int PS4_SYSV_ABI sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags);
|
||||
s64 PS4_SYSV_ABI sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags);
|
||||
} // namespace Libraries::Net
|
Loading…
Reference in New Issue
Block a user