1b8a62b91Sopenharmony_ci//! The libc backend. 2b8a62b91Sopenharmony_ci//! 3b8a62b91Sopenharmony_ci//! On most platforms, this uses the `libc` crate to make system calls. On 4b8a62b91Sopenharmony_ci//! Windows, this uses the Winsock2 API in `windows-sys`, which can be adapted 5b8a62b91Sopenharmony_ci//! to have a very `libc`-like interface. 6b8a62b91Sopenharmony_ci 7b8a62b91Sopenharmony_ci// Every FFI call requires an unsafe block, and there are a lot of FFI 8b8a62b91Sopenharmony_ci// calls. For now, set this to allow for the libc backend. 9b8a62b91Sopenharmony_ci#![allow(clippy::undocumented_unsafe_blocks)] 10b8a62b91Sopenharmony_ci// Lots of libc types vary between platforms, so we often need a `.into()` on 11b8a62b91Sopenharmony_ci// one platform where it's redundant on another. 12b8a62b91Sopenharmony_ci#![allow(clippy::useless_conversion)] 13b8a62b91Sopenharmony_ci 14b8a62b91Sopenharmony_ci#[cfg(not(any(windows, target_os = "wasi")))] 15b8a62b91Sopenharmony_ci#[macro_use] 16b8a62b91Sopenharmony_cimod weak; 17b8a62b91Sopenharmony_ci 18b8a62b91Sopenharmony_cimod conv; 19b8a62b91Sopenharmony_cimod offset; 20b8a62b91Sopenharmony_ci 21b8a62b91Sopenharmony_ci#[cfg(windows)] 22b8a62b91Sopenharmony_cimod io_lifetimes; 23b8a62b91Sopenharmony_ci#[cfg(not(windows))] 24b8a62b91Sopenharmony_ci#[cfg(not(feature = "std"))] 25b8a62b91Sopenharmony_cipub(crate) mod fd { 26b8a62b91Sopenharmony_ci pub(crate) use super::c::c_int as LibcFd; 27b8a62b91Sopenharmony_ci pub use crate::io::fd::*; 28b8a62b91Sopenharmony_ci} 29b8a62b91Sopenharmony_ci#[cfg(windows)] 30b8a62b91Sopenharmony_cipub(crate) mod fd { 31b8a62b91Sopenharmony_ci pub use super::io_lifetimes::*; 32b8a62b91Sopenharmony_ci} 33b8a62b91Sopenharmony_ci#[cfg(not(windows))] 34b8a62b91Sopenharmony_ci#[cfg(feature = "std")] 35b8a62b91Sopenharmony_cipub(crate) mod fd { 36b8a62b91Sopenharmony_ci pub use io_lifetimes::*; 37b8a62b91Sopenharmony_ci 38b8a62b91Sopenharmony_ci #[cfg(target_os = "wasi")] 39b8a62b91Sopenharmony_ci #[allow(unused_imports)] 40b8a62b91Sopenharmony_ci pub(crate) use super::c::c_int as LibcFd; 41b8a62b91Sopenharmony_ci #[cfg(unix)] 42b8a62b91Sopenharmony_ci #[allow(unused_imports)] 43b8a62b91Sopenharmony_ci pub(crate) use std::os::unix::io::RawFd as LibcFd; 44b8a62b91Sopenharmony_ci #[cfg(unix)] 45b8a62b91Sopenharmony_ci pub use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; 46b8a62b91Sopenharmony_ci #[cfg(target_os = "wasi")] 47b8a62b91Sopenharmony_ci pub use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; 48b8a62b91Sopenharmony_ci} 49b8a62b91Sopenharmony_ci 50b8a62b91Sopenharmony_ci// On Windows we emulate selected libc-compatible interfaces. On non-Windows, 51b8a62b91Sopenharmony_ci// we just use libc here, since this is the libc backend. 52b8a62b91Sopenharmony_ci#[cfg(windows)] 53b8a62b91Sopenharmony_ci#[path = "winsock_c.rs"] 54b8a62b91Sopenharmony_cipub(crate) mod c; 55b8a62b91Sopenharmony_ci#[cfg(not(windows))] 56b8a62b91Sopenharmony_cipub(crate) use libc as c; 57b8a62b91Sopenharmony_ci 58b8a62b91Sopenharmony_ci#[cfg(not(windows))] 59b8a62b91Sopenharmony_ci#[cfg(feature = "fs")] 60b8a62b91Sopenharmony_cipub(crate) mod fs; 61b8a62b91Sopenharmony_cipub(crate) mod io; 62b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 63b8a62b91Sopenharmony_ci#[cfg(feature = "io_uring")] 64b8a62b91Sopenharmony_cipub(crate) mod io_uring; 65b8a62b91Sopenharmony_ci#[cfg(not(any(windows, target_os = "wasi")))] 66b8a62b91Sopenharmony_ci#[cfg(feature = "mm")] 67b8a62b91Sopenharmony_cipub(crate) mod mm; 68b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "redox", target_os = "wasi")))] 69b8a62b91Sopenharmony_ci#[cfg(feature = "net")] 70b8a62b91Sopenharmony_cipub(crate) mod net; 71b8a62b91Sopenharmony_ci#[cfg(not(windows))] 72b8a62b91Sopenharmony_ci#[cfg(any( 73b8a62b91Sopenharmony_ci feature = "param", 74b8a62b91Sopenharmony_ci feature = "runtime", 75b8a62b91Sopenharmony_ci feature = "time", 76b8a62b91Sopenharmony_ci target_arch = "x86", 77b8a62b91Sopenharmony_ci))] 78b8a62b91Sopenharmony_cipub(crate) mod param; 79b8a62b91Sopenharmony_ci#[cfg(not(windows))] 80b8a62b91Sopenharmony_cipub(crate) mod process; 81b8a62b91Sopenharmony_ci#[cfg(not(windows))] 82b8a62b91Sopenharmony_ci#[cfg(feature = "rand")] 83b8a62b91Sopenharmony_cipub(crate) mod rand; 84b8a62b91Sopenharmony_ci#[cfg(not(windows))] 85b8a62b91Sopenharmony_ci#[cfg(feature = "termios")] 86b8a62b91Sopenharmony_cipub(crate) mod termios; 87b8a62b91Sopenharmony_ci#[cfg(not(windows))] 88b8a62b91Sopenharmony_ci#[cfg(feature = "thread")] 89b8a62b91Sopenharmony_cipub(crate) mod thread; 90b8a62b91Sopenharmony_ci#[cfg(not(windows))] 91b8a62b91Sopenharmony_cipub(crate) mod time; 92b8a62b91Sopenharmony_ci 93b8a62b91Sopenharmony_ci/// If the host libc is glibc, return `true` if it is less than version 2.25. 94b8a62b91Sopenharmony_ci/// 95b8a62b91Sopenharmony_ci/// To restate and clarify, this function returning true does not mean the libc 96b8a62b91Sopenharmony_ci/// is glibc just that if it is glibc, it is less than version 2.25. 97b8a62b91Sopenharmony_ci/// 98b8a62b91Sopenharmony_ci/// For now, this function is only available on Linux, but if it ends up being 99b8a62b91Sopenharmony_ci/// used beyond that, this could be changed to e.g. `#[cfg(unix)]`. 100b8a62b91Sopenharmony_ci#[cfg(all(unix, target_env = "gnu"))] 101b8a62b91Sopenharmony_cipub(crate) fn if_glibc_is_less_than_2_25() -> bool { 102b8a62b91Sopenharmony_ci // This is also defined inside `weak_or_syscall!` in 103b8a62b91Sopenharmony_ci // backend/libc/rand/syscalls.rs, but it's not convenient to re-export the weak 104b8a62b91Sopenharmony_ci // symbol from that macro, so we duplicate it at a small cost here. 105b8a62b91Sopenharmony_ci weak! { fn getrandom(*mut c::c_void, c::size_t, c::c_uint) -> c::ssize_t } 106b8a62b91Sopenharmony_ci 107b8a62b91Sopenharmony_ci // glibc 2.25 has `getrandom`, which is how we satisfy the API contract of 108b8a62b91Sopenharmony_ci // this function. But, there are likely other libc versions which have it. 109b8a62b91Sopenharmony_ci getrandom.get().is_none() 110b8a62b91Sopenharmony_ci} 111