FreeBSD Compatibility Layer
lib/basalt/c/src/compat/freebsd/ contains 16 Rust modules that implement FreeBSD-specific APIs needed by ported BSD utilities.
Some modules are real implementations (md5, rune table, bsd_sort, libutil); others are stubs that return success without doing anything substantive (capsicum, mntent, login_cap).
This page enumerates each module, identifies which ones are real and which are stubs, and notes the practical implications for ports.
Module List
| Module | Status | Purpose |
|---|---|---|
|
Real |
|
|
Real |
|
|
Real |
Small BSD-specific I/O helpers like |
|
Real |
|
|
Real |
|
|
Real |
FreeBSD |
|
Stub |
Capsicum file arguments. Accepts the API surface but does no capability work — returns successful results that effectively pass through to the regular file API. |
|
Stub |
Capsicum cap_rights surface ( |
|
Real |
FreeBSD libutil functions: |
|
Stub (mostly) |
|
|
Real |
RFC 1321 MD5 implementation. Used by |
|
Stub |
|
|
Real |
FreeBSD |
|
Stub |
|
|
Stub |
FreeBSD’s |
|
Stub |
libxo structured output library. Implements |
Real Implementations
The "real" modules implement the BSD function as specified. Ports that use them get the same behavior they would on FreeBSD:
bsd_err.rs-
The
err/warnfamily is essential for BSD utilities. basaltc’s implementation is byte-for-byte compatible with FreeBSD’s. bsd_flags.rs-
File flags are used by
chflagsandls -lO. basaltc parses and formats the standard flag names. The underlying file flags are stored in the file’s metadata via VFS, but very few SaltyOS ports actually rely on them. bsd_misc.rs-
Small BSD-specific helpers (
getbsize,setprogname,getprogname). The actualarc4randomChaCha20 CSPRNG seeded fromgetentropy()lives instdlib.rsrather than this file — see Environment and Arguments. bsd_sort.rs-
mergesortandheapsortgive callers a choice of algorithm with the same signature asqsort. Real implementations, no fall-through toqsort. bsd_io.rs-
fgetlnreturns a pointer into the FILE’s read buffer (zero-copy), unlikefgetswhich copies into a caller buffer. Real implementation that respects the FILE buffer state. bsd_stdio.rs-
The
stdoutp/stdinp/__stderrpaliases are pointers initialized at startup. See Buffered I/O for details. md5.rs-
RFC 1321 MD5 with the standard
MD5_CTXstate struct. Used bycrypt($1$), by ports that hash data, and bytarfor archive integrity. rune.rs-
The C-locale rune table with
_RuneLocalestruct compatible with FreeBSD. Theinit_rune_locale()function copies the static C rune table into the active state at startup. libutil.rs-
Real implementations of
humanize_number,expand_number,dehumanize_number,fgetln, and other libutil entry points. These are written from FreeBSD’s published semantics and are used byhead(1),tail(1),df(1), and similar utilities.
Stub Implementations
The "stub" modules accept the API but do not implement the underlying functionality:
cap_fileargs.rsandcapsicum.rs-
Capsicum is FreeBSD’s capability-based security framework. SaltyOS has its own capability system in the kernel, but it does not expose Capsicum semantics to userland. The stubs let ports that include the Capsicum API surface link, but the security guarantees Capsicum is supposed to provide do not apply. Ports that depend on Capsicum for sandboxing should be patched to use seccomp-style restrictions or be marked unsafe to run on SaltyOS.
login_cap.rs-
/etc/login.confprovides per-user resource limits and authentication settings. basaltc returns the default class for everyone — no parsing happens. Ports that consult login_cap to set process limits or session parameters get the defaults instead. This is enough for port operation but not for production multi-user systems. mntent.rs-
The mount-point enumeration interface (
/etc/fstabreading). basaltc’s stub returns "no mounts" because SaltyOS does not yet have a/etc/fstabconvention. Ports that walk mount points (typically system administration tools) get an empty list. statvfs.rs-
Filesystem statistics. The stub returns plausible defaults without querying actual disk usage. Programs like
dfwill show the same values for every filesystem. A real implementation requires VFS protocol additions that have not been done yet. umtx.rs-
FreeBSD’s low-level mutex syscall. Returns
ENOSYS. Ports that use this directly (rare — pthread is preferred) will fail. The pthread implementation is real and uses futex instead. xo.rs-
libxo lets a program emit one structured representation that can be rendered as text, XML, JSON, or HTML. basaltc emits text only by passing the format strings to
printfand ignoring the structured annotations. Ports that need JSON output (somefreebsd-utilsuse it) get text output.
Why Stubs Instead of Errors?
The stubs return success because:
-
They let ports link without requiring per-port source patches that remove the API call.
-
The non-stub behavior is what most callers actually want — most ports do not check the return value of
cap_enterorxo_open_container. -
The alternative (failing the call) would force ports to either patch the call sites or skip large code paths, both more invasive than accepting a stub.
The cost is that ports relying on the actual functionality (Capsicum sandboxing, JSON output from ls) silently lose that functionality.
This is a trade-off basaltc makes deliberately.
The README at lib/basalt/c/README.md should list which stubs are present so port authors know what to expect.
When to Promote a Stub to Real
A stub should be promoted to a real implementation when:
-
A SaltyOS port depends on the actual functionality, not the stub.
-
The underlying SaltyOS service (VFS, kernel, procmgr) supports the operation.
-
The implementation can be straightforward (no major design work needed).
For example, statvfs would be straightforward to implement once VFS exposes filesystem statistics.
mntent would follow naturally from a /etc/fstab convention being adopted.
Capsicum requires more thought because SaltyOS’s capability model differs from FreeBSD’s, and a faithful Capsicum emulation would be a substantial project.
Linux vs BSD Errno
A reminder from trona Boundary: basaltc uses Linux errno numbers, not BSD numbers. This affects compat/freebsd modules that might compare errno against literals. The compat modules in basaltc are written against the basaltc errno values, so they are internally consistent — but a port that hardcodes BSD errno numbers in its own code will see different values than it would on FreeBSD.
The most common breakage points are EAGAIN (BSD 35, Linux 11), ENAMETOOLONG (BSD 63, Linux 36), and ELOOP (BSD 62, Linux 40).
Active SaltyOS ports already carry patches for these where needed.
Related Pages
-
Environment and Arguments —
bsd_err.rs(err/warn) andbsd_misc.rs(setprogname) -
Users and Groups —
md5.rsprovides$1$crypt support -
Locale, ctype and wchar —
rune.rsprovides the C-locale rune table -
trona Boundary — Linux errno numbering as a BSD/Linux delta