Repository navigation
fix(libSceNet): report SO_ERROR from sceNetGetsockopt - #4988
Conversation
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
|
…on apart from new neighbours boykopovar#4988 adds a constant after NET_SO_RCVTIMEO and boykopovar#4989 adds a function before receive_error, so defining the SCE timeout constants and timeout_option there made the pull requests conflict.
…vice, ampr, nid) (#464) * fix(nid): validate buffer ranges and string terminators (cherry picked from commit ca67860) * fix(libSceNet): take 0x1105 and 0x1106 as the send and receive timeouts sceNetSetsockopt and sceNetGetsockopt answered EOPNOTSUPP for 0x1105 and 0x1106, the SCE send and receive timeouts in microseconds (shadPS4 net_types.h ORBIS_NET_SO_SNDTIMEO/RCVTIMEO, SharpProspero Socket.cs SoSndTimeo/SoRcvTimeo, KytyPS5 network.cpp). A title that set a receive timeout this way then blocked in sceNetRecv for good. Both options now set and read the timeouts that 0x1005 and 0x1006 already do. (cherry picked from commit febc362) * fix(libSceNet): sceNetEpollWait takes 2 as the OUT event sceNetEpollWait used Linux's EPOLLOUT bit (4) for writability. The SCE value is 2 (shadPS4 net_types.h ORBIS_NET_EPOLLOUT, KytyPS5 network.cpp EPOLL_OUT, SharpProspero Socket.cs EpollOut); IN (1), ERR (8) and HUP (0x10) already match. A socket registered for OUT was never polled for writability, so the wait ran out its timeout or blocked forever, and an IN|OUT registration never reported OUT. (cherry picked from commit b19a74f) * fix(libSceNet): report the registered socket as the epoll event ident sceNetEpollWait copied the whole event a title passed to sceNetEpollControl, so the ident and reserved fields came back as the title had left them. The ident of a returned event is the id that was registered and reserved is 0 (shadPS4 net.cpp sceNetEpollWaitImpl, KytyPS5 network.cpp EpollWait); a title that registers a socket without filling ident and looks the socket up by it now finds it. (cherry picked from commit 53cbdeb) * fix(libSceNet): report copied socket address lengths sceNetAccept, sceNetGetsockname, sceNetGetpeername, sceNetRecvfrom and sceNetRecvmsg stored the full address length (16 or 28) even when the caller's buffer was shorter and only part of the address was copied. FreeBSD 11.4 stores the copied length, the smaller of the two (kern_accept4, kern_recvit, kern_getsockname and kern_getpeername in sys/kern/uipc_syscalls.c), as libkernel's socket calls do since boykopovar#4295. (cherry picked from commit 4f78bd5) * fix(nid): resolve PE reference exports through their ordinals (cherry picked from commit 6e0f942) * fix(nid): bound version requirement chains to their section (cherry picked from commit f25eba6) * fix(nid): preserve each ELF string consumer independently (cherry picked from commit 89d89ac) * test(nid): avoid competing hash test registration (cherry picked from commit 4df7877) * test(nid): separate export-reference registration from path tests (cherry picked from commit 1c500fb) * test(nid): keep reference registration independent of other topics (cherry picked from commit ad43a48) * refactor(libSceNet): define timeout_option before receive_error boykopovar#4673 adds a function after receive_error, so defining timeout_option there made the two pull requests conflict. (cherry picked from commit ac8106b) * fix(libSceNetCtl): read 64-bit interface byte counters on Linux Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit a2e97d2) * feat(libSceLibcInternal): implement fminf required for PPSA99902 startup (cherry picked from commit 02d1dbb) * test(libSceNet): run CheckUnboundSocketName before CheckUnspecifiedIpv6 boykopovar#4785 calls its netstat check right after CheckPoolStats(), so calling CheckUnboundSocketName() there made the two pull requests conflict. (cherry picked from commit 92e0970) * fix(libScePngDec): validate this_size on create - Return SCE_PNG_DEC_ERROR_INVALID_SIZE when PngDecCreateParam::this_size does not match sizeof(PngDecCreateParam), matching libSceJpegDec behavior. - Add test coverage for invalid create parameter size. (cherry picked from commit a479fcd) * refactor(libSceNet): place the SCE timeout constants and timeout_option apart from new neighbours boykopovar#4988 adds a constant after NET_SO_RCVTIMEO and boykopovar#4989 adds a function before receive_error, so defining the SCE timeout constants and timeout_option there made the pull requests conflict. (cherry picked from commit 60fb528) * fix(ampr): retain pooled pages while remapping aliases (cherry picked from commit a2408b5) (cherry picked from commit ce98f83) * fix(libSceRudp): swap sceRudpEnd and sceRudpTerminate sceRudpEnd takes no argument and shuts the library down; sceRudpTerminate takes a context id and releases that context. main had the two swapped, so a title calling sceRudpEnd() passed a stray register as a context id and the library stayed initialised. Evidence: - PS5 console measurement by hugodearaujo in boykopovar#3073 (firmware 13.60): "After `sceRudpEnd()` all three return `0x80770001` again" (sceRudpGetMaxSegmentSize, sceRudpProcessEvents, sceRudpNetFlush). - AlexAltea/orbital cc408367da6a6ebbf5ac1ac559fefeadc73b2831 tools/ida/db_types.json:1971,1996: `int sceRudpEnd(void)`, `int sceRudpTerminate(int ctxId)`. - RPCS3 26098fb42d090cd522b4afcf3b754dd987c82978 rpcs3/Emu/Cell/Modules/cellRudp.cpp:108: `cellRudpEnd()` tears the library down. - AndnixSH/Vita3K-PS-Vita-OS-Fork c86ac732bc811057e690bed280c5076bdf95385e vita3k/modules/SceRudp/SceLibRudp.cpp:1032,1614: `sceRudpEnd()` clears every context, `sceRudpTerminate(int ctx_id)` erases one. The bodies are unchanged, only exchanged. guest_offline_imports now ends the library with sceRudpEnd(), and guest_rudp_status checks that sceRudpTerminate releases one context and sceRudpEnd all of them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 4029b5d) * test(libSceRudp): follow the End/Terminate swap in the context query and pump tests guest_rudp_context_queries released its context with sceRudpEnd(context) and shut the library down with sceRudpTerminate(), and guest_rudp_pump shut it down with sceRudpTerminate(), the order main had before the swap. They now call sceRudpTerminate(context) and sceRudpEnd(). (cherry picked from commit ebd71eb) * fix(libSceLibcInternal): return the negative zero from fminf for zeros of different sign (cherry picked from commit cd9573b) * feat(libSceProprietaryVoiceChatHelperPrx): implement the voice chat helper lifecycle Initialize and Terminate track whether the library is initialized, and SetVoiceChatState returns success without recording anything: the host has no system voice chat for a title's own voice chat to announce itself to, and the state argument is unknown. GetVoiceChatUsageState keeps throwing. With the state argument unreadable there is no recorded usage state, and whether the console returns the state or writes it through an output pointer, and how it encodes it, is unknown. Misuse throws rather than guessing an error code, as the library's error codes are unknown. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> (cherry picked from commit e933285) * fix(libSceFiber): run fibers on host stacks with room for host calls Host code that a guest fiber calls runs on the fiber's stack. Demon's Souls (PPSA01341) gives its job fibers 16 KiB contexts packed next to each other, and a fiber that reaches shader preparation through Driver::ResolveGraphicsStagesAbi goes about 21 KiB deep when SPIRV-Tools validates the module. That overwrites the saved frame of the fiber below, and the next switch to that fiber pops garbage into rbp, rbx, r12-r15 and rip (a jump to 0x1a in the observed crash). Fibers now run on an mmap'd host stack of the context size plus 1 MiB, with a guard page at the bottom, the same margin guest threads get since boykopovar#2647. The guest context is no longer written. Context size checks fill and scan the top context-size bytes of the host stack, so size_context_margin keeps its meaning. If the mapping fails the fiber runs in its context as before. Windows is unchanged: it pins and publishes the guest context as the stack, and that path is not covered here. The fiber test now runs a 256 KiB host call from a 16 KiB fiber placed at the top of a guard-filled area and checks nothing below the context was written. It fails on main. (cherry picked from commit 7947149) * fix(libSceFiber): throw when a fiber's host stack cannot be set up No fallback to the title's context: a failed mmap or mprotect throws, as on Windows. (cherry picked from commit 36eb627) * feat(libSceAppContent): implement sceAppContentAddcontEnqueueDownload The signature (uint32_t service label, const NpUnifiedEntitlementLabel*) follows SharpProspero Interop/AppContent/AppContent.cs (5dfdb4b0). dlc_emu dlc_content.cpp (fcf69b16) answers NOT_FOUND for a label that is not a known add-on and PARAMETER for a null label. No add-on content is ever installed here, as sceAppContentAddcontMount and sceAppContentGetAddcontInfo already model, so every non-null label answers NOT_FOUND and nothing is queued. dlc_emu's nonzero-padding check is left out, as sibling functions do not check it and no console source confirms it. Carried from @screamm with author attribution preserved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit fdfe220) * fix(nid): validate GNU hash geometry before rewriting (cherry picked from commit bb44366) * feat(libScePad): apply the angular velocity deadband Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 1d115b8) * feat(libSceVideoOut): implement sceVideoOutDeleteVrrActiveStatusEvent The NID -q-vbO859Tw, declared as sceVideoOutUnknown_q_vbO859Tw for PPSA02530, hashes to sceVideoOutDeleteVrrActiveStatusEvent. It removes the handle's VRR status registration from the queue like the other Delete*Event calls, the counterpart of sceVideoOutAddVrrActiveStatusEvent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017WeVmjnnPPKdxVTpr2Vjtw (cherry picked from commit 6f284b8) * feat(libSceDbgThreadSanitizer): declare the TSan annotation calls and report the sanitizer disabled Black Myth: Wukong (PPSA23226) exits at start-up with STATUS_DLL_NOT_FOUND after "Failed to load module: libs\libSceDbgThreadSanitizer.prx". The executable does not need the library: its bundled sce_module/libSceJobManager_nosubmission.prx lists it in DT_NEEDED and imports __tsan_acquire and __tsan_release from it, plus sceKernelIsThreadSanitizerEnabled from libkernel. The relinker converts every module in sce_module and loads it at start-up (only --module-dir directories are deferred), and GuestModuleBuilder adds each module's host dependencies to the executable's DT_NEEDED, which the Windows start-up stub loads. libSceDbgThreadSanitizer now exports __tsan_acquire and __tsan_release with the void(void* addr) signatures of LLVM compiler-rt's tsan_interface.h (llvm-project 87f0227cb601, LLVM 20.1.8). Both throw: AnyPS5 runs no race detector, and the module calls them only after sceKernelIsThreadSanitizerEnabled reports the sanitizer enabled. libkernel's sceKernelIsThreadSanitizerEnabled returns 0, as sceKernelIsAddressSanitizerEnabled does; its int(void) signature is assumed and recorded in the libkernel debt file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 0f77f3e) * feat(libSceSystemService): relaunch the title for sceSystemServiceLoadExec of its own eboot.bin Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 3292cd3) * feat(libSceSaveData): implement sceSaveDataGetConvertProgress (cherry picked from commit b078f47) * fix(ampr): reserve targets before releasing mapped pool pages (cherry picked from commit 3e9a37e) (cherry picked from commit a88a4c8) * fix(ampr): reserve remap targets before releasing pool pages (cherry picked from commit 45a157d) * test(ampr): retain both pooled-page ownership regressions Restore the original alias-remap regression alongside the pool-exhaustion regression so each ownership fix remains covered after combining the series. (cherry picked from commit acd8c8c) * feat(libSceLibcInternal): implement the posix_spawn attribute and file action calls XPSemu (PPSA97358) imports eleven posix_spawn calls from libSceLibcInternal.prx, one reference each, and no call site is known. Predicted stop (import order, not measured), behind isnanf (idx 296): `FAIL: unresolved ELF import 44hlATrd47U from libSceLibcInternal.prx` (posix_spawnattr_init, idx 347), followed by p--TkNVsXjA, LG6O0oW9bQU, Sj7y+JO5PcM, Ud8CbISKRGM, Hq9-2AMG+ks, IUfBO5UIZNc, Heh4KJwyoX8 (348-355), UV4m0bznVtU, Ani6e+T-y6Q and 3Nr9caNHhyg (379-381). The nine object calls follow FreeBSD release/11.4.0 (8c639945a445) lib/libc/gen/posix_spawn.c: posix_spawnattr_init allocates a zeroed attribute object (ENOMEM on failure), _destroy frees it, _setflags and _setsigdefault store the value; posix_spawn_file_actions_init allocates an empty list (-1 on failure, as in 11.4), _destroy frees it with its entries, and _addopen (path copied), _adddup2 and _addclose append in order after returning EBADF for a negative descriptor. Null or uninitialized objects, which FreeBSD dereferences, throw. posix_spawn and posix_spawnp throw "process creation not implemented", as execvp does: FreeBSD validates no argument before rfork/vfork, and no child process can be created here. TechnicalDebt records them. guest_posix_spawn covers the attribute round trips, the recorded action sequence, the EBADF cases and the throws. NIDs computed with tools/nid_names.py and present in aerolib. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 2fe382c) * feat(libSceNpEntitlementAccess): implement sceNpEntitlementAccessGetPftFlag Reports a full game, not a Play First Trial: 0 is written to the uint32_t output and 0 returned; a null pointer returns 0x817D0002. Signature, value, one-word write and error match sceNpEntitlementAccessGetGameTrialsFlag and sharpemu src/SharpEmu.Libs/Np/NpEntitlementAccessExports.cs:98-116. 0x817D0002 is the parameter error of KytyPS5, prosper and sceNpEntitlementAccessGetEntitlementKey. The library has no initialization state, so none is checked. Update technical debt documentation and add unit test in guest_offline_imports. (cherry picked from commit 7900b59) * feat(libSceSystemService): no-op sceSystemServiceShowControllerSettings (cherry picked from commit 46c7766) * fix(libScePlayGo): answer chunk ids from the package layout A package with no playgo-* file in sce_sys has no PlayGo data, so only chunk 0 is valid and any other id returns SCE_PLAYGO_ERROR_BAD_CHUNK_ID. A package with playgo-scenario.json but no chunk table (PPSA01748) keeps accepting every id. A chunk table (playgo-chunk.dat or playgo-chunkdefs.xml) still decides when it exists. A sce_sys that holds other playgo-* files without a chunk table or a scenario file, or a playgo-chunk.dat that is not a plgx table with a nonzero count, throws naming the file, since no such dump is known. Without this a title that walks the ids until the first error (Sifu PPSA03001) never gets the error. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> (cherry picked from commit 51c7206) * feat(libSceSystemService): no-op sceSystemServiceOpenChallengeActivity (cherry picked from commit 4aff906) * feat(libSceSsl): add missing verification callback export (cherry picked from commit 5d00bd7) * feat(libSceAmpr): implement the std::_Pad thread launch helpers Implement _ZNSt4_PadC2Ev, _ZNSt4_PadD2Ev, _ZNSt4_Pad7_LaunchEPP7pthread and _ZNSt4_Pad8_ReleaseEv, which Deathloop (PPSA01670) and Minecraft Legends (PPSA05510) import from libSceAmpr for the std::thread launch path. The algorithm and object layout follow Dinkumware V6.00 thr/xthread and thr/threadcall.cpp of Visual C++ 2013 (ganboing/crt.vc12 f1d47126): a vtable pointer whose first slot is the pure virtual _Go(), then the condition and mutex handles and bool _Started (0x8, 0x10, 0x18), with the console's pointer-to-slot handles of libc Threads.cpp (boykopovar#3079). The pad uses libc's _Cnd_*/_Mtx_* exports, starts the guest thread with pthread_create and an entry that calls _Go() and returns its result as the exit code, as _Call_func does. The unverified layout, thread attributes and error reporting are recorded in TechnicalDebt.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit d991cdc) * test(ampr): exercise simultaneous pad launches and destroyed storage (cherry picked from commit 49d8cf3) * fix(ampr): exclude the private pad entry from the export inventory (cherry picked from commit 8e3b2a0) * fix(ampr): raise std::_Pad failures as the guest std::system_error A failing _Pad primitive threw a host std::runtime_error, which no guest catch can see. threadcall.cpp calls the checked wrappers of xthread (_Mtx_lockX, _Cnd_waitX, _Thrd_startX), which pass a non-success code to _Throw_C_error: _Thrd_nomem and _Thrd_timedout become resource_unavailable_try_again, _Thrd_busy device_or_resource_busy and _Thrd_error invalid_argument, raised through _Throw_Cpp_error, which main now implements. A failing thread start is _Thrd_startX's resource_unavailable_try_again. _Release now wakes the launching thread with _Cnd_signal, as threadcall.cpp does; libc has it since the pad was written. guest_ampr_threads checks, in a forked child whose guest terminate handler reports the thrown object, that _Release on the thread still holding the pad's mutex throws std::system_error with EBUSY. It fails with the previous host exception and with busy mapped to invalid_argument. (cherry picked from commit dd1deb6) * feat(libSceAudioOut): implement sceAudioOut2EnableChat Palworld (PPSA23126, boykopovar#2648) stops at start-up on the export, imported by its bundled libdiscord_partner_sdk.prx: FAIL: unresolved ELF import oiOi7vgPfAY from libSceAudioOut.prx PPSA28416 imports it from its bundled party-ps5-shipping.prx as well. The call itself has not been observed yet. SharpProspero (5dfdb4b0, Interop/Audio/AudioOut2.cs:460-464) declares `int sceAudioOut2EnableChat()`, "Allows chat audio alongside the application's own", and the ps5-payload-dev SDK stub (f5d40f02, sce_stubs/libSceAudioOut.c:62) exports it as well. There is no context or handle to validate. The host mixes no chat audio and AudioOut2 has no chat port, so the call records that chat audio is allowed (traced once with APS5_TRACE_AUDIOOUT2) and returns 0. Whether the console fails it without a chat session or when repeated is recorded in technical debt, and the PPSA28416 "signature unknown" entry is dropped. NID oiOi7vgPfAY matches tools/nid_names.py and the shadPS4 aerolib list. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 50cd318) * test(libSceAudioOut): define TestEnableChat; drop stale EnableChat unknown-signature line Co-Authored-By: Claude <noreply@anthropic.com> (cherry picked from commit 76075ed) * fix(libSceNet): name an unbound socket with the zero address on Windows sceNetGetsockname on a socket that is neither bound nor connected failed with EINVAL on Windows, where Winsock reports WSAEINVAL. FreeBSD 11.4 returns the wildcard address with port 0 (in_getsockaddr and in6_getsockaddr in sys/netinet/in_pcb.c and sys/netinet6/in6_pcb.c), and Linux already does, so the call now builds that address for the socket's family. (cherry picked from commit feffc67) * test(libSceNet): order the Net checks as upstream does (CheckEpollWritable, CheckStreamSender) Folds upstream d0cef9a and a7e320d, which only reorder test helpers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(libSceFiber): define MAP_STACK as 0 where the host lacks it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: MiniRML <134226498+MiniRML@users.noreply.github.com> Co-authored-by: Yunus Shaikh <75296019+yunusshaikh7@users.noreply.github.com> Co-authored-by: bubblegg <86165363+bubblegg@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Leonardo <leonardo.rossi1922005@gmail.com> Co-authored-by: Yunus Shaikh <75296019+EagleBearerYS@users.noreply.github.com> Co-authored-by: Nithishvelan M <mnithishvelan@gmail.com> Co-authored-by: Blazing Cook <> Co-authored-by: David <david@example.com> Co-authored-by: Arekatla Nishanth Chowdary <av.sc.u4aie23002@av.students.amrita.edu> Co-authored-by: Dean Galvin <dean.galvin@live.com> Co-authored-by: Matheus Lima da Silva <matheusldasilva20088@gmail.com> Co-authored-by: Joey Fisher <fisherjoey@ymail.com> Co-authored-by: Adrià Franch <adriadam10@gmail.com> Co-authored-by: p3nicillin <lcmcclellan12@gmail.com> Co-authored-by: Nicolas Falesy <112726756+nicolasfalesy@users.noreply.github.com> Co-authored-by: fdfawef324 <287205748+fdfawef324@users.noreply.github.com> Co-authored-by: Aathish <101638624+Aathish-D@users.noreply.github.com> Co-authored-by: MarcZX100 <marczxrr@gmail.com> Co-authored-by: Blazing Cook <324818824+cookie42073-cmd@users.noreply.github.com> Co-authored-by: jagrat Singh <jagratsingh9899@gmail.com> Co-authored-by: ducloc080202 <ducloc080202@gmail.com> Co-authored-by: xXPBSXx <20614131+xXPBSXx@users.noreply.github.com> Co-authored-by: Yossi Yadgar <yadgar360@gmail.com> Co-authored-by: screamm <davidrydgren@gmail.com>
|
A second title for this fix, on Windows: OpenNOW PS5 0.1 (PPSA99082, catalog release, unwrapped and relinked with It needs #4924 and #4933 first, to get past With this PR cherry-picked on top, no request fails in a 60 s run and the title goes on to its decoder qualification. The ProsperoLichess result with this PR on Windows is in #4982: it connects, and with a PEM certificate list in place it goes online. One note for whoever merges second: this PR and #4924 conflict in AI-assisted: yes (Claude Code); the runs are from my machine. |
What
sceNetGetsockopt(s, SOL_SOCKET, SO_ERROR)(0x1007) used to fail withEOPNOTSUPP. It now returns the socket's pending error as a libSceNet errno, and 0 when there is none, as FreeBSD 11'ssogetoptdoes. The read clears it.SO_ERROR, mapped with the same tablenative_error()already uses forerrno/WSAGetLastError()(nownet_error(code)), so a refused connect reports 61 (ECONNREFUSED).sceNetConnect, as fix(libkernel): report SO_ERROR and the other SOL_SOCKET options like FreeBSD #4796 does for libkernel sockets. That difference is recorded indocs/dev/debt/libSceNet.md.curl checks a non-blocking connect this way: it waits for OUT, then reads
SO_ERROR. So a curl request over libSceNet sockets fails withcurl 7even after the TCP handshake succeeds.Tested
On the PR head 0daf1d5, Linux (Ubuntu 24.04, GCC 13) and Windows 11 (MinGW-w64 GCC 15.2 from WinLibs), Release:
guest_sce_netpasses 5/5 (--repeat until-fail:5) on both. The new check reads 0 from a connected socket. It reads 61 from a refused non-blocking loopback connect, then 0 on the next read. It fails onmain.Export.cpporGuestSceNet.cpp.ProsperoLichess (PPSA99009, catalog release) on Windows 11 (RTX 3080), default flags:
mainevery request fails after about 5.2 s (curl 7: Failed to connect to lichess.org port 443 after 5203 ms). DNS and the TCP handshake work, butsceNetEpollWaitpolls OUT as 4 instead of SCE's 2, which is fix(libSceNet): sceNetEpollWait takes 2 as the OUT event #4611.curl 7 ... after 112 ms): the OUT wait returns andsceNetGetsockopt(SO_ERROR)fails withEOPNOTSUPP.test/verify-soerr-stack2), it connects. The next stop is TLS: the title loads the console's CA list from/<sandbox>/common/cert/CA_LIST.cer, which AnyPS5 doesn't provide (curl 77).On Linux the headless catalog run stops at the
DisplayWindowthrow before any request.check_conventions.pypasses.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)SO_ERRORonly once OUT is delivered)