// std/net/epoll (the linux twin of std/net/kqueue): the raw bindings lower for // a linux target with a byte-exact `epoll_event` layout — 12-byte stride on // x86_64 (packed), modelled as an arch-branched `{events, data_lo, data_hi}` // struct of u32 fields (no packed attribute, no unaligned access). Exercises // create / ctl / wait + the readiness accessors so the IR covers the surface. // // Imports ONLY epoll.sx (libc-only — no std/build) so the .ir snapshot stays // small and churns only when the bindings change. ir-only on the aarch64-macOS // dev host (target x86_64-linux mismatches host arch+os → the runner asserts // .exit + .ir + .stderr from `sx ir --target`); runtime behavior validates on a // linux runner (see the module header's VALIDATION NOTE). The `inline if ARCH` // in epoll.sx is resolved by the compiler's flatten pre-pass, so no build.sx. ep :: #import "modules/std/net/epoll.sx"; main :: () -> i32 { epfd := ep.ep_create(); // register read + peer-close interest on a fd, then drain readiness if !ep.ep_ctl(epfd, ep.EPOLL_CTL_ADD, 1, ep.EPOLLIN | ep.EPOLLRDHUP) { return 2; } ep.ep_ctl(epfd, ep.EPOLL_CTL_MOD, 1, ep.EPOLLIN | ep.EPOLLOUT); evs : [8]ep.EpollEvent = ---; sl : []ep.EpollEvent = .{ ptr = @evs[0], len = 8 }; n := ep.ep_wait(epfd, sl, 8, 100); if n > 0 { if ep.ev_readable(evs[0]) { return ep.ev_fd(evs[0]); } if ep.ev_writable(evs[0]) { return 4; } if ep.ev_eof(evs[0]) { return 9; } if ep.ev_err(evs[0]) { return 8; } } ep.ep_ctl(epfd, ep.EPOLL_CTL_DEL, 1, 0); return xx size_of(ep.EpollEvent); // 12 on x86_64 }