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