diff --git a/rpcs3/Emu/Cell/lv2/sys_net.cpp b/rpcs3/Emu/Cell/lv2/sys_net.cpp index 6f8cb53fb6..b24bca0f4f 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net.cpp @@ -200,21 +200,56 @@ static sys_net_error get_last_error(bool is_blocking, int native_error = 0) } #ifdef _WIN32 - switch (native_error) #define ERROR_CASE(error) case WSA ## error: result = SYS_NET_ ## error; name = #error; break; #else - switch (native_error) #define ERROR_CASE(error) case error: result = SYS_NET_ ## error; name = #error; break; #endif + switch (native_error) { +#ifndef _WIN32 + ERROR_CASE(ENOENT); + ERROR_CASE(ENOMEM); + ERROR_CASE(EBUSY); + ERROR_CASE(ENOSPC); +#endif + + // TODO: We don't currently support EFAULT or EINTR + //ERROR_CASE(EFAULT); + //ERROR_CASE(EINTR); + + ERROR_CASE(EBADF); + ERROR_CASE(EACCES); + ERROR_CASE(EINVAL); + ERROR_CASE(EMFILE); + ERROR_CASE(EPIPE); ERROR_CASE(EWOULDBLOCK); ERROR_CASE(EINPROGRESS); ERROR_CASE(EALREADY); - ERROR_CASE(ENOTCONN); - ERROR_CASE(ECONNRESET); + ERROR_CASE(EDESTADDRREQ); + ERROR_CASE(EMSGSIZE); + ERROR_CASE(EPROTOTYPE); + ERROR_CASE(ENOPROTOOPT); + ERROR_CASE(EPROTONOSUPPORT); + ERROR_CASE(EOPNOTSUPP); + ERROR_CASE(EPFNOSUPPORT); + ERROR_CASE(EAFNOSUPPORT); ERROR_CASE(EADDRINUSE); + ERROR_CASE(EADDRNOTAVAIL); + ERROR_CASE(ENETDOWN); + ERROR_CASE(ENETUNREACH); + ERROR_CASE(ECONNABORTED); + ERROR_CASE(ECONNRESET); + ERROR_CASE(ENOBUFS); ERROR_CASE(EISCONN); - default: sys_net.error("Unknown/illegal socket error: %d", native_error); + ERROR_CASE(ENOTCONN); + ERROR_CASE(ESHUTDOWN); + ERROR_CASE(ETOOMANYREFS); + ERROR_CASE(ETIMEDOUT); + ERROR_CASE(ECONNREFUSED); + ERROR_CASE(EHOSTDOWN); + ERROR_CASE(EHOSTUNREACH); + default: + fmt::throw_exception("sys_net get_last_error(is_blocking=%d, native_error=%d): Unknown/illegal socket error", is_blocking, native_error); } if (name && result != SYS_NET_EWOULDBLOCK && result != SYS_NET_EINPROGRESS) @@ -2269,6 +2304,23 @@ error_code sys_net_bnet_recvfrom(ppu_thread& ppu, s32 s, vm::ptr buf, u32 return true; } +#ifdef _WIN32 + else + { + // Windows returns an error when trying to peek at a message and buffer not long enough to contain the whole message, should be ignored + if ((native_flags & MSG_PEEK) && get_native_error() == WSAEMSGSIZE) + { + native_result = len; + return true; + } + // Windows will return WSASHUTDOWN when the connection is shutdown, POSIX just returns EOF (0) in this situation. + if( get_native_error() == WSAESHUTDOWN) + { + native_result = 0; + return true; + } + } +#endif result = get_last_error(!sock.so_nbio && (flags & SYS_NET_MSG_DONTWAIT) == 0); @@ -2939,6 +2991,12 @@ error_code sys_net_bnet_socket(ppu_thread& ppu, s32 family, s32 type, s32 protoc { return -get_last_error(false); } + u32 default_RCVBUF = (type==SYS_NET_SOCK_STREAM) ? 65535 : 9216; + if (setsockopt(native_socket, SOL_SOCKET, SO_RCVBUF, reinterpret_cast(&default_RCVBUF), sizeof(default_RCVBUF)) != 0) + sys_net.error("Error setting defalult SO_RCVBUF on sys_net_bnet_socket socket"); + u32 default_SNDBUF = 131072; + if (setsockopt(native_socket, SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&default_SNDBUF), sizeof(default_SNDBUF)) != 0) + sys_net.error("Error setting default SO_SNDBUF on sys_net_bnet_socket socket"); } auto sock_lv2 = std::make_shared(native_socket, type, family);