Treat Hammerhead like Solaris/illumos in the os-layer meson build. Meson derives host_machine.system() from uname sysname, which on Hammerhead is "hammerhead", not "sunos". The os/ static library's Solaris branch (which adds -lsocket/-lnsl and the _XOPEN_SOURCE/__EXTENSIONS__ defines needed for struct msghdr.msg_control and the XPG socket API) therefore never fires, producing undefined socket()/gethostbyname() symbols at link time. Hammerhead IS illumos, so extend the guard to match its sysname. --- a/os/meson.build +++ b/os/meson.build @@ -63,7 +63,7 @@ os_c_args = [] # eg. struct msghdr -> msg_control -if host_machine.system() == 'sunos' +if host_machine.system() == 'sunos' or host_machine.system() == 'hammerhead' os_c_args += '-D_XOPEN_SOURCE=1' os_c_args += '-D_XOPEN_SOURCE_EXTENDED=1' os_c_args += '-D__EXTENSIONS__' Fix inverted re-arm check in the illumos event-ports (PORT_SOURCE_FD) ospoll backend - the listening socket only ever accepted exactly one client for the lifetime of the server. Root cause (found 2026-07-22, hh-alpha9, Task 8 M5 integration test): illumos event ports are one-shot per delivered event - once port_getn() returns an event for a PORT_SOURCE_FD object, that fd is automatically dissociated from the port and MUST be re-associated (port_associate() again, done here via epoll_mod()) to keep receiving further events on it. ospoll_wait()'s PORT-backend dispatch loop re-arms level-triggered fds with: if (osfd->trigger == ospoll_trigger_level && !xorg_list_is_empty(&osfd->deleted)) { epoll_mod(ospoll, osfd); } osfd->deleted is the intrusive list node ospoll_remove() links onto ospoll->deleted when an fd is torn down (see the xorg_list_add call right after port_dissociate() in ospoll_remove()). So xorg_list_is_empty(&osfd->deleted) is true exactly when this specific fd has NOT just been removed by its own callback - i.e. it's still a live, valid fd safe to re-arm. The listening socket is a level-triggered fd that lives for the entire server lifetime and is never removed, so its deleted node is always empty. With the `!` in front, the condition only fires when the fd HAS just been deleted (backwards - re-arming an fd that's about to be freed), and never fires for the common "still alive" case. Net effect: the listen socket's single initial port_associate() (done at ospoll_add time) gets consumed by the first accept() event and is never renewed, so every connection after the first sits unnoticed in the kernel accept backlog forever. Confirmed via truss -p : after the first client's full connection setup, port_getn() goes back to sleeping and no further accept(4, ...) call is ever made, even though a second client's connect() has already completed at the socket layer (visible in `netstat -f unix` as a live but un-accepted pair). Fix: drop the negation so accepting fds get re-armed, and only skip fds that were actually just torn down. --- a/os/ospoll.c +++ b/os/ospoll.c @@ -638,7 +638,7 @@ osfd->callback(osfd->fd, xevents, osfd->data); if (osfd->trigger == ospoll_trigger_level && - !xorg_list_is_empty(&osfd->deleted)) { + xorg_list_is_empty(&osfd->deleted)) { epoll_mod(ospoll, osfd); } }