Skip to content

Support macOS and the BSDs, not just Linux#1

Merged
jaredLunde merged 1 commit into
mainfrom
portability-macos-bsd
Jun 4, 2026
Merged

Support macOS and the BSDs, not just Linux#1
jaredLunde merged 1 commit into
mainfrom
portability-macos-bsd

Conversation

@jaredLunde
Copy link
Copy Markdown
Contributor

Why

handoff's mechanism is plain POSIX — fork/exec FD inheritance, flock, Unix-domain control sockets, signals. None of it is Linux-only; the crate was just incidentally Linux-bound. This makes services that embed handoff build and run on macOS and the BSDs with no opt-in — automatic via #[cfg(target_os = …)], not a Cargo feature (an embedder shouldn't have to flip a flag to get a working build on their platform).

A full sweep of every libc::/nix:: call site found exactly one production break, two test breaks, and a docs cleanup. Everything else is uniform across Unix (verified: no pidfd/signalfd/prctl/epoll/memfd//proc in library code; FD handoff is fork/exec inheritance, not SCM_RIGHTS).

Changes

  • supervisor.rsmake_socketpair() cfg-gates SOCK_CLOEXEC on the control socketpair. macOS doesn't define that flag (nix won't even compile the symbol there), so the macOS path creates the pair then sets FD_CLOEXEC via a follow-up fcntl. The Linux/BSD atomic path is unchanged. The non-atomic window on macOS is theoretical — this runs on the rare swap path, not under a fork storm.
  • fd.rs — drops SOCK_CLOEXEC from a test socketpair (throwaway source FDs for the dup2-shuffle assertion; the flag isn't needed and isn't defined on macOS).
  • stress.rs — FD-leak counter reads /dev/fd instead of /proc/self/fd. /dev/fd is the portable spelling: a symlink to /proc/self/fd on Linux, a real fdescfs on macOS and FreeBSD.
  • CI — new macos-latest test job (runs unit + integration + stress, so it actually exercises the fcntl cloexec fallback and /dev/fd enumeration that cross-compilation can't), plus a FreeBSD cross-compile check (GitHub has no free BSD runner, so a type-check is the pragmatic proof the BSD path stays buildable).
  • Docs — broadened the rename-atomicity note beyond Linux (APFS/UFS/ZFS hold the same guarantee); added a Platforms section.

Out of scope

Windows — no fork/exec FD inheritance, no flock. It would need a separate backend behind the Drainable API; that's a different decision, not requested here.

Verification (local, on Linux)

cargo check cross-compiles without an Apple/BSD SDK (type-check only, no linking):

  • cargo check --workspace --all-targets --target aarch64-apple-darwin — proves the macOS cfg branch compiles and nothing else is silently Linux-bound
  • cargo check --workspace --all-targets --target x86_64-unknown-freebsd
  • ✅ Native Linux: full test suite passes (lib + integration + crash-matrix + stress + wire-race + slow-seal), clippy clean, fmt clean

The macOS CI job in this PR is what validates the macOS code paths running for real.

🤖 Generated with Claude Code

The handoff mechanism is plain POSIX — fork/exec FD inheritance, flock,
Unix-domain control sockets, signals — with no Linux-only syscalls. It was
only incidentally Linux-bound. Make it build and run on macOS and the BSDs
automatically (via cfg, not a Cargo feature — no opt-in for embedders).

- supervisor.rs: cfg-gate SOCK_CLOEXEC on the control socketpair. macOS
  doesn't define the flag (nix won't compile the symbol there), so fall back
  to a follow-up fcntl(FD_CLOEXEC) on each end. Linux/BSD path unchanged.
- fd.rs: drop SOCK_CLOEXEC from a test socketpair — throwaway source FDs
  don't need it, and dropping it keeps the test compiling on macOS.
- stress.rs: read /dev/fd instead of /proc/self/fd for the FD-leak counter.
  /dev/fd is the portable spelling across Linux, macOS, and FreeBSD.
- CI: add a macos-latest test job (exercises the fcntl fallback and /dev/fd
  for real) and a FreeBSD cross-compile check (no free BSD runner exists).
- Docs: broaden the rename-atomicity note beyond Linux; add a Platforms
  section (Linux/macOS/BSD supported, Windows not).

Windows is out of scope: no fork/exec FD inheritance and no flock, so the
model would need a separate backend.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jaredLunde jaredLunde merged commit 7133357 into main Jun 4, 2026
1 check passed
@jaredLunde jaredLunde mentioned this pull request Jun 5, 2026
jaredLunde added a commit that referenced this pull request Jun 5, 2026
Patch release: macOS/BSD portability (#1) plus the macOS EINVAL flake fix
on the supervisor's SO_RCVTIMEO arm against a closed peer (#2).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant