1//! `rustix` provides efficient memory-safe and [I/O-safe] wrappers to
2//! POSIX-like, Unix-like, Linux, and Winsock2 syscall-like APIs, with
3//! configurable backends.
4//!
5//! With rustix, you can write code like this:
6//!
7//! ```
8//! # #[cfg(feature = "net")]
9//! # fn read(sock: std::net::TcpStream, buf: &mut [u8]) -> std::io::Result<()> {
10//! # use rustix::net::RecvFlags;
11//! let nread: usize = rustix::net::recv(&sock, buf, RecvFlags::PEEK)?;
12//! # let _ = nread;
13//! # Ok(())
14//! # }
15//! ```
16//!
17//! instead of like this:
18//!
19//! ```
20//! # #[cfg(feature = "net")]
21//! # fn read(sock: std::net::TcpStream, buf: &mut [u8]) -> std::io::Result<()> {
22//! # use std::convert::TryInto;
23//! # #[cfg(unix)]
24//! # use std::os::unix::io::AsRawFd;
25//! # #[cfg(target_os = "wasi")]
26//! # use std::os::wasi::io::AsRawFd;
27//! # #[cfg(windows)]
28//! # use windows_sys::Win32::Networking::WinSock as libc;
29//! # #[cfg(windows)]
30//! # use std::os::windows::io::AsRawSocket;
31//! # const MSG_PEEK: i32 = libc::MSG_PEEK;
32//! let nread: usize = unsafe {
33//! #[cfg(any(unix, target_os = "wasi"))]
34//! let raw = sock.as_raw_fd();
35//! #[cfg(windows)]
36//! let raw = sock.as_raw_socket();
37//! match libc::recv(
38//! raw as _,
39//! buf.as_mut_ptr().cast(),
40//! buf.len().try_into().unwrap_or(i32::MAX as _),
41//! MSG_PEEK,
42//! ) {
43//! -1 => return Err(std::io::Error::last_os_error()),
44//! nread => nread as usize,
45//! }
46//! };
47//! # let _ = nread;
48//! # Ok(())
49//! # }
50//! ```
51//!
52//! rustix's APIs perform the following tasks:
53//! - Error values are translated to [`Result`]s.
54//! - Buffers are passed as Rust slices.
55//! - Out-parameters are presented as return values.
56//! - Path arguments use [`Arg`], so they accept any string type.
57//! - File descriptors are passed and returned via [`AsFd`] and [`OwnedFd`]
58//! instead of bare integers, ensuring I/O safety.
59//! - Constants use `enum`s and [`bitflags`] types.
60//! - Multiplexed functions (eg. `fcntl`, `ioctl`, etc.) are de-multiplexed.
61//! - Variadic functions (eg. `openat`, etc.) are presented as non-variadic.
62//! - Functions that return strings automatically allocate sufficient memory
63//! and retry the syscall as needed to determine the needed length.
64//! - Functions and types which need `l` prefixes or `64` suffixes to enable
65//! large-file support (LFS) are used automatically. File sizes and offsets
66//! are always presented as `u64` and `i64`.
67//! - Behaviors that depend on the sizes of C types like `long` are hidden.
68//! - In some places, more human-friendly and less historical-accident names
69//! are used (and documentation aliases are used so that the original names
70//! can still be searched for).
71//! - Provide y2038 compatibility, on platforms which support this.
72//! - Correct selected platform bugs, such as behavioral differences when
73//! running under seccomp.
74//!
75//! Things they don't do include:
76//! - Detecting whether functions are supported at runtime, except in specific
77//! cases where new interfaces need to be detected to support y2038 and LFS.
78//! - Hiding significant differences between platforms.
79//! - Restricting ambient authorities.
80//! - Imposing sandboxing features such as filesystem path or network address
81//! sandboxing.
82//!
83//! See [`cap-std`], [`system-interface`], and [`io-streams`] for libraries
84//! which do hide significant differences between platforms, and [`cap-std`]
85//! which does perform sandboxing and restricts ambient authorities.
86//!
87//! [`cap-std`]: https://crates.io/crates/cap-std
88//! [`system-interface`]: https://crates.io/crates/system-interface
89//! [`io-streams`]: https://crates.io/crates/io-streams
90//! [`getrandom`]: https://crates.io/crates/getrandom
91//! [`bitflags`]: https://crates.io/crates/bitflags
92//! [`AsFd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.AsFd.html
93//! [`OwnedFd`]: https://doc.rust-lang.org/stable/std/os/fd/struct.OwnedFd.html
94//! [I/O-safe]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md
95//! [`Result`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html
96//! [`Arg`]: https://docs.rs/rustix/*/rustix/path/trait.Arg.html
97
98#![deny(missing_docs)]
99#![allow(stable_features)]
100#![cfg_attr(linux_raw, deny(unsafe_code))]
101#![cfg_attr(rustc_attrs, feature(rustc_attrs))]
102#![cfg_attr(doc_cfg, feature(doc_cfg))]
103#![cfg_attr(all(wasi_ext, target_os = "wasi", feature = "std"), feature(wasi_ext))]
104#![cfg_attr(
105 all(linux_raw, naked_functions, target_arch = "x86"),
106 feature(naked_functions)
107)]
108#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
109#![cfg_attr(core_ffi_c, feature(core_ffi_c))]
110#![cfg_attr(core_c_str, feature(core_c_str))]
111#![cfg_attr(alloc_c_string, feature(alloc_ffi))]
112#![cfg_attr(alloc_c_string, feature(alloc_c_string))]
113#![cfg_attr(not(feature = "std"), no_std)]
114#![cfg_attr(feature = "rustc-dep-of-std", feature(ip))]
115#![cfg_attr(
116 any(feature = "rustc-dep-of-std", core_intrinsics),
117 feature(core_intrinsics)
118)]
119#![cfg_attr(asm_experimental_arch, feature(asm_experimental_arch))]
120#![cfg_attr(not(feature = "all-apis"), allow(dead_code))]
121// Clamp depends on Rust 1.50 which is newer than our MSRV.
122#![allow(clippy::manual_clamp)]
123// It is common in linux and libc APIs for types to vary between platforms.
124#![allow(clippy::unnecessary_cast)]
125// It is common in linux and libc APIs for types to vary between platforms.
126#![allow(clippy::useless_conversion)]
127// Redox and WASI have enough differences that it isn't worth
128// precisely conditionallizing all the `use`s for them.
129#![cfg_attr(any(target_os = "redox", target_os = "wasi"), allow(unused_imports))]
130// On the release branch, don't worry about unused-import warnings.
131#![allow(unused_imports)]
132
133#[cfg(not(feature = "rustc-dep-of-std"))]
134extern crate alloc;
135
136// Internal utilities.
137#[cfg(not(windows))]
138#[macro_use]
139pub(crate) mod cstr;
140#[macro_use]
141pub(crate) mod const_assert;
142pub(crate) mod utils;
143
144// linux_raw: Weak symbols are used by the use-libc-auxv feature for
145// glibc 2.15 support.
146//
147// libc: Weak symbols are used to call various functions available in some
148// versions of libc and not others.
149#[cfg(any(
150 all(linux_raw, feature = "use-libc-auxv"),
151 all(libc, not(any(windows, target_os = "wasi")))
152))]
153#[macro_use]
154mod weak;
155
156// Pick the backend implementation to use.
157#[cfg_attr(libc, path = "backend/libc/mod.rs")]
158#[cfg_attr(linux_raw, path = "backend/linux_raw/mod.rs")]
159#[cfg_attr(wasi, path = "backend/wasi/mod.rs")]
160mod backend;
161
162/// Export the `*Fd` types and traits that are used in rustix's public API.
163///
164/// Users can use this to avoid needing to import anything else to use the same
165/// versions of these types and traits.
166pub mod fd {
167 use super::backend;
168 #[cfg(windows)]
169 pub use backend::fd::AsSocket;
170 pub use backend::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
171}
172
173// The public API modules.
174#[cfg(not(windows))]
175pub mod ffi;
176#[cfg(not(windows))]
177#[cfg(feature = "fs")]
178#[cfg_attr(doc_cfg, doc(cfg(feature = "fs")))]
179pub mod fs;
180pub mod io;
181#[cfg(linux_kernel)]
182#[cfg(feature = "io_uring")]
183#[cfg_attr(doc_cfg, doc(cfg(feature = "io_uring")))]
184pub mod io_uring;
185#[cfg(not(any(windows, target_os = "wasi")))]
186#[cfg(feature = "mm")]
187#[cfg_attr(doc_cfg, doc(cfg(feature = "mm")))]
188pub mod mm;
189#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
190#[cfg(feature = "net")]
191#[cfg_attr(doc_cfg, doc(cfg(feature = "net")))]
192pub mod net;
193#[cfg(not(windows))]
194#[cfg(feature = "param")]
195#[cfg_attr(doc_cfg, doc(cfg(feature = "param")))]
196pub mod param;
197#[cfg(not(windows))]
198#[cfg(any(feature = "fs", feature = "net"))]
199#[cfg_attr(doc_cfg, doc(cfg(any(feature = "fs", feature = "net"))))]
200pub mod path;
201#[cfg(not(windows))]
202#[cfg(feature = "process")]
203#[cfg_attr(doc_cfg, doc(cfg(feature = "process")))]
204pub mod process;
205#[cfg(not(windows))]
206#[cfg(not(target_os = "wasi"))]
207#[cfg(feature = "pty")]
208#[cfg_attr(doc_cfg, doc(cfg(feature = "pty")))]
209pub mod pty;
210#[cfg(not(windows))]
211#[cfg(feature = "rand")]
212#[cfg_attr(doc_cfg, doc(cfg(feature = "rand")))]
213pub mod rand;
214#[cfg(not(windows))]
215#[cfg(feature = "termios")]
216#[cfg_attr(doc_cfg, doc(cfg(feature = "termios")))]
217pub mod termios;
218#[cfg(not(windows))]
219#[cfg(feature = "thread")]
220#[cfg_attr(doc_cfg, doc(cfg(feature = "thread")))]
221pub mod thread;
222#[cfg(not(windows))]
223#[cfg(feature = "time")]
224#[cfg_attr(doc_cfg, doc(cfg(feature = "time")))]
225pub mod time;
226
227// "runtime" is also a public API module, but it's only for libc-like users.
228#[cfg(not(windows))]
229#[cfg(feature = "runtime")]
230#[doc(hidden)]
231#[cfg_attr(doc_cfg, doc(cfg(feature = "runtime")))]
232pub mod runtime;
233
234// We have some internal interdependencies in the API features, so for now,
235// for API features that aren't enabled, declare them as `pub(crate)` so
236// that they're not public, but still available for internal use.
237
238#[cfg(all(
239 linux_raw,
240 not(windows),
241 not(feature = "fs"),
242 not(feature = "use-libc-auxv"),
243 not(target_vendor = "mustang"),
244 any(
245 feature = "param",
246 feature = "runtime",
247 feature = "time",
248 target_arch = "x86",
249 )
250))]
251pub(crate) mod fs;
252#[cfg(not(windows))]
253#[cfg(all(
254 not(feature = "param"),
255 any(feature = "runtime", feature = "time", target_arch = "x86"),
256))]
257pub(crate) mod param;
258#[cfg(not(windows))]
259#[cfg(not(any(feature = "fs", feature = "net")))]
260pub(crate) mod path;
261#[cfg(not(windows))]
262#[cfg(not(feature = "process"))]
263pub(crate) mod process;
264