What's Changed
BREAKING: CallFunction now returns (syscall.Errno, error)
errno is always captured inside the assembly trampoline, immediately after the C function returns — the only thread-safe window before the Go runtime can migrate the goroutine to a different OS thread.
goffi is the first pure-Go FFI with correct errno capture on Linux.
Migration
// Before (v0.5.x):
err := ffi.CallFunction(cif, fn, &result, args)
// After (v0.6.0):
errno, err := ffi.CallFunction(cif, fn, &result, args)
// Or if errno not needed:
_, err := ffi.CallFunction(cif, fn, &result, args)Why Always-Capture?
Opt-in CallFunctionErrno is a pit of failure — you don't know you need errno until the function fails, and by then the goroutine may be on a different OS thread. Cost: ~3-5 ns per call.
Platform Support
| Platform | errno function | Library |
|---|---|---|
| Linux (glibc/musl) | __errno_location |
libc.so.6 |
| macOS | __error |
libSystem.B.dylib |
| FreeBSD | __error |
libc.so.7 |
| Windows | — | Returns errno=0 (uses GetLastError separately) |
Also Includes (from v0.5.6 → v0.6.0)
- Callback stack-move corruption fix (PR #59 by @tie)
sync.PoolforsyscallArgs(goroutine stack safety)structs.HostLayouton all ABI-boundary structs- Example avalue fix + CI examples check
- FreeBSD ARM64 support (8 platforms total)
Thanks to @tie for the stack-move fix, @unxed for performance proposals, and @lkmavi for testing!