fix(rudp): throw from sceRudpGetMaxSegmentSize and justify the success of the pump calls

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
xXPBSXx 2026-10-11 20:31:52 +02:00
parent abf6f06be4
commit 4eb3340dcb
3 changed files with 13 additions and 27 deletions

View File

@ -258,14 +258,8 @@ int APS5_VABI sceRudpNetReceived(void) {
return 0;
}
int APS5_VABI sceRudpGetMaxSegmentSize(uint16_t* size) {
if (size == nullptr) {
return RUDP_ERROR_INVALID_ARGUMENT;
}
std::lock_guard<std::mutex> lk(g_mutex);
if (!g_inited) {
return RUDP_ERROR_NOT_INITIALIZED;
}
int APS5_VABI sceRudpGetMaxSegmentSize(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}

View File

@ -11,7 +11,7 @@ int APS5_VABI sceRudpInit_nid_postfix(void*, int);
int APS5_VABI sceRudpTerminate();
int APS5_VABI sceRudpProcessEvents();
int APS5_VABI sceRudpNetFlush();
int APS5_VABI sceRudpGetMaxSegmentSize(std::uint16_t*);
int APS5_VABI sceRudpGetMaxSegmentSize();
int APS5_VABI sceRudpNetReceived();
}
@ -25,29 +25,23 @@ static void Require(bool value, int line) {
int main() {
constexpr int notInitialized = static_cast<int>(0x80770001);
constexpr int invalidArgument = static_cast<int>(0x80770004);
std::uint16_t segmentSize = 0x5a5a;
CHECK(sceRudpProcessEvents() == notInitialized);
CHECK(sceRudpNetFlush() == notInitialized);
CHECK(sceRudpGetMaxSegmentSize(&segmentSize) == notInitialized);
CHECK(sceRudpGetMaxSegmentSize(nullptr) == invalidArgument);
CHECK(segmentSize == 0x5a5a);
alignas(8) static unsigned char pool[0xC58];
CHECK(sceRudpInit_nid_postfix(pool, sizeof(pool)) == 0);
CHECK(sceRudpProcessEvents() == 0);
CHECK(sceRudpNetFlush() == 0);
CHECK(sceRudpGetMaxSegmentSize(&segmentSize) == 0);
CHECK(sceRudpGetMaxSegmentSize(nullptr) == invalidArgument);
CHECK(segmentSize == 0x5a5a);
CHECK(sceRudpTerminate() == 0);
try {
sceRudpNetReceived();
} catch (const std::runtime_error& error) {
CHECK(std::string(error.what()) == "sceRudpNetReceived not implemented");
return 0;
for (const auto call : {&sceRudpNetReceived, &sceRudpGetMaxSegmentSize}) {
bool threw = false;
try {
call();
} catch (const std::runtime_error&) {
threw = true;
}
CHECK(threw);
}
std::fprintf(stderr, "sceRudpNetReceived returned instead of reporting that it is not implemented\n");
return 1;
return 0;
}

View File

@ -39,6 +39,7 @@ Throughout the project, every function at every stage either **does exactly what
- [libSceHttp2](../../core/libs/prx/libSceHttp2/Export.cpp) - no request reaches the network, so `sceHttp2SetMinSslVersion` has no TLS connection to restrict and returns success for any `id`, like `sceHttp2SslEnableOption` (prosper returns the invalid-id error for an unknown one)
- [libSceNpTrophy2](../../core/libs/prx/libSceNpTrophy2/src/GameInfo.cpp): `sceNpTrophy2RegisterUnlockCallback` accepts a callback that is never called, as no trophy is ever unlocked, `sceNpTrophy2UnregisterUnlockCallback` only returns success, and `sceNpTrophy2ShowTrophyList` returns success without showing a list (there is no system trophy UI; seen on PPSA15552).
- [sceAvPlayerSetTrickSpeed](../../core/libs/prx/libSceAvPlayer/src/Source.cpp) (libSceAvPlayer) with a negative speed runs the clock backwards but delivers no frames; when a forward speed is set again, playback resumes from the rewound time.
- [sceRudpProcessEvents and sceRudpNetFlush](../../core/libs/prx/libSceRudp/Export.cpp) (libSceRudp) - there is no reliable-UDP stack on the host, and every `sceRudpWrite`, `sceRudpRead` and `sceRudpGetStatus` call here reports a reset or idle context without queueing data, so no context ever holds pending data to process or send; both calls return success after `sceRudpInit` and `RUDP_ERROR_NOT_INITIALIZED` before it, as [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/rudp/rudp.cpp) returns OK from its stubs. PPSA03490 calls `sceRudpProcessEvents(0)` followed by `sceRudpNetFlush()` from its P2P service thread and ignores the first result; whether the real calls take parameters is unknown
- [sceRudpActivate](../../core/libs/prx/libSceRudp/Export.cpp) (libSceRudp) - there is no reliable-UDP stack on the host to activate, so it returns success without doing anything, as [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/rudp/rudp.cpp) does for its own `sceRudpActivate`. PPSA01325 calls it with no arguments during start-up; what the console activates, and whether it reports an error before `sceRudpInit`, is unverified
- [ulobjmgr](../../core/libs/prx/ulobjmgr/Export.cpp) registers no object: `_sceUlobjmgrRegisterObject` always hands out id 0 and `_sceUlobjmgrUnregisterObject` releases nothing, as shadPS4 does
- [libSceHttp](../../core/libs/prx/libSceHttp/Export.cpp) - no request reaches the network, so `sceHttpSetResponseHeaderMaxSize` has no response header to limit, `sceHttpSetRecvBlockSize` (`(int id, u32 blockSize)` as in [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/network/http.h)) no response body to read in blocks and `sceHttpRedirectCacheFlush` no redirect to forget; `sceHttpsUnloadCert` returns success like `sceHttpsLoadCert`, which keeps no certificate; `sceHttpSetRedirectCallback` and `sceHttpSetCookieRecvCallback` accept callbacks that are never called, `sceHttpsSetSslVersion` has no TLS connection to configure and `sceHttpsGetSslError` reports error 0 with detail 0; `sceHttpSetAuthInfoCallback` accepts a callback that is never called, as no server asks for authentication
@ -597,6 +598,3 @@ Throughout the project, every function at every stage either **does exactly what
- [_fstatfs](../../core/libs/prx/libkernel/File/src/Stdio.cpp) (libkernel) fills the FreeBSD 11 `struct statfs` of the PS5 payload SDK with the host volume that holds the file: block size, transfer size, total, free and available blocks, maximum name length and the read-only, `nosuid` and `noexec` flags (on Windows only read-only, and `f_files` and `f_ffree` are 0, as NTFS has no fixed number of files). The filesystem type number and name, mount paths, owner, filesystem id and I/O counters are left 0 or empty, since they would describe a host mount, not a console one. Sockets and pipes return `EINVAL`, as FreeBSD's `getvnode` does; a Windows descriptor that is neither a file nor a pipe throws. Stremio Plus (PPSA74126) reads the free space before a download and only logs the other fields
- [_WStoul](../../core/libs/prx/libc/src/Strings.cpp), [_Iswctype](../../core/libs/prx/libc/src/RuneLocale.cpp) and [swscanf_s](../../core/libs/prx/libc/src/ScanningWide.cpp) (libc) - `_WStoul` is `wcstoul` and throws for a base other than 0 or 2 to 36. `_Iswctype` takes the class numbers of Dinkumware's [xwcc.h](https://github.com/superna9999/ti-cgt6x/blob/cgt6x_7_3_4/include/xwcc.h) (1 `alnum` to 11 `xdigit`, 12 `blank`) and throws for any other value, including the FreeBSD masks `wctype` returns; the numbering is not confirmed on the console's `libc.prx`. `swscanf_s` follows C11 7.29.2.2 and K.3.9.1.5, but reads the size argument as `unsigned int` like `sscanf_s` where K.3.9.1.5 specifies `rsize_t`; the console's width is unverified. A runtime-constraint violation (null buffer, format or receiving pointer) only returns `EOF`, and a too small array gets a null first element as in `sscanf_s`. A literal mismatch is a matching failure and a field that is only a prefix, such as `0x` or `1e`, does not convert, as C11 requires; FreeBSD's `vfwscanf` reports an input failure for the first and converts the second. Integers out of range are truncated from `strtoll`/`strtoull`. It throws for `%p`, `%S`, `%C`, unknown length modifiers, scanset ranges, `%n` with suppression or width, and narrow `%s`, `%c` or `%[` input that the C-locale `wcrtomb` cannot convert
- [sceSharePlayGetCurrentConnectionInfoA](../../core/libs/prx/libSceSharePlay/Export.cpp) (libSceSharePlay) - reports no Share Play session, as the library keeps none: status 0 (DORMANT), mode 0, empty online IDs, account IDs 0 and both user IDs -1 (`SCE_USER_SERVICE_USER_ID_INVALID`). A null pointer returns `SCE_SHARE_PLAY_ERROR_INVALID_ARGS` (0x810E0001). The 72-byte `SceSharePlayConnectionInfoA` layout and the error code follow [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/main/src/libs/libNet.cpp) and [fpPS4](https://github.com/red-prig/fpPS4/blob/trunk/src/ps4_libsceshareplay.pas), which agree on both; KytyPS5 sets the user IDs to -1 and fpPS4 leaves them 0, and which one the console returns is not verified. KytyPS5 also returns `SCE_SHARE_PLAY_ERROR_NOT_INITIALIZED` before `sceSharePlayInitialize`; this library keeps no initialization state and does not.
- PPSA03490 imports declared without parameters, signatures unknown, added without an implementation because the title fails to load without them: [sceRudpNetReceived](../../core/libs/prx/libSceRudp/Export.cpp) (libSceRudp)
- [sceRudpProcessEvents and sceRudpNetFlush](../../core/libs/prx/libSceRudp/Export.cpp) (libSceRudp) - there is no reliable-UDP stack on the host, so with nothing to process or send they return success after `sceRudpInit` and `RUDP_ERROR_NOT_INITIALIZED` before it, as [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/rudp/rudp.cpp) returns OK from its stubs. PPSA03490 calls `sceRudpProcessEvents(0)` followed by `sceRudpNetFlush()` from its P2P service thread and ignores the first result; whether the real calls take parameters is unknown
- [sceRudpGetMaxSegmentSize](../../core/libs/prx/libSceRudp/Export.cpp) (libSceRudp) - PPSA03490 passes a pointer to a 16-bit value it has set to 0 and treats a nonzero result as failure. The real segment size is unknown, so nothing is written and the title keeps 0; it returns `RUDP_ERROR_INVALID_ARGUMENT` for a null pointer, `RUDP_ERROR_NOT_INITIALIZED` before `sceRudpInit` and 0 after it