Repository navigation
feat(libkernel): UDP sockets and name resolution on macOS hosts - #7850
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.
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.
|
fogydes
left a comment
There was a problem hiding this comment.
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
…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>
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.
d7079b8 to
7701a9b
Compare
|
Thanks @fogydes. The two lines of This drops the second, unconnected socket and the macOS-only |
|
Checked the diff: every macOS change sits behind |
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.
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.
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.
What
UDP sockets and name resolution on macOS hosts. The socket layer calls
ppolland asks forPOLLRDHUP, and the resolver callsgethostbyname_r; macOS has none of them, solibkernelandlibScePosixForWebKitdo not compile on macOS without this. Part of the macOS series announced on #1 (#1 (comment)).pollwith the timeout rounded up to a millisecond.POLLHUPby peeking one byte.FIONREADon a datagram socket, and the byte count thatfstatandkeventreport for it, come fromSO_NREAD, the size of the next datagram. macOS'sFIONREADcounts every queued datagram together with its source address. One helper,QueuedBytes, serves the three; on Linux it makes the sameioctl(FIONREAD)call as before.socketpairthrows forSOCK_SEQPACKET, which has noAF_UNIXpair on macOS, andguest_socket_pairexpects that throw there.gethostbynamereplacesgethostbyname_r; macOS keeps its result in thread-specific storage.guest_udpsends on its connected socket without an address. macOS, like FreeBSD, failssendtowith an address on a connected socket withEISCONN, 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 returnEISCONNthere on every host and checks it, so the two pull requests merge in either order.log_macroscaptures its writes through a datagram pair with 1 MiB buffers instead ofSOCK_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_NREADforfstatandkevent.Tested
macOS 26.5.1, Apple M5 Max, Apple clang 21, x86-64 build under Rosetta 2.
main9127ea3 with the rest of the macOS series (ci/macos-series-2on 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.Without this PR,
libkernelandlibScePosixForWebKitdo not compile on macOS (ppoll,POLLRDHUP,gethostbyname_r). With it,guest_udp,guest_tcp,guest_kqueue,guest_equeue_events,guest_resolver,log_macrosandlog_macros_timestampspass.With
SO_NREADinioctlonly (the first version of this commit),guest_kqueueaborts where it expects a kevent byte count of 1 for a 1-byte datagram on anAF_UNIXpair. A probe, run under Rosetta and natively, shows why.FIONREADreads 17 for that datagram, 35 after a second 2-byte datagram and 21 for a 5-byte UDP datagram on loopback.SO_NREADreads 1, 1 and 5.guest_socket_pair,guest_pollandguest_sce_netstill fail on macOS, at checks this PR does not touch:shutdown(SHUT_RD)fails withENOTCONNon a stream end whose peer shut its writing side.polldoes not report urgent data withPOLLPRI.sceNetShutdowndoes not wake arecvfromblocked on an unbound UDP socket.feat: macOS on Apple Silicon host support (Rosetta 2 and MoltenVK) #7332 handles all three. With the failing
shutdowncheck reported instead of required, the rest ofguest_socket_pairpasses, including theSOCK_SEQPACKETcheck this PR adds.guest_udpandguest_kqueuepass 5 runs of 5. With fix(libkernel): return EISCONN from sendto with an address on a connected datagram socket #7475 merged on top,guest_udppasses 5 runs of 5 as well.ninja,ninja libsandctest -j4: 1624 tests, 991 passed, 23 failed, the rest skipped (no Vulkan loader in the environment). 17 failures are the same as in the run before this update, all among the failures feat(libkernel): direct memory mappings on macOS hosts #7631 lists. Five come from tests thatmainadded or changed today, in feat(libc): implement floating-point rounding and exception flags #6985, fix(libc): honor guest TZ in time conversions #6916, fix(libc): call guest unwind callbacks with the System V ABI on Windows #6851 and feat(libc): implement std::_Throw_bad_optional_access #7872. The last isguest_socket_read_write, which fails only some runs; it passed when run alone afterwards.Linux and Windows: not run. On Linux,
QueuedBytesmakes the sameioctlcall as before andgethostbyname_rruns as before. The twoguest_udplines send on a connected socket without an address, which every host accepts; fix(libkernel): return EISCONN from sendto with an address on a connected datagram socket #7475 ran the same lines on Windows. Every other change is in an__APPLE__branch.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)