Skip to content

feat(libkernel): UDP sockets and name resolution on macOS hosts - #7850

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
mugurc:feat/libkernel-sockets-macos
Oct 21, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
mugurc:feat/libkernel-sockets-macos

Conversation

@mugurc

@mugurc mugurc commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What

UDP sockets and name resolution on macOS hosts. The socket layer calls ppoll and asks for POLLRDHUP, and the resolver calls gethostbyname_r; macOS has none of them, so libkernel and libScePosixForWebKit do not compile on macOS without this. Part of the macOS series announced on #1 (#1 (comment)).

  • The equeue wait uses poll with the timeout rounded up to a millisecond.
  • A readable stream socket whose peer closed is reported with POLLHUP by peeking one byte.
  • FIONREAD on a datagram socket, and the byte count that fstat and kevent report for it, come from SO_NREAD, the size of the next datagram. macOS's FIONREAD counts every queued datagram together with its source address. One helper, QueuedBytes, serves the three; on Linux it makes the same ioctl(FIONREAD) call as before.
  • socketpair throws for SOCK_SEQPACKET, which has no AF_UNIX pair on macOS, and guest_socket_pair expects that throw there.
  • gethostbyname replaces gethostbyname_r; macOS keeps its result in thread-specific storage.
  • guest_udp sends on its connected socket without an address. macOS, like FreeBSD, fails sendto with an address on a connected socket with EISCONN, where Linux accepts it. The two changed lines are the same as in fix(libkernel): return EISCONN from sendto with an address on a connected datagram socket #7475, which makes the guest return EISCONN there on every host and checks it, so the two pull requests merge in either order.
  • log_macros captures its writes through a datagram pair with 1 MiB buffers instead of SOCK_SEQPACKET.

The whole-port PRs #7201 and #7332 contain these functions too. #7332 carries the first version of this commit from the series and also reads SO_NREAD for fstat and kevent.

Tested

macOS 26.5.1, Apple M5 Max, Apple clang 21, x86-64 build under Rosetta 2. main 9127ea3 with the rest of the macOS series (ci/macos-series-2 on my fork), the open macOS fix #7524, the JIT shared memory change of the closed #6928 (#7937 carries it now) and three changes from #7332. The libraries do not link on macOS without the series.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source (none added)
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

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.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 8344 docs/dev/debt/libkernel.md L186
PR 8483 docs/dev/debt/libkernel.md L186
PR 8658 core/libs/prx/libkernel/Socket/src/Udp.cpp L439, L764-765, L801-802, L844, L867-868, L1304
core/libs/tests/LogMacros.cpp L40-41
PR 8670 docs/dev/debt/libkernel.md L186

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 5021 core/libs/prx/libScePosixForWebKit/Resolver.cpp
core/libs/prx/libkernel/Socket/src/Udp.cpp
core/libs/tests/GuestSocketPair.cpp
docs/dev/debt/libkernel.md
PR 6044 core/libs/tests/GuestSocketPair.cpp
core/libs/tests/GuestUdp.cpp
core/libs/tests/LogMacros.cpp
PR 6149 docs/dev/debt/libkernel.md
PR 6469 docs/dev/debt/libkernel.md
PR 6740 docs/dev/debt/libkernel.md
PR 6879 docs/dev/debt/libkernel.md
PR 6936 docs/dev/debt/libkernel.md
PR 6977 core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 7049 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/libScePosixForWebKit/Resolver.cpp
core/libs/prx/libkernel/Socket/src/Udp.cpp
core/libs/tests/LogMacros.cpp
PR 7447 docs/dev/debt/libkernel.md
PR 7509 docs/dev/debt/libkernel.md
PR 8520 docs/dev/debt/libkernel.md
PR 8553 docs/dev/debt/libkernel.md
PR 8726 docs/dev/debt/libkernel.md

@fogydes fogydes 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.

Tested and reviewed the diff:

The macOS host socket adaptations (SO_NREAD for datagram size on FIONREAD/fstat/kevent, millisecond rounding for poll timeouts in absence of ppoll, and gethostbyname fallback) are well isolated under #ifdef __APPLE__.

One overlap coordination note:
The modifications in core/libs/tests/GuestUdp.cpp (lines 154, 202, 222-223) overlap with open PR #7475 (fix(libkernel): return EISCONN from sendto with an address on a connected datagram socket).

PR #7475 adds explicit EISCONN (56) validation in Udp.cpp for sendto calls with an address on connected sockets to match FreeBSD kernel behavior, and updates GuestUdp.cpp accordingly. Your separation of sender (connected) and addressed (unconnected) in GuestUdp.cpp aligns cleanly with that change.

To help maintainers sequence them without merge conflicts, consider adding Depends on: #7475 (or noting how the two interact in the PR description).

AI-assisted: yes

ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 19, 2026
…ution on macOS hosts (@mugurc)

This branch carried an earlier form of this part of mugurc's macOS
series; boykopovar#7850 is the current one, split out for main. Its socket code
is the newer form and is taken in both conflicts: the readable-peer
peek is limited to stream sockets, and the datagram byte count goes
through its QueuedBytes helper (SO_NREAD on macOS) in ioctl as in
kevent and fstat. In the libkernel debt file main's socketpair entry
and the branch's short macOS line stay as they are, and the macOS
sockets entry is the PR's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 19, 2026
The merge of boykopovar#7850 combined this branch's earlier form of the macOS
gethostbyname path with the PR's without a conflict, nesting a second
copy of the __APPLE__ branch inside the Linux one and leaving an
unterminated conditional, so libScePosixForWebKit stopped building.
The function is now exactly the PR's: gethostbyname on macOS, the
gethostbyname_r loop elsewhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The guest socket layer relies on a few Linux calls:

- The equeue wait uses poll with the timeout rounded up to a millisecond;
  macOS has no ppoll.
- A readable stream socket whose peer closed is reported with POLLHUP by
  peeking one byte; macOS has no POLLRDHUP.
- FIONREAD on a datagram socket, and the byte count that fstat and kevent
  report for it, is SO_NREAD, the size of the next datagram; macOS adds the
  source address to FIONREAD.
- socketpair throws for SOCK_SEQPACKET, which has no AF_UNIX pair on macOS.
- gethostbyname replaces gethostbyname_r, which macOS lacks.

The UDP test sends on its connected socket without an address, as boykopovar#7475
does, because macOS, like FreeBSD, fails sendto with an address on a
connected socket with EISCONN. The log test uses a datagram pair with
enlarged buffers instead of SOCK_SEQPACKET.
@mugurc
mugurc force-pushed the feat/libkernel-sockets-macos branch from d7079b8 to 7701a9b Compare October 19, 2026 20:55
@mugurc

mugurc commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @fogydes. The two lines of guest_udp that #7475 changes are now changed the same way here: the connected sender sends without an address, and the sendmsg header has no name. With identical lines the two pull requests merge in either order without a conflict, so this one needs no Depends on. git merge-tree agrees for both orders on main 9127ea3.

This drops the second, unconnected socket and the macOS-only EISCONN check from this pull request. #7475 adds that check for every host, and on macOS the host already returns EISCONN there. On macOS guest_udp passes with this head alone and with #7475 merged on top. The description is updated.

@adriadam10 adriadam10 self-assigned this Oct 21, 2026
@adriadam10
adriadam10 merged commit de4ef84 into boykopovar:main Oct 21, 2026
11 of 12 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the diff: every macOS change sits behind __APPLE__, QueuedBytes keeps the ioctl(FIONREAD) call on Linux, POLLRDHUP stays in the non-Apple branch, the guest_udp lines match #7475, and the debt entries match the code; merged.

iamthehimansh added a commit to iamthehimansh/AnyPS5 that referenced this pull request Oct 21, 2026
Conflicts in Udp.cpp and LogMacros.cpp with upstream's boykopovar#7850 (UDP
sockets and name resolution on macOS hosts). Both files take upstream's
version: its QueuedBytes covers the FIONREAD datagram sizing this branch
added, its POLLRDHUP replacement covers ours, and it handles
SOCK_SEQPACKET on macOS its own way.
iamthehimansh added a commit to iamthehimansh/AnyPS5 that referenced this pull request Oct 21, 2026
Taking upstream's Udp.cpp from boykopovar#7850 dropped two macOS fixes this branch
had, and two tests failed on macOS:

- macOS refuses shutdown(SHUT_RD) with ENOTCONN once the peer has shut
  down its sending side, although the socket is still connected and
  queued data stays readable; the console accepts it. guest_socket_pair
  aborted there.
- After the peer closes, macOS can fail the next stream send with
  ECONNRESET where FreeBSD reports EPIPE. guest_socket_read_write failed
  2 runs in 8 expecting errno 32.

Both are restored on top of upstream's code. The other macOS socket
changes this branch had are covered by boykopovar#7850 or not needed by any test.

macOS only; the Linux and Windows views match upstream. All 35 socket,
network, log and event-queue tests pass run one at a time, and
guest_socket_read_write passes 20 of 20.
iamthehimansh added a commit to iamthehimansh/AnyPS5 that referenced this pull request Oct 21, 2026
Taking upstream's Udp.cpp from boykopovar#7850 also dropped this branch's macOS
poll loop for urgent data. macOS poll() neither reports POLLPRI for
pending TCP urgent data nor wakes for it, so guest_poll aborted on
every run (6 of 6).

The loop is restored as a macOS-only branch of poll_nid_postfix ahead
of upstream's generic ::poll path: SIOCATMARK reports the urgent byte
without consuming it, and while a socket waits for it the wait is cut
into short slices and re-checked.

macOS only; the Linux and Windows views match upstream. guest_poll
passes 6 of 6, and all 60 socket, network, log and poll tests pass run
one at a time.
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.

3 participants