ReviewOS

home-lang/home

Native FilePoll: decode kevent errors and retire already-removed registrations

#501
Closed chris opened this 11 days ago ·
11 days ago

Follow-up to #66, #493 and #499. The unchanged pinned regression test/js/bun/spawn/spawn-pipe-stale-fd-unregister.test.ts fails in native Home with a five-second timeout. Extracting its exact fixture reveals panic: attempt to use null value during teardown after a registered stdout fd is deliberately closed and its number reused. This also reproduces before the #499 input changes. Installed Bun 1.3.14 fails this newer regression too (empty output instead of OK), so it is not a passing control.

The native FilePoll still feeds positive kevent error values through Maybe.errnoSys, which decodes a syscall return code, and then unwraps null. The selected current Bun Rust implementation has direct kevent_change_error decoding, preserves global syscall failures separately, and treats ENOENT/EBADF during deregistration as already removed so registration flags are cleared. Home's Linux/FreeBSD deregistration paths also need the corresponding already-removed handling.

Port the actual error conventions and flag cleanup; preserve the unchanged fixture's fd close/reuse, pending read, cancellation, child cleanup and OK/exit assertions. Verify repeated teardown and adjacent timer/spawn/watchers to catch stale registration or event-loop lifetime regressions. Darwin is locally executable; Linux/FreeBSD behavior needs its own validation and must not be counted as proven merely by compiling guarded code.

Source pin: 4982b91e3702094330f3be3883354c52b8c01323. This is distinct from Blob/stream input validation and rejected-payload cleanup in #499 and raw extra socket ownership in #495.

11 days ago

Published ba2cf90dc on codex/runtime-port as Chris Breuer with no coauthors. Not merged into main.

Ported direct kevent error-value decoding, separate handling of global syscall failure, and already-removed deregistration handling. ENOENT/EBADF now allow registration flags to clear; other errors remain errors. Both-direction packed error events are handled without interpreting positive errno data as a syscall return code. Linux and FreeBSD receive the corresponding source-level deregistration handling, but their runtime behavior is not locally verified.

The exact unchanged stale-fd regression passes 1 test / 3 assertions on Darwin, plus three additional runs. The old fixture produced a null-unwrap panic and then the test deadline. The full native spawn file passes 126 tests / 5484 assertions / 5 skips, all 21 native regression files pass, and the final main batch is 34/34 commands. Build and cached rebuild: 17/17.

This does not establish Bun.Terminal support: the wider audit found its skeleton creation/I/O methods, now tracked in #503. #499 and #502 cover separate input semantics/ownership changes. Keeping this open pending integration and other-platform verification under #66.

11 days ago

The direct kevent change-error decoding and already-removed deregistration handling for Linux, Darwin, and FreeBSD are now on main in ba2cf90dc.

Reverified the unchanged pinned spawn-pipe-stale-fd-unregister.test.ts on current native Home: 1 pass / 0 fail / 3 assertions. The deliberate registered-fd close/reuse completes naturally instead of panicking or timing out. The 59-file native runtime aggregate also passes.

Closing the integrated Darwin reproduction. Other-platform whole-suite validation remains tracked under #66.

Sign in to comment on this issue.