โ—index ๐Ÿape-rust-scoreboard.md ๐Ÿท๏ธtags ๐Ÿ‘คabout

๐Ÿ One Binary, Six OSes: What I'd Tell Myself Before Starting

Sixth and last post in the one-bin-to-rule-them-all series. Previously: intro, probe matrix, extern-static pattern, ripgrep and dog, the async wall.

Five posts of evidence ๐Ÿ.. A probe, three real tools, a forked libc, a stack of std patches, a new reusable crate for system config, and a clean cut between what works and what doesn't. This post is the wrap-up: the finding-by-finding scoreboard, the things I had wrong in my head going in, and a proper thank-you to the people whose shoulders this whole thing sits on.

I'll keep it short. The substance lives in the preceding posts; this is the index ๐Ÿ“š.

Finding disposition

Fourteen findings came out of the investigation. Twelve are closed by the work in the previous posts, two are deferred to cosmo itself, one is really just expected behaviour that we noted and moved on from. Ordered by finding number, not by importance:

IDWhat brokeClosed by
F-001struct stat layout wrong on aarch64libc-cosmo: redefine stat for cosmo-aarch64
F-002errno numbers pass through unnormalised on BSD / macOSstd patch: extern-static COSMO_E* cascade in sys/io/error/unix.rs
F-003socket constants mismatch, TcpListener::bind failslibc-cosmo: extern-static socket constants
F-004Command::new fails on non-Linuxstd patch: process/unix/common.rs switches to ErrorKind::WouldBlock check
F-005thread::sleep panics on FreeBSDlibc-cosmo: CLOCK_MONOTONIC extern-static
F-006cosmo loader aborts on OpenBSD 7.7+deferred: cosmo-side, not a Rust fix
F-007OpenBSD 7.6 installer kernel panic in my qemudeferred: qemu/kernel interaction, out of scope
F-008Windows errno passthroughsame std patch as F-002
F-009TcpListener::bind fails on Windowssame as F-003 via libc-cosmo
F-010Command::new("echo") fails on Windowsworking as designed: echo is a cmd builtin, not a PE binary
F-011Instant::elapsed panics on macOS / OpenBSDsame as F-005, plus std patch in sys/time/unix.rs
F-013getrandom probe misclassifies ENOSYSgetrandom-cosmo: skip the probe under cfg(cosmo)
F-014no /etc/resolv.conf on Windowscosmo-sysconf: runtime dispatch, GetAdaptersAddresses on Windows
F-015MSG_NOSIGNAL rejected on Windowslibc-cosmo: extern-static + one-line std patch
F-016async IO reactor is compile-time target_osdeferred: structural, needs a mio refactor or a cosmo-side epoll shim

Twelve closed with the patterns this series built. Three genuinely open, and the character of each open finding is worth naming.

F-006 is cosmo-side. OpenBSD 7.7 tightened syscall-origin enforcement in ways cosmo's APE loader trips over. I could not run any cosmo binary on OpenBSD 7.7 or 7.8, C or Rust. That's something that would probably have to be addressed in the loader itself, but I'm not the person to say how. I poked around enough to convince myself it wasn't a Rust-side problem and then stopped.

F-007 is further out of scope than F-006. The OpenBSD 7.6 installer kernel-panicked on the qemu I was running. It isn't about cosmo and isn't about Rust; is a host-environment artefact that I recorded and moved on from. The fact that OpenBSD 7.4 is in the matrix via a prebuilt cloud image is the workaround.

F-016 is the one from the previous post, and it's the most interesting of the three. It's the only one that stops the series' thesis at the door, because neither the extern-static pattern nor a cfg(cosmo) gate can reach it. Async Rust under cosmo is Linux-only today, and I don't have a confident view of what it would take to change that.

Things I got wrong going in

I expected macOS to be the hard target, it was mostly easy. I expected Windows to be intractable, it came down to one honest-to-goodness Windows-shaped problem (F-014, DNS discovery) and a lot of Linux-constants-baked-at-compile-time. I expected OpenBSD to be a rounding error, is actually where cosmo itself hits walls, not where Rust does. And I expected TLS to be the wall for xh, is inconvenient but tractable, and the real wall was the mio reactor, which isn't a constant-divergence problem at all.

Thank you ๐Ÿ’—

This was, honestly, a lot of fun ๐Ÿคฉ.. I learned more about syscall conventions, libc layouts, rustc targets, and the actual shape of how Rust links against the operating system than I had any right to from a handful of evenings of work, and the only reason any of that was possible is that I got to stand on the shoulders of some very large giants: Justine Tunney for Cosmopolitan and the APE format (still one of the wildest pieces of systems work I've ever read ๐Ÿ”ฅ), @ahgamut for rust-ape-example which is the entire scaffolding that made Rust-on-cosmocc possible in the first place, and the Rust ๐Ÿฆ€ community in general for a language and standard library that were close enough to "already correct" that a handful of cfg(cosmo) gates could carry most of the weight.

Sooner or later, after a healthy amount of polishing, I'll release the full set of forks and patches publicly ๐Ÿš€.. It will most likely break at the next upstream commit on any of the repos it depends on, because is the nature of living on a branch that nobody upstream has opinions about yet. But the shape of what's there today is real, and the ideas transfer even if the code rots.

If you want to see any of it with your own eyes in the meantime, the three sync binaries from post 1 are still there:

  • probe.com โ€” the 12-category probe ๐Ÿงช
  • rg.com โ€” ripgrep ๐Ÿ”Ž
  • dog.com โ€” the dog DNS CLI ๐Ÿ•

Same disclaimer as before: these are binaries from a stranger on the internet, don't trust them with anything important, run them in a VM or a container if you want to poke at them seriously ๐Ÿค.

Thanks for spending the time reading a slightly too-long journey into systems programming. It meant a lot that anyone came along for the ride ๐Ÿ’—.

Happy hacking everyone ๐Ÿฆ!

:discuss share / comment on Mastodon โ†’