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"))] 128 extern crate alloc; 129 130 // Internal utilities. 131 #[cfg(not(windows))] 132 #[macro_use] 133 pub(crate) mod cstr; 134 #[macro_use] 135 pub(crate) mod const_assert; 136 pub(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")] 142 mod 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. 148 pub 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))] 157 pub mod ffi; 158 #[cfg(not(windows))] 159 #[cfg(feature = "fs")] 160 #[cfg_attr(doc_cfg, doc(cfg(feature = "fs")))] 161 pub mod fs; 162 pub 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")))] 166 pub mod io_uring; 167 #[cfg(not(any(windows, target_os = "wasi")))] 168 #[cfg(feature = "mm")] 169 #[cfg_attr(doc_cfg, doc(cfg(feature = "mm")))] 170 pub 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")))] 174 pub mod net; 175 #[cfg(not(windows))] 176 #[cfg(feature = "param")] 177 #[cfg_attr(doc_cfg, doc(cfg(feature = "param")))] 178 pub 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"))))] 182 pub mod path; 183 #[cfg(not(windows))] 184 #[cfg(feature = "process")] 185 #[cfg_attr(doc_cfg, doc(cfg(feature = "process")))] 186 pub mod process; 187 #[cfg(not(windows))] 188 #[cfg(feature = "rand")] 189 #[cfg_attr(doc_cfg, doc(cfg(feature = "rand")))] 190 pub mod rand; 191 #[cfg(not(windows))] 192 #[cfg(feature = "termios")] 193 #[cfg_attr(doc_cfg, doc(cfg(feature = "termios")))] 194 pub mod termios; 195 #[cfg(not(windows))] 196 #[cfg(feature = "thread")] 197 #[cfg_attr(doc_cfg, doc(cfg(feature = "thread")))] 198 pub mod thread; 199 #[cfg(not(windows))] 200 #[cfg(feature = "time")] 201 #[cfg_attr(doc_cfg, doc(cfg(feature = "time")))] 202 pub 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")))] 209 pub 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 ))] 220 pub(crate) mod param; 221 #[cfg(not(windows))] 222 #[cfg(not(any(feature = "fs", feature = "net")))] 223 pub(crate) mod path; 224 #[cfg(not(windows))] 225 #[cfg(not(feature = "process"))] 226 pub(crate) mod process; 227