Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Layer 0 Spec — Crate air-sys-types

Technical specification — Version 0.1 (partial, to be completed)

⚠️ Document status

This spec covers the fundamental types of the air-sys-types crate, identified throughout the specifications of the syscall families. The types are grouped by their family of origin. The estimated total is roughly ~187 public types in the complete crate.

This document lists the types and their signatures. A complete spec would detail, for each type, its methods, invariants, conversions, and tests. Work to resume: produce the exhaustive spec type by type, in parallel with the actual implementation.

Crate overview

The air-sys-types crate is the absolute foundation of the Air stack: every other module depends on it. It exposes:

  • The fundamental newtypes: Errno, Pid, Tid, etc.
  • The RAII wrappers for kernel resources: OwnedFd, BorrowedFd, Mapping, etc.
  • The bitflags for kernel flags: OpenFlags, CloneFlags, etc.
  • The typed enums for kernel semantics: Signal, Capability, etc.
  • The data structures mirroring the kernel: StatxResult, SignalFdInfo, etc.

Crate principles.

  1. No allocation by default. The fundamental types (Errno, Pid, etc.) are newtypes over primitive types, without allocation.

  2. #[repr(transparent)] or #[repr(C)] as needed. Types that must have a kernel-compatible layout use #[repr(C)]. Simple newtypes use #[repr(transparent)].

  3. Explicit conversions. Conversions between types (for example, Pid::as_raw() -> i32) are explicit via named methods, not via implicit From/Into.

  4. Validation at construction. Types that have invariants (for example, Pid, which is NonZeroI32) validate at construction and expose try_new methods that return Option or Result.

  5. Extensive documentation. Each type has a docstring that explains its role, its invariants, and its relationship with the kernel.

Fundamental types (universal)

Errno

#![allow(unused)]
fn main() {
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Errno(NonZeroI32);

impl Errno {
    // ~140 constants corresponding to the standard errno codes
    pub const EPERM: Self;
    pub const ENOENT: Self;
    pub const ESRCH: Self;
    pub const EINTR: Self;
    pub const EIO: Self;
    // ... etc.
    
    pub const fn as_raw(self) -> i32;
    pub const fn name(self) -> &'static str;
    pub const fn description(self) -> &'static str;
}

impl core::fmt::Display for Errno { /* ... */ }
impl core::error::Error for Errno {}
}

See ADR-019 for the context.

File descriptors

#![allow(unused)]
fn main() {
pub struct OwnedFd { /* ... */ }
pub struct BorrowedFd<'fd> { /* ... */ }
pub type RawFd = i32;

impl OwnedFd {
    pub fn as_fd(&self) -> BorrowedFd<'_>;
    pub fn into_raw_fd(self) -> RawFd;
    pub unsafe fn from_raw_fd(fd: RawFd) -> Self;
}

impl<'fd> BorrowedFd<'fd> {
    pub fn as_raw_fd(&self) -> RawFd;
    pub unsafe fn borrow_raw(fd: RawFd) -> Self;
}

impl Drop for OwnedFd {
    fn drop(&mut self) { /* calls close(fd), ignores error */ }
}
}

Discipline: every FD managed by Air goes through OwnedFd/BorrowedFd. No bare RawFd except in the raw APIs.

DirFd

#![allow(unused)]
fn main() {
pub enum DirFd<'fd> {
    Cwd,
    Fd(BorrowedFd<'fd>),
}
}

Basis for the *at operations (see ADR-021 convention 1).

Types of the process family

#![allow(unused)]
fn main() {
pub struct Pid(NonZeroI32);
pub struct Tid(NonZeroI32);

pub struct PidFd { /* internal OwnedFd */ }
pub struct PidFdReceiver { /* ... */ }
pub struct TidReceiver { /* ... */ }

pub enum WaitTarget<'fd> {
    AnyChild,
    Pid(Pid),
    ProcessGroup(Pid),
    AnyProcessGroup,
    PidFd(BorrowedFd<'fd>),
}

pub struct WaitOptions(i32);  // bitflags
pub struct WaitStatus {
    pub pid: Pid,
    pub uid: u32,
    pub event: WaitEvent,
}

pub enum WaitEvent {
    Exited { code: i32 },
    Killed { signal: Signal, core_dumped: bool },
    Stopped { signal: Signal },
    Continued,
    Trapped { signal: Signal },
}

pub struct CloneFlags(u64);  // bitflags
pub struct CloneArgs { /* ... */ }
pub enum CloneResult { /* ... */ }

pub struct Signal(NonZeroI32);
pub struct SignalMask { /* ... */ }

pub enum Capability { /* enum of the Linux capabilities */ }
pub struct CapabilityMask(u64);
pub struct CapabilitySet { /* ... */ }
pub enum CapabilityTarget { /* ... */ }

pub enum Resource { /* enum of the Linux limits */ }
pub struct Rlimit { /* ... */ }
pub enum RlimitValue { Finite(u64), Infinity }

pub enum DumpableMode { /* ... */ }
pub struct ExecveatFlags(i32);  // bitflags
pub struct PidFdOpenFlags(u32);  // bitflags
}

~20 types for this family.

Types of the fs family

#![allow(unused)]
fn main() {
pub struct OpenFlags(u64);  // bitflags
pub type Mode = u32;
pub struct OpenHow { /* ... */ }
pub struct ResolveFlags(u64);  // bitflags

pub struct StatxResult { /* ... */ }
pub struct StatxMask(u32);  // bitflags
pub struct StatxFlags(u32);  // bitflags
pub struct StatxTimestamp { /* ... */ }

pub struct AccessMode(u32);  // bitflags
pub struct AccessFlags(i32);  // bitflags

pub struct RenameFlags(u32);  // bitflags
pub struct FallocateMode(i32);  // bitflags

pub enum SeekWhence { Set, Current, End, Data, Hole }

pub struct DirEntry { /* ... */ } // name: Vec<u8> (octets) — ADR-048
pub enum DirEntryType { /* ... */ }
pub struct DirEntryIter<'buf> { /* ... */ }

pub enum UtimeValue { Now, Omit, Time(StatxTimestamp) }

pub struct FdFlags(i32);  // bitflags
pub struct StatusFlags(i32);  // bitflags
pub struct FileLock { /* ... */ }
pub struct Seals(u32);  // bitflags

pub struct FileHandle { /* ... */ }
pub struct NameToHandleFlags(i32);  // bitflags

pub struct IoSlice<'data> { /* ... */ }
pub struct IoSliceMut<'data> { /* ... */ }
}

~25 types for this family.

Types of the mem family

#![allow(unused)]
fn main() {
pub struct Mapping {
    addr: NonNull<u8>,
    length: usize,
}
pub struct MappingPointer { /* ... */ }

pub struct ProtectionFlags(i32);  // bitflags
pub struct MapFlags(i32);  // bitflags
pub struct MremapFlags(i32);  // bitflags

pub enum MadviseAdvice { /* ~25 variants */ }

pub struct MlockFlags(u32);  // bitflags
pub struct MlockallFlags(i32);  // bitflags

pub struct MemfdFlags(u32);  // bitflags
pub struct MsyncFlags(i32);  // bitflags

pub struct RemoteIoSlice { /* ... */ }
}

~10 types for this family.

Types of the io_uring module

Type placement (ADR-022 / ADR-028). This document specifies the air-sys-types crate. For io_uring, only the pure-data types (with no behavior, no FD/mmap, no lifetime tied to a ring) live here; the stateful / coupled types (ring, builders, tokens, completions, #[repr(C)] mirrors, RAII guards) live in air-sys-syscall::io_uring by encapsulation. The rule is decided Temps by Temps, as the implementation progresses.

Note (naming, ADR-029). Explicit facade names, without abbreviation. The old abbreviated names (IoUringOp, RawSqe, RawCqe, RawOp, FdPool, RegisteredBuffer, ProvidedBuffers) are replaced; the kernel mirrors keep their short inherited names.

#![allow(unused)]
fn main() {
// PLACEMENT (ADR-022/028). Only `SetupFlags`, `CompletionFlags` and
// `IoUringOpcode` live in `air-sys-types` (pure types, delivered in Temps 1).
// ALL the other types below live in `air-sys-syscall::io_uring`
// (stateful / coupled — encapsulation); listed here for reference, specified in
// the `io-uring-*.md` specs. The later Temps will place their types according to
// the same rule (pure here, coupled in air-sys-syscall).
pub struct IoUring { /* ... */ }
pub struct IoUringBuilder { /* ... */ }
pub struct IoUringParams { /* ... */ }
pub struct IoUringCapabilities { /* ... */ }
pub struct SetupFlags(u32);  // bitflags

pub struct Completion { /* ... */ }
pub struct CompletionFlags(u32);  // bitflags
pub struct CompletionIter<'ring> { /* ... */ }
pub struct SubmitOptions { /* ... */ }

pub struct SubmissionToken(/* opaque: slot index + generation */);
pub struct MultishotToken(/* opaque */);

pub enum IoUringOpcode { /* enum of the operations */ }
pub enum CancelTarget { /* token / fd / op / any */ }

// Fixed resources (Temps 3a)
pub struct FixedFdTable { /* ... */ }
pub struct FixedSlot<'t> { /* ... */ }
pub enum FixedSlotTarget { /* Index(u32) | Alloc */ }
pub struct RegisteredBuffers { /* ... */ }
pub struct RegisteredBufferSlice<'b> { /* ... */ }
pub struct Personality(/* id */);
pub struct WorkQueueWorkerLimits { /* ... */ }
pub struct NapiConfig { /* ... */ }
pub enum ClockSource { /* Monotonic | Boottime | Realtime */ }

// Ring-mapped provided buffers (Temps 3b)
pub struct ProvidedBufferRing { /* ... */ }
pub struct ProvidedBuffer<'r> { /* RAII guard */ }
pub struct ProvidedBufferRingOptions { /* ... */ }
pub struct ProvidedBufferRingStatus { /* ... */ }

// Linked / multishot / zero-copy network
pub struct LinkedChainBuilder<'ring> { /* ... */ }
pub struct ChainTokens { /* ... */ }
pub struct ZeroCopyFlags(u32);  // bitflags

// Multi-thread (Temps 3e)
pub struct LockedIoUring { /* ... */ }
pub struct RingPool { /* ... */ }
pub struct RingHandle { /* ... */ }
pub struct SqpollIoUring { /* ... */ }

// Confinement (Temps 3f)
pub struct RestrictionSet { /* ... */ }
pub enum Restriction { /* ... */ }
pub enum RegisterOp { /* ... */ }
pub struct SqeFlagSet { /* ... */ }

// Raw access level 1 (Temps 4) — verbose type, fields = kernel names
#[repr(C)]
pub struct RawSubmissionQueueEntry { /* 64 bytes; fields user_data, res… */ }

#[repr(C)]
pub struct RawCompletionQueueEntry { /* 16 or 32 bytes */ }

pub struct RawOpcode(pub u8);
pub const RAW_USER_DATA_TAG: u64 = 1 << 63;

pub struct TimeoutFlags(u32);  // bitflags
pub struct PollEvents(u32);  // bitflags
pub enum EpollOp { /* ... */ }
pub struct EpollEvent { /* ... */ }
}

In air-sys-types: 3 types (Temps 1 — SetupFlags, CompletionFlags, IoUringOpcode). The others live in air-sys-syscall::io_uring or are not yet implemented.

Types of the signal family

#![allow(unused)]
fn main() {
pub struct SignalFdInfo { /* ... */ }
pub struct SignalFdFlags(i32);  // bitflags

pub struct SignalQueueInfo { /* ... */ }
pub enum SignalValue { Integer(i32), Pointer(u64) }

// synchronous_handler submodule
pub enum FatalSignal { Segv, Bus, Fpe, Ill }
pub struct SignalInfo { /* ... */ }
pub struct PreviousHandler { /* opaque */ }
}

~6 types for this family.

Types of the time family

#![allow(unused)]
fn main() {
pub enum Clock {
    Realtime, Monotonic, ProcessCpuTime, ThreadCpuTime,
    MonotonicRaw, RealtimeCoarse, MonotonicCoarse,
    Boottime, RealtimeAlarm, BoottimeAlarm, Tai,
}

pub struct Instant {
    clock: Clock,
    seconds: i64,
    nanoseconds: u32,
}

pub struct Timespec { /* internal */ }

pub struct TimerFd { /* internal OwnedFd */ }
pub struct TimerFdSpecification {
    pub initial: Duration,
    pub interval: Duration,
}
pub struct TimerFdFlags(i32);  // bitflags
pub struct TimerSetFlags(i32);  // bitflags

pub enum SleepDeadline {
    Relative(Duration),
    AbsoluteInstant(Instant),
}

pub enum SleepError {
    Interrupted { remaining: Duration },
    Other(Errno),
}
}

~9 types for this family.

Types of the net family

#![allow(unused)]
fn main() {
pub enum SocketDomain { /* ... */ }
pub enum SocketType { /* ... */ }
pub enum SocketAddr {
    Unix(UnixSocketAddr),
    Inet(InetSocketAddr),
    Inet6(Inet6SocketAddr),
    // ...
}

pub struct UnixSocketAddr { /* ... */ }
pub struct InetSocketAddr { /* ... */ }
pub struct Inet6SocketAddr { /* ... */ }

pub struct MessageFlags(i32);  // bitflags
pub struct AcceptFlags(i32);  // bitflags
pub struct AcceptResult { /* ... */ }

pub struct SendMessageRequest { /* ... */ }
pub struct ReceiveMessageRequest { /* ... */ }
pub struct SendMessageResult { /* ... */ }
pub struct ReceiveMessageResult { /* ... */ }
pub enum ShutdownMode { Read, Write, Both }

pub enum AncillarySent { /* ... */ }
pub enum AncillaryReceived { /* ... */ }

pub enum SocketOptionLevel { /* ... */ }
pub enum LingerOption { Disabled, Enabled(Duration) }

pub struct UnixCredentials { /* ... */ }
}

~20 types for this family.

Types of the ipc family

#![allow(unused)]
fn main() {
pub struct EventFd { /* internal OwnedFd */ }
pub struct EventFdFlags(i32);  // bitflags

pub struct PipeFlags(i32);  // bitflags
pub struct SpliceFlags(u32);  // bitflags
}

~4 types for this family.

Types of the security family

#![allow(unused)]
fn main() {
pub struct SeccompFilter { /* ... */ }
pub struct SeccompRule { /* ... */ }
pub enum SeccompAction { /* ... */ }
pub enum SeccompMode { /* ... */ }
pub struct SeccompFilterFlags(u32);  // bitflags

pub struct SyscallNumber(i32);
pub struct SyscallArgumentCondition { /* ... */ }
pub enum ConditionOp { /* ... */ }

pub struct LandlockRuleset { /* ... */ }
pub struct LandlockAccessFs(u64);  // bitflags
}

~10 types for this family.

Types of the system family

#![allow(unused)]
fn main() {
pub struct UtsName {
    pub sysname: CString,
    pub nodename: CString,
    pub release: CString,
    pub version: CString,
    pub machine: CString,
    pub domainname: CString,
}

pub struct SystemInfo { /* ... */ }
pub struct GetrandomFlags(u32);  // bitflags
}

3 types for this family.

Global summary

FamilyApproximate number of types
Fundamental5 (Errno, OwnedFd, BorrowedFd, RawFd, DirFd)
process20
fs25
mem10
io_uring (in air-sys-types)3 (Temps 1)
signal6
time9
net20
ipc4
security10
system3

Estimated total: ~140-160 public types.

The final spec would perhaps have a few more types depending on the needs that emerge during implementation. The initial estimate of ~187 types remains reasonable.

Work to resume

TODO: produce an exhaustive spec of air-sys-types:

For each type, document:

  • Internal representation (#[repr(...)]).
  • Constructors (new, try_new, etc.) and invariants.
  • Main methods (as_raw, from_raw, conversions).
  • Trait implementations (Debug, Display, Error, Clone, Copy, etc.).
  • Tests to plan for (constructions, invariants, conversions).
  • Relationship with the equivalent kernel types.

This exhaustive spec is probably to be produced in parallel with the actual implementation of the crate, rather than ahead of it, because adjustments will emerge naturally.


Document license: MPL 2.0 Status: Partial spec of the air-sys-types crate. To be completed in parallel with the implementation.