Skip to content

fix(libkernel): getsockopt reads options of libSceNet sockets - #9515

Open
EagleBearerYS wants to merge 6 commits into
boykopovar:mainfrom
EagleBearerYS:fix/libkernel-getsockopt-net-sockets
Open

EagleBearerYS wants to merge 6 commits into
boykopovar:mainfrom
EagleBearerYS:fix/libkernel-getsockopt-net-sockets

Conversation

@EagleBearerYS

@EagleBearerYS EagleBearerYS commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Title-less conformance fixes of this kind are merged now, for example #7365 and #8411.

What

setsockopt reaches a socket created with sceNetSocket through the option setter libSceNet registers with libkernel, but getsockopt looks the descriptor up only among libkernel's own sockets and fails. A title can set an option on such a socket through the BSD call and not read it back.

  • libSceNet now registers an option getter next to its setter, and libkernel's getsockopt asks it for a descriptor libkernel doesn't own, as setsockopt does. The getter answers through sceNetGetsockopt, so SO_RCVTIMEO and SO_SNDTIMEO come back as a struct timeval, as FreeBSD 11.4's sogetopt returns them.
  • sceNetGetsockopt reads back SO_REUSEADDR and SO_BROADCAST, which sceNetSetsockopt takes but sceNetGetsockopt failed with EOPNOTSUPP. It reads them from the host socket. FreeBSD's sogetopt returns so_options & option for the boolean options, so they read back as 0x4 and 0x20 when set.
  • The debt entry that lists the libkernel calls reaching a libSceNet socket now names getsockopt with setsockopt.

Two commits: e887616 for sceNetGetsockopt, aea804d for the libkernel getter and the debt entry. No title is claimed.

Overlap, merge order only: this PR goes after #7511 and #9365, and rebases on them. #7511 adds pointer and length checks at the start of getsockopt_nid_postfix, where this PR adds the getter call; after the rebase the call comes after those checks, so a libSceNet socket fails a bad pointer or length as libkernel's own sockets do. #9365 corrects the same close and setsockopt debt sentence, and this PR's addition of getsockopt to it goes on top. #9542 (Queuse) adds the same SO_REUSEADDR and SO_BROADCAST readback in sceNetGetsockopt, with short-buffer handling. The order is agreed with Queuse in this thread (comment): #9523 → #9542 → this PR → #9578. The two merge as text, but would put the same two case labels in one switch, so this PR drops e887616's sceNetGetsockopt hunk at its first merge of main after #9542 lands. It keeps the libkernel getter forwarding and its tests. On #9542 with this PR merged in and that hunk dropped, guest_sce_net and guest_net_boolean_readback pass on both runners (run).

Tested

On GitHub's runners from my fork, on main at a6dcea9 (run, of the same code; aea804d adds the debt edit only):

  • guest_sce_net, on a datagram socket made with sceNetSocket:
    • sceNetGetsockopt reads SO_BROADCAST and SO_REUSEADDR back as 0x20 and 0x4 after sceNetSetsockopt sets them;
    • libkernel's getsockopt reads SO_BROADCAST back as 0x20;
    • after libkernel's setsockopt sets SO_RCVTIMEO to 0.25 s, libkernel's getsockopt returns the same struct timeval.
  • With main's code guest_sce_net fails on Linux and Windows. With the change it passes 10 runs in a row on both.
  • Every test registered under core/libs/prx/libc and core/libs/prx/libkernel passes: 142 and 207 on Windows, 197 libkernel tests on Linux. In the Linux libc suite (115), the timing test precise_wait failed with and without the change in this run.
  • tools/check_conventions.py --base origin/main passes.
  • xXPBSXx's run (comment): WSL2 Ubuntu 24.04 (a virtualised kernel), GCC 13.3.0, Release, the PR head alone on its merge base a6dcea9. guest_sce_net passes 3 of 3, and with libSceNet's Export.cpp and libkernel's SocketPoll.hpp, Socket.cpp and Udp.cpp at the merge base and the PR's tests kept, it aborts.
  • Not tested: macOS, a console, any title.
  • efd999c, a merge of main 938812d. The only conflict was docs/dev/debt/libkernel.md, where main reworded the sceKernelPread line next to this PR's close and getsockopt line; both changes are kept, and the PR's own diff is unchanged. On GitHub's runners (run), guest_sce_net, guest_socket_options, guest_socket_error and guest_socket_descriptor_flags pass 10 runs in a row on Linux and on Windows, 4 of 4, none skipped. The libc and libkernel suites pass on both (119 and 201 tests on Linux, 146 and 211 on Windows), run with APS5_SKIP_TIMING_TESTS=1, which relaxes precise_wait's median bounds on GitHub's hosted runners.
  • abbb7ac, a merge of main 67bbe03. The only conflict was docs/dev/debt/libkernel.md, where feat(libkernel): answer sceKernelAddReadEvent and sceKernelAddWriteEvent on regular files #9099 (aarushkha, regular-file events) reworded the sceKernelAddReadEvent pipe entry and added its own regular-file entry just above this PR's close, setsockopt and getsockopt line; the merge keeps both of main's entries and this PR's line, and the PR's own diff is unchanged. On GitHub's runners (run), guest_sce_net, guest_socket_options, guest_socket_error and guest_socket_descriptor_flags pass 10 runs in a row with the change, on Linux and on Windows: 4 run, 4 pass, 0 skip, 0 fail. With main's code, guest_sce_net fails on both. The libc and libkernel suites pass on both (143 and 205 tests on Linux, 170 and 218 on Windows), run with APS5_SKIP_TIMING_TESTS=1, which relaxes precise_wait's median bounds on GitHub's hosted runners.
  • fc47c2f, a merge of main a512780. The one conflict was in core/libs/tests/GuestSceNet.cpp, where refactor(libs): add full export headers for libs #10706 (the public-header migration) removed the test's local declarations, among them this PR's getsockopt_nid_postfix. The merge takes main's side, since libkernel's include/Api.hpp now declares getsockopt_nid_postfix with the same arguments. It also drops this PR's local sceNetGetsockopt declaration in libSceNet's Export.cpp, which tests/test_public_headers.py --audit-only reports as a second declaration next to Net.hpp's. So the PR's own diff loses those two declarations and is otherwise unchanged. On GitHub's runners (run), guest_sce_net, guest_socket_options, guest_socket_error, guest_socket_descriptor_flags and public_headers pass 10 runs in a row with the change, on Linux and on Windows: 5 run, 5 pass, 0 skip, 0 fail. With main's code, guest_sce_net fails on both. The libc and libkernel suites pass on both (143 and 206 tests on Linux, 170 and 222 on Windows), run with APS5_SKIP_TIMING_TESTS=1, which relaxes precise_wait's median bounds on GitHub's hosted runners.
  • 00924d8, a merge of main 66e6772 (run). The one conflict was docs/dev/debt/libkernel.md's entry on libSceNet sockets, where main adds poll and fcntl and this PR adds getsockopt; the merge keeps both, in the same words as feat(libSceNet): implement the Ex and Internal socket forms, sceNetSysctl, scope-ID text and the default route #9578's merge. The PR's code diff is unchanged. guest_sce_net, guest_socket_descriptor_flags, guest_socket_error, guest_socket_options and public_headers pass 10 runs in a row. Linux: 5 run, 5 pass, 0 skip, 0 fail. Windows: 5 run, 5 pass, 0 skip, 0 fail. The before arm fails guest_sce_net on both. Suites: libc and libkernel pass on Linux (144 and 207) and on Windows (171 and 223). The suites ran with APS5_SKIP_TIMING_TESTS=1, which relaxes precise_wait's median bounds on GitHub's hosted runners.

Checklist

…ockopt

sceNetSetsockopt takes both, but sceNetGetsockopt failed them with EOPNOTSUPP. It now reads them from the host socket. FreeBSD's sogetopt returns so_options & option for the boolean options, so they read back as 0x4 and 0x20 when set.
setsockopt reaches a socket created with sceNetSocket through the option setter libSceNet registers, but getsockopt looked the descriptor up only among libkernel's own sockets and failed, so a title could set an option on such a socket through the BSD call and not read it back. libSceNet now registers an option getter with libkernel next to its setter, which answers through sceNetGetsockopt, so SO_RCVTIMEO and SO_SNDTIMEO come back as a struct timeval.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The socket-hook change and the reported Windows/Linux tests look promising, but the checklist currently says Depends on: none while the PR description identifies two live overlaps. CONTRIBUTING.md requires overlap authors to agree on merge order and declare the dependency. The getsockopt_nid_postfix hunk overlaps open #7511, which validates pointer/length ordering in the same function; this PR inserts the libSceNet dispatch before that function’s current lookup. The docs/dev/debt/libkernel.md hunk overlaps open #9365 on the same socket-call sentence. Please coordinate with both authors, identify the agreed order, and update the checklist (and #9365’s “no open pull request edits these sentences” statement) before merge. I am not asking for a code change based on the reviewed diff.

@EagleBearerYS

Copy link
Copy Markdown
Contributor Author

Thanks, @MarcZX10. This PR goes after both: Depends on now lists #7511 and #9365, and I've left a note on each. When it rebases on #7511, the libSceNet getter call moves after #7511's pointer and length checks, so a libSceNet socket fails those the same way libkernel's own sockets do. On #9365, this PR's addition of getsockopt to the close and setsockopt sentence goes on top of its correction, and the note there says that this PR also edits that sentence. The Overlap line in the description now gives the order.

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 4630 docs/dev/debt/libkernel.md
PR 5021 core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 5836 core/libs/prx/libSceNet/Export.cpp
core/libs/tests/GuestSceNet.cpp
PR 6149 docs/dev/debt/libkernel.md
PR 6936 docs/dev/debt/libkernel.md
PR 7088 core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 7105 docs/dev/debt/libkernel.md
PR 7121 docs/dev/debt/libkernel.md
PR 7149 docs/dev/debt/libkernel.md
PR 7192 docs/dev/debt/libkernel.md
PR 7201 core/libs/prx/libSceNet/Export.cpp
core/libs/prx/libkernel/Socket/src/Udp.cpp
PR 7447 docs/dev/debt/libkernel.md
PR 7509 docs/dev/debt/libkernel.md
PR 7804 docs/dev/debt/libkernel.md
PR 8605 core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 8725 docs/dev/debt/libkernel.md
PR 8916 docs/dev/debt/libkernel.md
PR 9156 docs/dev/debt/libkernel.md
PR 9199 docs/dev/debt/libkernel.md
PR 9284 docs/dev/debt/libkernel.md
PR 9293 docs/dev/debt/libkernel.md
PR 9297 docs/dev/debt/libkernel.md
PR 9302 docs/dev/debt/libkernel.md
PR 9326 docs/dev/debt/libkernel.md
PR 9389 docs/dev/debt/libkernel.md
PR 9442 docs/dev/debt/libkernel.md
PR 9557 docs/dev/debt/libkernel.md
PR 9566 docs/dev/debt/libkernel.md
PR 9575 docs/dev/debt/libkernel.md
PR 9713 core/libs/prx/libkernel/Socket/src/Udp.cpp
PR 9932 core/libs/prx/libSceNet/Export.cpp
core/libs/tests/GuestSceNet.cpp
PR 9947 docs/dev/debt/libkernel.md
PR 9948 core/libs/prx/libSceNet/Export.cpp
core/libs/prx/libkernel/Socket/include/SocketPoll.hpp
core/libs/prx/libkernel/Socket/src/Udp.cpp
core/libs/tests/GuestSceNet.cpp
PR 10319 docs/dev/debt/libkernel.md
PR 10442 docs/dev/debt/libkernel.md
PR 10552 docs/dev/debt/libkernel.md
PR 10558 docs/dev/debt/libkernel.md
PR 10749 docs/dev/debt/libkernel.md
PR 11002 docs/dev/debt/libkernel.md
PR 11085 docs/dev/debt/libkernel.md
PR 11215 docs/dev/debt/libkernel.md
PR 11223 core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 11264 docs/dev/debt/libkernel.md
PR 11267 docs/dev/debt/libkernel.md
PR 11272 core/libs/prx/libSceNet/Export.cpp
core/libs/tests/GuestSceNet.cpp
PR 11341 core/libs/prx/libSceNet/Export.cpp
docs/dev/debt/libkernel.md
PR 11403 docs/dev/debt/libkernel.md

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed the updated full body and diff after the author recorded the shared getsockopt/debt ordering with #7511 and #9365. The new getter registration is adjacent to the existing setter bridge, and the reported tests exercise the net-specific and libkernel dispatch paths with the FreeBSD timeval representation. Current hosted checks and the reported cross-platform test suites support the change; I did not run a local build. The prior overlap coordination blocker is resolved.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rechecked the current head and the updated dependency coordination. The PR now declares #7511 and #9365, explains how the getter dispatch follows #7511 pointer/length checks, and records the shared debt sentence order with #9365. The tests cover libSceNet boolean reads and libkernel timeval dispatch; author reports repeated Linux/Windows red/green runs and broader suites, with one Linux timing test failing on both base and change. Hosted eligibility, conventions, intake, labels and report checks pass; product/relinker jobs are skipped. I did not run local tests.

@xXPBSXx

xXPBSXx commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Linux data point for aea804d9fd: WSL2 Ubuntu 24.04 (virtualised kernel, not bare-metal), GCC 13.3.0, Release, BUILD_TESTING=ON, PR head alone (not merged onto main; its merge-base is a6dcea927).

  • With the PR: ctest -R '^guest_sce_net$' passes 3 of 3.
  • With libSceNet/Export.cpp, libkernel/Socket/include/SocketPoll.hpp, libkernel/Socket/src/Socket.cpp and libkernel/Socket/src/Udp.cpp restored to the merge-base (the PR's tests kept): fails (Subprocess aborted).
    Not tested: macOS, Windows, a title run.
    AI-assisted (Claude Code).

@EagleBearerYS

Copy link
Copy Markdown
Contributor Author

@xXPBSXx thanks for the Linux run, both red and green. It's in Tested now.

@Queuse

Queuse commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

@EagleBearerYS I found a partial overlap with my #9542 while checking the wider socket-option queue: both add native SO_REUSEADDR/SO_BROADCAST readback. Mine also handles short output buffers and has a dedicated regression. #9578 carries your readback commit as well.

Would #9523 → #9542 → this PR → #9578 work for you, keeping your existing #7511/#9365 prerequisites? That would let this PR keep the getter forwarding and its tests while dropping the duplicate readback hunk. If yours needs to land first, I can instead rebase #9542 and retain only its short-buffer behavior and dedicated test. I have marked mine as a draft while we agree on the order.

@EagleBearerYS

Copy link
Copy Markdown
Contributor Author

@Queuse that order works: #9523 → #9542 → this PR → #9578, with #7511 and #9365 still before this PR. #9542's readback is the same as this PR's e887616 (the host's SO_REUSEADDR and SO_BROADCAST, returned as 0x4 and 0x20), and it adds the short-buffer handling. The two don't conflict as text, but together they'd put the same two case labels in sceNetGetsockopt's switch, so one has to go. Once #9542 lands, this PR drops that hunk when it next merges main and keeps its getter forwarding and its tests. #9578, which carries the same commit, follows at its own next merge. I checked the composition, #9542 with this PR merged in and that hunk dropped: guest_sce_net and guest_net_boolean_readback pass on both runners (run). With that, the order is agreed, and I've added it to both PRs' Depends on. #9542 can go back to ready whenever you like.

@Queuse

Queuse commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Thanks, @EagleBearerYS. I've recorded the agreed #9523 → #9542 → #9515 → #9578 order and your combined test results in #9542, keeping your #7511/#9365 prerequisites explicit. The overlap item in the checklist is now settled. #9542 is still a draft while the separate test-reorganization coordination with #6044 is pending.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 23, 2026
# Conflicts:
#	docs/dev/debt/libkernel.md
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 24, 2026
@github-actions github-actions Bot added needs rebase Conflicts with main, rebase needed and removed needs rebase Conflicts with main, rebase needed labels Oct 24, 2026
@oneandonlydean

Copy link
Copy Markdown
Collaborator

@EagleBearerYS This PR now conflicts with main in core/libs/tests/GuestSceNet.cpp. Main’s #10706 public-header migration removed local socket declarations, while this PR’s test still supplies GuestPollEntry and a local poll declaration. Main now requires each exported function to be declared once, in the library's public header (checked by the public_headers tests). Could you reconcile the poll test’s argument types with the current public interface?

Main's boykopovar#10706 declares getsockopt_nid_postfix and sceNetGetsockopt in the libraries' public headers, so this branch's local declarations of them in GuestSceNet.cpp and libSceNet's Export.cpp go.
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 25, 2026
@EagleBearerYS

Copy link
Copy Markdown
Contributor Author

@oneandonlydean Thanks, merged main (a512780) in fc47c2f. The conflict was the test's local declaration block, which #10706 removed. This PR had added only getsockopt_nid_postfix there, and libkernel's include/Api.hpp now declares it with the same arguments, so the merge takes main's side. GuestPollEntry and the poll declaration in that block were main's lines, not this PR's, and they go with it. The merge also drops this PR's local sceNetGetsockopt declaration in libSceNet's Export.cpp, which public_headers reported as a second declaration next to Net.hpp's. guest_sce_net, the three guest_socket_* tests and public_headers pass 10 runs in a row on Linux and Windows (run). #9578, which builds on this PR, has the same merge in 6c938db.

Main extends the libkernel debt entry on libSceNet sockets with poll and
fcntl, where this branch adds getsockopt to the same entry; the merge keeps
both.
@Queuse

Queuse commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

The #9523/#9542 branches are refreshed, and #9542 is ready for review. The agreed #9523 → #9542 → #9515 → #9578 order still works on my side. #6044 was closed without the test relocation, so the draft blocker mentioned in my earlier reply is gone.

I preserved main's merged protocol/TCP_NODELAY getters and their short-output rules in both refreshes; each branch passes its own regression plus the protocol, TCP_NODELAY and buffer controls on Windows.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants