Spec couche 0 — Crate air-sys-types
Spécification technique — Version 0.1 (partielle, à compléter)
⚠️ Statut du document
Cette spec couvre les types fondamentaux de la crate
air-sys-types, identifiés au fil des spécifications des familles de syscalls. Les types sont regroupés par famille d’origine. Le total estimé est d’environ ~187 types publics dans la crate complète.Ce document liste les types et leurs signatures. Une spec complète détaillerait pour chaque type ses méthodes, invariants, conversions, et tests. Travail à reprendre : produire la spec exhaustive type par type, en parallèle de l’implémentation effective.
Vue d’ensemble de la crate
La crate air-sys-types est la fondation absolue du stack Air : tous les autres modules dépendent d’elle. Elle expose :
- Les newtypes fondamentaux :
Errno,Pid,Tid, etc. - Les wrappers RAII pour les ressources kernel :
OwnedFd,BorrowedFd,Mapping, etc. - Les bitflags pour les flags kernel :
OpenFlags,CloneFlags, etc. - Les enums typés pour les sémantiques kernel :
Signal,Capability, etc. - Les structures de données mirroring kernel :
StatxResult,SignalFdInfo, etc.
Principes de la crate.
-
Pas d’allocation par défaut. Les types fondamentaux (Errno, Pid, etc.) sont des newtypes sur des types primitifs, sans allocation.
-
#[repr(transparent)]ou#[repr(C)]selon les besoins. Les types qui doivent avoir un layout kernel-compatible utilisent#[repr(C)]. Les newtypes simples utilisent#[repr(transparent)]. -
Conversions explicites. Les conversions entre types (par exemple,
Pid::as_raw() -> i32) sont explicites via méthodes nommées, pas viaFrom/Intoimplicites. -
Validation à la construction. Les types qui ont des invariants (par exemple,
Pidqui estNonZeroI32) valident à la construction et exposent des méthodestry_newqui retournentOptionouResult. -
Documentation extensive. Chaque type a un docstring qui explique son rôle, ses invariants, et son lien avec le kernel.
Types fondamentaux (universels)
Errno
#![allow(unused)]
fn main() {
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Errno(NonZeroI32);
impl Errno {
// ~140 constantes correspondant aux codes errno standards
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 {}
}
Cf. ADR-019 pour le contexte.
Jeu d’errno piloté par les besoins (extension additive du sceau). Le socle n’expose que les constantes effectivement référencées — par le code couche 0 ou par un contrat couche 1 landé qui doit mapper l’errno par nom. Le prompt
074a ainsi ajoutéEXDEV/EPIPE/ELOOP/ECONNRESET/ETIMEDOUT(+ aliasEWOULDBLOCK ≡ EAGAIN), pilotés par les contratsair-base-lib(§1 mapping) etair-filesystem(# Errors). Valeursasm-generic, identiques x86_64/aarch64. La listename()/description()exhaustive (~140) viendra avec la PR dédiée ADR-019.
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) { /* appelle close(fd), ignore erreur */ }
}
}
Discipline : tout FD géré par Air passe par OwnedFd/BorrowedFd. Pas de RawFd à nu sauf dans les APIs raw.
DirFd
#![allow(unused)]
fn main() {
pub enum DirFd<'fd> {
Cwd,
Fd(BorrowedFd<'fd>),
}
}
Base pour les opérations *at (cf. ADR-021 convention 1).
Types de la famille process
#![allow(unused)]
fn main() {
pub struct Pid(NonZeroI32);
pub struct Tid(NonZeroI32);
pub struct PidFd { /* OwnedFd interne */ }
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 { /* énum des capabilities Linux */ }
pub struct CapabilityMask(u64);
pub struct CapabilitySet { /* ... */ }
pub enum CapabilityTarget { /* ... */ }
pub enum Resource { /* énum des limites Linux */ }
pub struct Rlimit { /* ... */ }
pub enum RlimitValue { Finite(u64), Infinity }
pub enum DumpableMode { /* ... */ }
pub struct ExecveatFlags(i32); // bitflags
pub struct PidFdOpenFlags(u32); // bitflags
}
~20 types pour cette famille.
Types de la famille fs
#![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 pour cette famille.
Types de la famille mem
#![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 pour cette famille.
Types du module io_uring
Placement des types (ADR-022 / ADR-028). Ce document spécifie la crate
air-sys-types. Pourio_uring, seuls les types pure-données (sans comportement, ni FD/mmap, ni durée de vie liée à un anneau) y vivent ; les types stateful / couplés (anneau, builders, jetons, complétions, miroirs#[repr(C)], gardes RAII) vivent dansair-sys-syscall::io_uringpar encapsulation. La règle se tranche Temps par Temps, au fil de l’implémentation.Note (nommage, ADR-029). Noms de façade explicites, sans abréviation. Les anciens noms abrégés (
IoUringOp,RawSqe,RawCqe,RawOp,FdPool,RegisteredBuffer,ProvidedBuffers) sont remplacés ; les miroirs kernel gardent les noms hérités courts.
#![allow(unused)]
fn main() {
// PLACEMENT (ADR-022/028). Seuls `SetupFlags`, `CompletionFlags` et
// `IoUringOpcode` vivent dans `air-sys-types` (types purs, livrés au Temps 1).
// TOUS les autres types ci-dessous vivent dans `air-sys-syscall::io_uring`
// (stateful / couplés — encapsulation) ; listés ici pour mémoire, spécifiés dans
// les specs `io-uring-*.md`. Les Temps ultérieurs placeront leurs types selon la
// même règle (purs ici, couplés dans 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 : index de slot + génération */);
pub struct MultishotToken(/* opaque */);
pub enum IoUringOpcode { /* énum des opérations */ }
pub enum CancelTarget { /* token / fd / op / any */ }
// Ressources fixes (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 */ }
// Buffers fournis ring-mapped (Temps 3b)
pub struct ProvidedBufferRing { /* ... */ }
pub struct ProvidedBuffer<'r> { /* guard RAII */ }
pub struct ProvidedBufferRingOptions { /* ... */ }
pub struct ProvidedBufferRingStatus { /* ... */ }
// Linked / multishot / réseau zero-copy
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 { /* ... */ }
// Accès brut niveau 1 (Temps 4) — type verbeux, champs = noms kernel
#[repr(C)]
pub struct RawSubmissionQueueEntry { /* 64 octets ; champs user_data, res… */ }
#[repr(C)]
pub struct RawCompletionQueueEntry { /* 16 ou 32 octets */ }
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 { /* ... */ }
}
Dans air-sys-types : 3 types (Temps 1 — SetupFlags, CompletionFlags,
IoUringOpcode). Les autres vivent dans air-sys-syscall::io_uring ou ne sont
pas encore implémentés.
Types de la famille signal
#![allow(unused)]
fn main() {
pub struct SignalFdInfo { /* ... */ }
pub struct SignalFdFlags(i32); // bitflags
pub struct SignalQueueInfo { /* ... */ }
pub enum SignalValue { Integer(i32), Pointer(u64) }
// Sous-module synchronous_handler
pub enum FatalSignal { Segv, Bus, Fpe, Ill }
pub struct SignalInfo { /* ... */ }
pub struct PreviousHandler { /* opaque */ }
}
~6 types pour cette famille.
Types de la famille time
#![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 { /* interne */ }
pub struct TimerFd { /* OwnedFd interne */ }
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 pour cette famille.
Types de la famille net
#![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 pour cette famille.
Types de la famille ipc
#![allow(unused)]
fn main() {
pub struct EventFd { /* OwnedFd interne */ }
pub struct EventFdFlags(i32); // bitflags
pub struct PipeFlags(i32); // bitflags
pub struct SpliceFlags(u32); // bitflags
}
~4 types pour cette famille.
Types de la famille security
#![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 pour cette famille.
Types de la famille system
#![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 pour cette famille.
Récapitulatif global
| Famille | Nombre approximatif de types |
|---|---|
| Fondamentaux | 5 (Errno, OwnedFd, BorrowedFd, RawFd, DirFd) |
process | 20 |
fs | 25 |
mem | 10 |
io_uring (dans air-sys-types) | 3 (Temps 1) |
signal | 6 |
time | 9 |
net | 20 |
ipc | 4 |
security | 10 |
system | 3 |
Total estimé : ~140-160 types publics.
La spec finale aurait peut-être un peu plus de types selon les besoins qui émergent à l’implémentation. L’estimation initiale de ~187 types reste raisonnable.
Travail à reprendre
TODO : produire une spec exhaustive de
air-sys-types:Pour chaque type, documenter :
- Représentation interne (
#[repr(...)]).- Constructeurs (
new,try_new, etc.) et invariants.- Méthodes principales (
as_raw,from_raw, conversions).- Implémentations de traits (
Debug,Display,Error,Clone,Copy, etc.).- Tests à prévoir (constructions, invariants, conversions).
- Lien avec les types kernel équivalents.
Cette spec exhaustive est probablement à produire en parallèle de l’implémentation effective de la crate, plutôt qu’en amont, parce que des ajustements émergeront naturellement.
Licence du document : MPL 2.0
Statut : Spec partielle de la crate air-sys-types. À compléter en parallèle de l’implémentation.