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//! ```rust 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//! ```rust 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 and types which need `l` prefixes or `64` suffixes to enable 63//! large-file support are used automatically, and file sizes and offsets 64//! are presented as `u64` and `i64`. 65//! - Behaviors that depend on the sizes of C types like `long` are hidden. 66//! - In some places, more human-friendly and less historical-accident names 67//! are used (and documentation aliases are used so that the original names 68//! can still be searched for). 69//! - Provide y2038 compatibility, on platforms which support this. 70//! - Correct selected platform bugs, such as behavioral differences when 71//! running under seccomp. 72//! 73//! Things they don't do include: 74//! - Detecting whether functions are supported at runtime. 75//! - Hiding significant differences between platforms. 76//! - Restricting ambient authorities. 77//! - Imposing sandboxing features such as filesystem path or network address 78//! sandboxing. 79//! 80//! See [`cap-std`], [`system-interface`], and [`io-streams`] for libraries 81//! which do hide significant differences between platforms, and [`cap-std`] 82//! which does perform sandboxing and restricts ambient authorities. 83//! 84//! [`cap-std`]: https://crates.io/crates/cap-std 85//! [`system-interface`]: https://crates.io/crates/system-interface 86//! [`io-streams`]: https://crates.io/crates/io-streams 87//! [`getrandom`]: https://crates.io/crates/getrandom 88//! [`bitflags`]: https://crates.io/crates/bitflags 89//! [`AsFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.AsFd.html 90//! [`OwnedFd`]: https://docs.rs/io-lifetimes/latest/io_lifetimes/struct.OwnedFd.html 91//! [io-lifetimes crate]: https://crates.io/crates/io-lifetimes 92//! [I/O-safe]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md 93//! [`Result`]: https://docs.rs/rustix/latest/rustix/io/type.Result.html 94//! [`Arg`]: https://docs.rs/rustix/latest/rustix/path/trait.Arg.html 95 96#![deny(missing_docs)] 97#![allow(stable_features)] 98#![cfg_attr(linux_raw, deny(unsafe_code))] 99#![cfg_attr(rustc_attrs, feature(rustc_attrs))] 100#![cfg_attr(doc_cfg, feature(doc_cfg))] 101#![cfg_attr(all(target_os = "wasi", feature = "std"), feature(wasi_ext))] 102#![cfg_attr( 103 all(linux_raw, naked_functions, target_arch = "x86"), 104 feature(naked_functions) 105)] 106#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] 107#![cfg_attr(core_ffi_c, feature(core_ffi_c))] 108#![cfg_attr(core_c_str, feature(core_c_str))] 109#![cfg_attr(alloc_c_string, feature(alloc_ffi))] 110#![cfg_attr(alloc_c_string, feature(alloc_c_string))] 111#![cfg_attr(not(feature = "std"), no_std)] 112#![cfg_attr(feature = "rustc-dep-of-std", feature(core_intrinsics))] 113#![cfg_attr(feature = "rustc-dep-of-std", feature(ip))] 114#![cfg_attr( 115 all(not(feature = "rustc-dep-of-std"), core_intrinsics), 116 feature(core_intrinsics) 117)] 118#![cfg_attr(asm_experimental_arch, feature(asm_experimental_arch))] 119#![cfg_attr(not(feature = "all-apis"), allow(dead_code))] 120// Clamp depends on Rust 1.50 which is newer than our MSRV. 121#![allow(clippy::manual_clamp)] 122// It is common in linux and libc APIs for types to vary between platforms. 123#![allow(clippy::unnecessary_cast)] 124// It is common in linux and libc APIs for types to vary between platforms. 125#![allow(clippy::useless_conversion)] 126 127#[cfg(not(feature = "rustc-dep-of-std"))] 128extern crate alloc; 129 130// Internal utilities. 131#[cfg(not(windows))] 132#[macro_use] 133pub(crate) mod cstr; 134#[macro_use] 135pub(crate) mod const_assert; 136pub(crate) mod utils; 137 138// Pick the backend implementation to use. 139#[cfg_attr(libc, path = "backend/libc/mod.rs")] 140#[cfg_attr(linux_raw, path = "backend/linux_raw/mod.rs")] 141#[cfg_attr(wasi, path = "backend/wasi/mod.rs")] 142mod backend; 143 144/// Export the `*Fd` types and traits that are used in rustix's public API. 145/// 146/// Users can use this to avoid needing to import anything else to use the same 147/// versions of these types and traits. 148pub mod fd { 149 use super::backend; 150 #[cfg(windows)] 151 pub use backend::fd::AsSocket; 152 pub use backend::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; 153} 154 155// The public API modules. 156#[cfg(not(windows))] 157pub mod ffi; 158#[cfg(not(windows))] 159#[cfg(feature = "fs")] 160#[cfg_attr(doc_cfg, doc(cfg(feature = "fs")))] 161pub mod fs; 162pub mod io; 163#[cfg(any(target_os = "android", target_os = "linux"))] 164#[cfg(feature = "io_uring")] 165#[cfg_attr(doc_cfg, doc(cfg(feature = "io_uring")))] 166pub mod io_uring; 167#[cfg(not(any(windows, target_os = "wasi")))] 168#[cfg(feature = "mm")] 169#[cfg_attr(doc_cfg, doc(cfg(feature = "mm")))] 170pub mod mm; 171#[cfg(not(any(target_os = "redox", target_os = "wasi")))] 172#[cfg(feature = "net")] 173#[cfg_attr(doc_cfg, doc(cfg(feature = "net")))] 174pub mod net; 175#[cfg(not(windows))] 176#[cfg(feature = "param")] 177#[cfg_attr(doc_cfg, doc(cfg(feature = "param")))] 178pub mod param; 179#[cfg(not(windows))] 180#[cfg(any(feature = "fs", feature = "net"))] 181#[cfg_attr(doc_cfg, doc(cfg(any(feature = "fs", feature = "net"))))] 182pub mod path; 183#[cfg(not(windows))] 184#[cfg(feature = "process")] 185#[cfg_attr(doc_cfg, doc(cfg(feature = "process")))] 186pub mod process; 187#[cfg(not(windows))] 188#[cfg(feature = "rand")] 189#[cfg_attr(doc_cfg, doc(cfg(feature = "rand")))] 190pub mod rand; 191#[cfg(not(windows))] 192#[cfg(feature = "termios")] 193#[cfg_attr(doc_cfg, doc(cfg(feature = "termios")))] 194pub mod termios; 195#[cfg(not(windows))] 196#[cfg(feature = "thread")] 197#[cfg_attr(doc_cfg, doc(cfg(feature = "thread")))] 198pub mod thread; 199#[cfg(not(windows))] 200#[cfg(feature = "time")] 201#[cfg_attr(doc_cfg, doc(cfg(feature = "time")))] 202pub mod time; 203 204// "runtime" is also a public API module, but it's only for libc-like users. 205#[cfg(not(windows))] 206#[cfg(feature = "runtime")] 207#[doc(hidden)] 208#[cfg_attr(doc_cfg, doc(cfg(feature = "runtime")))] 209pub mod runtime; 210 211// We have some internal interdependencies in the API features, so for now, 212// for API features that aren't enabled, declare them as `pub(crate)` so 213// that they're not public, but still available for internal use. 214 215#[cfg(not(windows))] 216#[cfg(all( 217 not(feature = "param"), 218 any(feature = "runtime", feature = "time", target_arch = "x86"), 219))] 220pub(crate) mod param; 221#[cfg(not(windows))] 222#[cfg(not(any(feature = "fs", feature = "net")))] 223pub(crate) mod path; 224#[cfg(not(windows))] 225#[cfg(not(feature = "process"))] 226pub(crate) mod process; 227