• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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