# Vendored `libc` Fork — Redox `waitid` Surface **Status:** TEMPORARY. Vendored for as long as it is required; delete once upstream `libc` carries the Redox bindings. **Location:** `local/sources/libc/` **Base:** crates.io `libc` 0.2.189, unmodified except `src/unix/redox/mod.rs`. **Version label:** `0.2.189+rb` — Cat 2 convention. `+rb` is build metadata, which semver ignores when matching, so `^0.2` requirements still resolve to the fork. A `-rb` suffix would read as a pre-release and fail. **Established:** 2026-08-03. Related: `LOCAL-FORK-SUPREMACY-POLICY.md`, `FORK-BUMP-PATCHING-POLICY.md`, `local/AGENTS.md` § "Local fork dependency rule". --- ## Why this fork exists relibc implements the POSIX `waitid` surface in full, but the `libc` crate's Redox bindings never exposed it — and still do not as of 0.2.189. Any crate that calls `waitid` therefore cannot build for `x86_64-unknown-redox`: ``` error[E0531]: cannot find unit struct, unit variant or constant `CLD_EXITED` in crate `libc` error[E0531]: cannot find unit struct, unit variant or constant `P_ALL` in crate `libc` ``` That breaks `nix`, and through it `ctrlc` and rustc's bootstrap tooling — which is what blocked `rust-native`, and with it the whole native toolchain (`gcc-native`, `llvm-native`, `rust-native`) that `config/redbear-full.toml` requires. This is a **binding gap, not a missing implementation**. Every symbol added here is already real in relibc: | Symbol | relibc source | Evidence | |---|---|---| | `waitid()` | `src/header/sys_wait/mod.rs:153` | `nm libc.a` → `T waitid` | | `idtype_t` | `src/header/sys_wait/mod.rs:17` | `pub type idtype_t = c_int` | | `P_ALL` / `P_PID` / `P_PGID` | `src/header/sys_wait/mod.rs:20-24` | `0` / `1` / `2` | | `CLD_*` (6) | `include/signal.h:457-467` | `CLD_EXITED 1` … `CLD_CONTINUED 6` | Values and types are taken from **relibc**, not from Linux. Redox's `idtype_t` is `c_int` where glibc uses an enum, and copying the Linux definitions would have produced a silently wrong ABI. ## What is actually changed One file: `src/unix/redox/mod.rs`. Every other target is byte-for-byte upstream 0.2.189, so host builds and all non-Redox targets are unaffected. ## How it is wired `[patch.crates-io]` in the rust workspace, carried durably as `local/patches/rust/02-libc-redox-fork.patch`: ```toml libc = { path = "../../../../local/sources/libc" } ``` `+rb` build metadata is what makes this safe: it leaves the upstream semver (`0.2.189`) intact, so `^0.2` requirements still resolve. A `-rb` suffix would be read as a pre-release and fail to satisfy them — see `local/AGENTS.md` § "Version conventions". Registered in `local/fork-upstream-map.toml` as `diverged`. The fork is vendored from the crates.io **package**, whose file set differs from the upstream git tag by construction — the package omits `.github/` and adds `.cargo_vcs_info.json` — so a tag content-diff reports differences that mean nothing. `snapshot` mode was tried first and produced exactly that noise. `src/unix/redox/mod.rs` is also on the expected-differ list in `verify-fork-versions.sh` for when the mode changes. ## Retiring this fork Upstream-reportable: the gap belongs in the `libc` crate. When upstream exposes the Redox `waitid` surface: 1. Confirm `CLD_*`, `P_*`, `idtype_t` and `waitid` are all present in `src/unix/redox/mod.rs` for the version being resolved. 2. Drop `02-libc-redox-fork.patch` from `recipes/dev/rust/recipe.toml`. 3. Remove the `libc` row from `local/fork-upstream-map.toml` and both `libc)` arms from `verify-fork-versions.sh`. 4. Delete `local/sources/libc/`. 5. Rebuild `rust-native` to confirm `nix` still compiles. Until then this fork stays. Bumping it follows `FORK-BUMP-PATCHING-POLICY.md`: re-vendor the newer upstream and re-apply the Redox block — never carry the old base forward.