linux_api/lib.rs
1//! Type definitions and utilities for interacting with the Linux API.
2//! Does not depend on the `std` crate (i.e. is `no_std`) nor libc.
3//!
4//! We currently re-export C bindings. This allows normal C code, using
5//! libc headers, to work with these kernel types. Normally this can't be done
6//! because the libc and kernel headers contain incompatible definitions.
7//!
8//! # Type names
9//!
10//! We provide 3 styles of types:
11//!
12//! * snake-cased-types prefixed with `linux_`. These are ABI-compatible with
13//! the corresponding kernel types. These types are re-exported in this crate's
14//! generated C header, and are the types used in exported C function APIs.
15//!
16//! * snake-cased-types *without* the `linux_` prefix. These are *also* ABI-compatible
17//! with the corresponding kernel types, and are intended for use in Rust
18//! code. They never require or enforce invariants beyond that bytes are
19//! initialized, so are safe to transmute from initialized bytes, or from the
20//! corresponding `linux_` type if the required bytes are known to be
21//! initialized. See [`crate::signal::sigaction`] for an example of a type
22//! with such invariants.
23//!
24//! We do *not* expose these types in C interfaces, since they have the same
25//! name as types in the original Linux headers, and often with the same name
26//! in C library headers. Exported C APIs should use the `linux_` types in their
27//! signatures, and convert internally to the non-prefixed types. In cases
28//! where the 2 types are not simply aliased, they usually implement
29//! `bytemuck::TransparentWrapper` or similar APIs that allow converting
30//! values *and references* in both directions.
31//!
32//! * camel-cased types are *not* necessarily bitwise-compatible with kernel types
33//! with similar names. These primarily include `enum`s and `bitflags` types.
34//! Kernel constants such as `O_WRONLY` are typically defined as instants of
35//! such types, and are convertible to and from the original integer types.
36
37#![cfg_attr(not(any(test, feature = "std")), no_std)]
38// https://github.com/rust-lang/rfcs/blob/master/text/2585-unsafe-block-in-unsafe-fn.md
39#![deny(unsafe_op_in_unsafe_fn)]
40#![allow(clippy::not_unsafe_ptr_arg_deref)]
41#![allow(clippy::enum_variant_names)]
42#![allow(clippy::too_many_arguments)]
43
44#[allow(non_upper_case_globals)]
45#[allow(non_camel_case_types)]
46#[allow(non_snake_case)]
47// https://github.com/rust-lang/rust/issues/66220
48#[allow(improper_ctypes)]
49#[allow(unsafe_op_in_unsafe_fn)]
50#[allow(clippy::all)]
51#[allow(unused)]
52mod bindings;
53
54pub mod auxvec;
55pub mod capability;
56pub mod close_range;
57pub mod epoll;
58pub mod errno;
59pub mod exit;
60pub mod fcntl;
61pub mod futex;
62pub mod inet;
63pub mod ioctls;
64pub mod ldt;
65pub mod limits;
66pub mod mman;
67pub mod netlink;
68pub mod poll;
69pub mod posix_types;
70pub mod prctl;
71pub mod resource;
72pub mod rseq;
73pub mod rtnetlink;
74pub mod sched;
75pub mod signal;
76pub mod socket;
77pub mod stat;
78pub mod syscall;
79pub mod sysinfo;
80pub mod time;
81pub mod types;
82pub mod ucontext;
83pub mod utsname;
84pub mod wait;
85
86// Internally we often end up needing to convert from types that bindgen inferred, in const
87// contexts.
88//
89// We could use `as`, but it'd be easy to accidentally truncate, especially if
90// the constant we're converting isn't the type we thought it was.
91//
92// Because these are in const contexts, we can't use `try_from`.
93mod const_conversions {
94 pub const fn u64_from_u32(val: u32) -> u64 {
95 // Guaranteed not to truncate
96 val as u64
97 }
98
99 pub const fn usize_from_u32(val: u32) -> usize {
100 // Guaranteed not to truncate
101 val as usize
102 }
103
104 pub const fn i32_from_u32(val: u32) -> i32 {
105 // Maybe not strictly necessary for safety, but probably
106 // a mistake of some kind if this fails.
107 assert!(val <= (i32::MAX as u32));
108
109 val as i32
110 }
111
112 pub const fn i32_from_u32_allowing_wraparound(val: u32) -> i32 {
113 val as i32
114 }
115
116 pub const fn u16_from_u32(val: u32) -> u16 {
117 assert!(val <= (u16::MAX as u32));
118
119 val as u16
120 }
121}