Net: Fix various socket-related issues (#3347)

* Store platform-specific level in a separate variable

So the level logged in the getsockopt/setsockopt unreachable is actually useful in cases where the level is unknown.

* Define ORBIS_NET_IPPROTO_IPV6

Not implemented yet, but since it's known we might as well add it.

* Fix error codes

Our libSceNet code expects accurate ORBIS_NET_E* errors, while the sys_net code returns ORBIS_NET_ERROR_* errors.

* Remove duplicate getsockname implementation

* Use separate mutex for ReceivePacket calls

Calls to ReceivePacket shouldn't block other socket functions, and allowing them to block these functions frequently causes deadlocks in games that use multiple threads for socket behaviors.
That said, concurrent receives are still a potential issue, so the function should still have a mutex.

* Add missing error codes

* Clang

* Minor nit

Not sure why these were left separate from the rest of the net errnos

* Set __Error() in ConvertReturnErrorCode

Because the new error values are positive, the logic of "negative return is an error" doesn't work anymore. The easiest fix, while retaining corrected error values, is to just set __Error() in ConvertReturnErrorCode, and have that return -1 instead.
I also added some formatting fixes here too.

* Set errno on stubbed P2P socket error returns.

Otherwise the errno is just whatever was set by a previous failing function, which may cause issues in some games.
I used EAGAIN here since it appears to be valid for all three of these functions, but this can be changed if requested.

* Fix missed error returns

* Fix socket methods in file_system

Missed these
This commit is contained in:
Stephen Miller 2025-07-30 13:54:28 -05:00 committed by GitHub
parent f685233401
commit 6c34b86add
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 79 additions and 82 deletions

View File

@ -298,12 +298,8 @@ s64 PS4_SYSV_ABI write(s32 fd, const void* buf, size_t nbytes) {
}
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;
// Socket functions handle errnos internally.
return file->socket->SendPacket(buf, nbytes, 0, nullptr, 0);
}
return file->f.WriteRaw<u8>(buf, nbytes);
@ -486,12 +482,8 @@ s64 PS4_SYSV_ABI read(s32 fd, void* buf, size_t nbytes) {
}
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;
// Socket functions handle errnos internally.
return file->socket->ReceivePacket(buf, nbytes, 0, nullptr, 0);
}
return ReadFile(file->f, buf, nbytes);
}
@ -685,12 +677,8 @@ s32 PS4_SYSV_ABI fstat(s32 fd, OrbisKernelStat* sb) {
break;
}
case Core::FileSys::FileType::Socket: {
s32 result = file->socket->fstat(sb);
if (result < 0) {
ErrSceToPosix(result);
return -1;
}
return result;
// Socket functions handle errnos internally
return file->socket->fstat(sb);
}
default:
UNREACHABLE();

View File

@ -220,26 +220,6 @@ s32 PS4_SYSV_ABI posix_getpagesize() {
return 16_KB;
}
s32 PS4_SYSV_ABI posix_getsockname(Libraries::Net::OrbisNetId s,
Libraries::Net::OrbisNetSockaddr* addr, u32* paddrlen) {
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 = file->socket->GetSocketAddress(addr, paddrlen);
if (returncode >= 0) {
LOG_ERROR(Lib_Net, "return code : {:#x}", (u32)returncode);
return 0;
}
*Libraries::Kernel::__Error() = 0x20;
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
return -1;
}
// stubbed on non-devkit consoles
s32 PS4_SYSV_ABI sceKernelGetGPI() {
LOG_DEBUG(Kernel, "called");
@ -308,7 +288,8 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
Libraries::Net::sys_getsockopt);
LIB_FUNCTION("fFxGkxF2bVo", "libScePosix", 1, "libkernel", 1, 1,
Libraries::Net::sys_setsockopt);
LIB_FUNCTION("RenI1lL1WFk", "libScePosix", 1, "libkernel", 1, 1, posix_getsockname);
LIB_FUNCTION("RenI1lL1WFk", "libScePosix", 1, "libkernel", 1, 1,
Libraries::Net::sys_getsockname);
LIB_FUNCTION("KuOmgKoqCdY", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_bind);
LIB_FUNCTION("5jRCs2axtr4", "libScePosix", 1, "libkernel", 1, 1,
Libraries::Net::sceNetInetNtop); // TODO fix it to sys_ ...

View File

@ -40,6 +40,7 @@ enum OrbisNetProtocol : u32 {
ORBIS_NET_IPPROTO_IGMP = 2,
ORBIS_NET_IPPROTO_TCP = 6,
ORBIS_NET_IPPROTO_UDP = 17,
ORBIS_NET_IPPROTO_IPV6 = 41,
ORBIS_NET_SOL_SOCKET = 0xFFFF
};

View File

@ -8,6 +8,7 @@ constexpr int ORBIS_NET_EPERM = 1;
constexpr int ORBIS_NET_ENOENT = 2;
constexpr int ORBIS_NET_EINTR = 4;
constexpr int ORBIS_NET_EBADF = 9;
constexpr int ORBIS_NET_ENOMEM = 12;
constexpr int ORBIS_NET_EACCES = 13;
constexpr int ORBIS_NET_EFAULT = 14;
constexpr int ORBIS_NET_ENOTBLK = 15;
@ -15,6 +16,7 @@ constexpr int ORBIS_NET_EBUSY = 16;
constexpr int ORBIS_NET_EEXIST = 17;
constexpr int ORBIS_NET_ENODEV = 19;
constexpr int ORBIS_NET_EINVAL = 22;
constexpr int ORBIS_NET_ENFILE = 23;
constexpr int ORBIS_NET_EMFILE = 24;
constexpr int ORBIS_NET_ENOSPC = 28;
constexpr int ORBIS_NET_EPIPE = 32;
@ -37,6 +39,7 @@ constexpr int ORBIS_NET_ENETUNREACH = 51;
constexpr int ORBIS_NET_ENETRESET = 52;
constexpr int ORBIS_NET_ECONNABORTED = 53;
constexpr int ORBIS_NET_ECONNRESET = 54;
constexpr int ORBIS_NET_ENOBUFS = 55;
constexpr int ORBIS_NET_EISCONN = 56;
constexpr int ORBIS_NET_ENOTCONN = 57;
constexpr int ORBIS_NET_ETOOMANYREFS = 59;
@ -48,6 +51,7 @@ constexpr int ORBIS_NET_EHOSTDOWN = 64;
constexpr int ORBIS_NET_EHOSTUNREACH = 65;
constexpr int ORBIS_NET_ENOTEMPTY = 66;
constexpr int ORBIS_NET_EPROCUNAVAIL = 76;
constexpr int ORBIS_NET_ECANCELED = 87;
constexpr int ORBIS_NET_EPROTO = 92;
constexpr int ORBIS_NET_EADHOC = 160;
constexpr int ORBIS_NET_EINACTIVEDISABLED = 163;
@ -77,10 +81,6 @@ constexpr int ORBIS_NET_RESOLVER_ESERVERREFUSED = 232;
constexpr int ORBIS_NET_RESOLVER_ENORECORD = 233;
constexpr int ORBIS_NET_RESOLVER_EALIGNMENT = 234;
// common errno
constexpr int ORBIS_NET_ENOMEM = 12;
constexpr int ORBIS_NET_ENOBUFS = 55;
// error codes
constexpr int ORBIS_NET_ERROR_BASE = 0x80410100; // not existed used for calculation
constexpr int ORBIS_NET_ERROR_EPERM = 0x80410101;

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <common/assert.h>
#include "core/libraries/kernel/kernel.h"
#include "net.h"
#include "net_error.h"
#include "sockets.h"
@ -12,10 +13,12 @@ int P2PSocket::Close() {
LOG_ERROR(Lib_Net, "(STUBBED) called");
return 0;
}
int P2PSocket::SetSocketOptions(int level, int optname, const void* optval, u32 optlen) {
LOG_ERROR(Lib_Net, "(STUBBED) called");
return 0;
}
int P2PSocket::GetSocketOptions(int level, int optname, void* optval, u32* optlen) {
LOG_ERROR(Lib_Net, "(STUBBED) called");
return 0;
@ -34,16 +37,19 @@ int P2PSocket::Listen(int backlog) {
int P2PSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetSockaddr* to,
u32 tolen) {
LOG_ERROR(Lib_Net, "(STUBBED) called");
*Libraries::Kernel::__Error() = ORBIS_NET_EAGAIN;
return -1;
}
int P2PSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr* from, u32* fromlen) {
LOG_ERROR(Lib_Net, "(STUBBED) called");
*Libraries::Kernel::__Error() = ORBIS_NET_EAGAIN;
return -1;
}
SocketPtr P2PSocket::Accept(OrbisNetSockaddr* addr, u32* addrlen) {
LOG_ERROR(Lib_Net, "(STUBBED) called");
*Libraries::Kernel::__Error() = ORBIS_NET_EAGAIN;
return nullptr;
}

View File

@ -4,6 +4,7 @@
#include <common/assert.h>
#include "common/error.h"
#include "core/libraries/kernel/file_system.h"
#include "core/libraries/kernel/kernel.h"
#include "net.h"
#ifndef _WIN32
#include <sys/stat.h>
@ -16,11 +17,13 @@ namespace Libraries::Net {
#ifdef _WIN32
#define ERROR_CASE(errname) \
case (WSA##errname): \
return ORBIS_NET_ERROR_##errname;
*Libraries::Kernel::__Error() = ORBIS_NET_##errname; \
return -1;
#else
#define ERROR_CASE(errname) \
case (errname): \
return ORBIS_NET_ERROR_##errname;
*Libraries::Kernel::__Error() = ORBIS_NET_##errname; \
return -1;
#endif
static int ConvertReturnErrorCode(int retval) {
@ -107,7 +110,8 @@ static int ConvertReturnErrorCode(int retval) {
ERROR_CASE(EHOSTUNREACH)
ERROR_CASE(ENOTEMPTY)
}
return ORBIS_NET_ERROR_EINTERNAL;
*Libraries::Kernel::__Error() = ORBIS_NET_EINTERNAL;
return -1;
}
// if it is 0 or positive return it as it is
return retval;
@ -121,6 +125,8 @@ static int ConvertLevels(int level) {
return IPPROTO_IP;
case ORBIS_NET_IPPROTO_TCP:
return IPPROTO_TCP;
case ORBIS_NET_IPPROTO_IPV6:
return IPPROTO_IPV6;
}
return -1;
}
@ -192,7 +198,7 @@ int PosixSocket::SendPacket(const void* msg, u32 len, int flags, const OrbisNetS
int PosixSocket::ReceivePacket(void* buf, u32 len, int flags, OrbisNetSockaddr* from,
u32* fromlen) {
std::scoped_lock lock{m_mutex};
std::scoped_lock lock{receive_mutex};
if (from != nullptr) {
sockaddr addr;
int res = recvfrom(sock, (char*)buf, len, flags, &addr, (socklen_t*)fromlen);
@ -258,16 +264,17 @@ int PosixSocket::GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) {
#define CASE_SETSOCKOPT_VALUE(opt, value) \
case opt: \
if (optlen != sizeof(*value)) { \
return ORBIS_NET_ERROR_EFAULT; \
*Libraries::Kernel::__Error() = ORBIS_NET_EFAULT; \
return -1; \
} \
memcpy(value, optval, optlen); \
return 0
int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u32 optlen) {
std::scoped_lock lock{m_mutex};
level = ConvertLevels(level);
s32 native_level = ConvertLevels(level);
::linger native_linger;
if (level == SOL_SOCKET) {
if (native_level == SOL_SOCKET) {
switch (optname) {
CASE_SETSOCKOPT(SO_REUSEADDR);
CASE_SETSOCKOPT(SO_KEEPALIVE);
@ -286,12 +293,14 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
CASE_SETSOCKOPT_VALUE(ORBIS_NET_SO_USESIGNATURE, &sockopt_so_usesignature);
case ORBIS_NET_SO_LINGER: {
if (socket_type != ORBIS_NET_SOCK_STREAM) {
return ORBIS_NET_ERROR_EPROCUNAVAIL;
*Libraries::Kernel::__Error() = ORBIS_NET_EPROCUNAVAIL;
return -1;
}
if (optlen < sizeof(OrbisNetLinger)) {
LOG_ERROR(Lib_Net, "size missmatched! optlen = {} OrbisNetLinger={}", optlen,
sizeof(OrbisNetLinger));
return ORBIS_NET_ERROR_EINVAL;
*Libraries::Kernel::__Error() = ORBIS_NET_EINVAL;
return -1;
}
const void* native_val = &native_linger;
@ -299,14 +308,16 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
native_linger.l_onoff = reinterpret_cast<const OrbisNetLinger*>(optval)->l_onoff;
native_linger.l_linger = reinterpret_cast<const OrbisNetLinger*>(optval)->l_linger;
return ConvertReturnErrorCode(
setsockopt(sock, level, SO_LINGER, (const char*)native_val, native_len));
setsockopt(sock, native_level, SO_LINGER, (const char*)native_val, native_len));
}
case ORBIS_NET_SO_NAME:
return ORBIS_NET_ERROR_EINVAL; // don't support set for name
*Libraries::Kernel::__Error() = ORBIS_NET_EINVAL;
return -1; // don't support set for name
case ORBIS_NET_SO_NBIO: {
if (optlen != sizeof(sockopt_so_nbio)) {
return ORBIS_NET_ERROR_EFAULT;
*Libraries::Kernel::__Error() = ORBIS_NET_EFAULT;
return -1;
}
memcpy(&sockopt_so_nbio, optval, optlen);
#ifdef _WIN32
@ -318,7 +329,7 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
#endif
}
}
} else if (level == IPPROTO_IP) {
} else if (native_level == IPPROTO_IP) {
switch (optname) {
// CASE_SETSOCKOPT(IP_HDRINCL);
CASE_SETSOCKOPT(IP_TOS);
@ -332,13 +343,14 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
CASE_SETSOCKOPT_VALUE(ORBIS_NET_IP_MAXTTL, &sockopt_ip_maxttl);
case ORBIS_NET_IP_HDRINCL: {
if (socket_type != ORBIS_NET_SOCK_RAW) {
return ORBIS_NET_ERROR_EPROCUNAVAIL;
*Libraries::Kernel::__Error() = ORBIS_NET_EPROCUNAVAIL;
return -1;
}
return ConvertReturnErrorCode(
setsockopt(sock, level, optname, (const char*)optval, optlen));
setsockopt(sock, native_level, optname, (const char*)optval, optlen));
}
}
} else if (level == IPPROTO_TCP) {
} else if (native_level == IPPROTO_TCP) {
switch (optname) {
CASE_SETSOCKOPT(TCP_NODELAY);
CASE_SETSOCKOPT(TCP_MAXSEG);
@ -362,7 +374,8 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
case opt: \
if (*optlen < sizeof(value)) { \
*optlen = sizeof(value); \
return ORBIS_NET_ERROR_EFAULT; \
*Libraries::Kernel::__Error() = ORBIS_NET_EFAULT; \
return -1; \
} \
*optlen = sizeof(value); \
*(decltype(value)*)optval = value; \
@ -370,8 +383,8 @@ int PosixSocket::SetSocketOptions(int level, int optname, const void* optval, u3
int PosixSocket::GetSocketOptions(int level, int optname, void* optval, u32* optlen) {
std::scoped_lock lock{m_mutex};
level = ConvertLevels(level);
if (level == SOL_SOCKET) {
s32 native_level = ConvertLevels(level);
if (native_level == SOL_SOCKET) {
switch (optname) {
CASE_GETSOCKOPT(SO_REUSEADDR);
CASE_GETSOCKOPT(SO_KEEPALIVE);
@ -392,7 +405,7 @@ int PosixSocket::GetSocketOptions(int level, int optname, void* optval, u32* opt
CASE_GETSOCKOPT_VALUE(ORBIS_NET_SO_NAME,
(char)0); // writes an empty string to the output buffer
}
} else if (level == IPPROTO_IP) {
} else if (native_level == IPPROTO_IP) {
switch (optname) {
CASE_GETSOCKOPT(IP_HDRINCL);
CASE_GETSOCKOPT(IP_TOS);
@ -405,7 +418,7 @@ int PosixSocket::GetSocketOptions(int level, int optname, void* optval, u32* opt
CASE_GETSOCKOPT_VALUE(ORBIS_NET_IP_TTLCHK, sockopt_ip_ttlchk);
CASE_GETSOCKOPT_VALUE(ORBIS_NET_IP_MAXTTL, sockopt_ip_maxttl);
}
} else if (level == IPPROTO_TCP) {
} else if (native_level == IPPROTO_TCP) {
switch (optname) {
CASE_GETSOCKOPT(TCP_NODELAY);
CASE_GETSOCKOPT(TCP_MAXSEG);

View File

@ -58,6 +58,7 @@ struct Socket {
virtual int GetSocketAddress(OrbisNetSockaddr* name, u32* namelen) = 0;
virtual int fstat(Libraries::Kernel::OrbisKernelStat* stat) = 0;
std::mutex m_mutex;
std::mutex receive_mutex;
};
struct PosixSocket : public Socket {

View File

@ -26,10 +26,10 @@ int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 add
if (returncode >= 0) {
return returncode;
}
*Libraries::Kernel::__Error() = returncode;
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
return -1;
}
int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
auto file = FDTable::Instance()->GetSocket(s);
if (!file) {
@ -41,10 +41,10 @@ int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrle
if (returncode >= 0) {
return returncode;
}
*Libraries::Kernel::__Error() = returncode;
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
return -1;
}
int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
auto file = FDTable::Instance()->GetSocket(s);
if (!file) {
@ -66,10 +66,12 @@ int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen)
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 file = FDTable::Instance()->GetSocket(s);
if (!file) {
@ -81,10 +83,10 @@ int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* padd
if (returncode >= 0) {
return returncode;
}
*Libraries::Kernel::__Error() = returncode;
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
return -1;
}
int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) {
auto file = FDTable::Instance()->GetSocket(s);
if (!file) {
@ -96,10 +98,10 @@ int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optv
if (returncode >= 0) {
return returncode;
}
*Libraries::Kernel::__Error() = returncode;
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
return -1;
}
int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
auto file = FDTable::Instance()->GetSocket(s);
if (!file) {
@ -111,10 +113,10 @@ int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
if (returncode >= 0) {
return returncode;
}
*Libraries::Kernel::__Error() = returncode;
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
return -1;
}
int PS4_SYSV_ABI sys_setsockopt(OrbisNetId s, int level, int optname, const void* optval,
u32 optlen) {
auto file = FDTable::Instance()->GetSocket(s);
@ -127,13 +129,14 @@ int PS4_SYSV_ABI sys_setsockopt(OrbisNetId s, int level, int optname, const void
if (returncode >= 0) {
return returncode;
}
*Libraries::Kernel::__Error() = returncode;
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
return -1;
}
int PS4_SYSV_ABI sys_shutdown(OrbisNetId s, int how) {
return -1;
}
int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protocol) {
if (name == nullptr) {
LOG_INFO(Lib_Net, "name = no-named family = {} type = {} protocol = {}", family, type,
@ -169,13 +172,16 @@ int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protoc
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);
}
int PS4_SYSV_ABI sys_netabort(OrbisNetId s, int flags) {
LOG_ERROR(Lib_Net, "(STUBBED) called");
return -1;
}
int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
auto file = FDTable::Instance()->GetSocket(s);
if (!file) {
@ -187,10 +193,10 @@ int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
if (returncode >= 0) {
return returncode;
}
*Libraries::Kernel::__Error() = returncode;
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
return -1;
}
int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
const OrbisNetSockaddr* addr, u32 addrlen) {
auto file = FDTable::Instance()->GetSocket(s);
@ -203,14 +209,15 @@ int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
if (returncode >= 0) {
return returncode;
}
*Libraries::Kernel::__Error() = returncode;
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
return -1;
}
int PS4_SYSV_ABI sys_sendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags) {
LOG_ERROR(Lib_Net, "(STUBBED) called");
return -1;
}
s64 PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
u32* paddrlen) {
auto file = FDTable::Instance()->GetSocket(s);
@ -223,10 +230,10 @@ s64 PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, Orbis
if (returncode >= 0) {
return returncode;
}
*Libraries::Kernel::__Error() = returncode;
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)*Libraries::Kernel::__Error());
return -1;
}
s64 PS4_SYSV_ABI sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) {
LOG_ERROR(Lib_Net, "(STUBBED) called");
return -1;