1use crate::Error;
2use core::mem::MaybeUninit;
3
4cfg_if! {
5 if #[cfg(any(target_os = "netbsd", target_os = "openbsd", target_os = "android"))] {
6 use libc::__errno as errno_location;
7 } else if #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "hurd", target_os = "redox", target_os = "dragonfly"))] {
8 use libc::__errno_location as errno_location;
9 } else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] {
10 use libc::___errno as errno_location;
11 } else if #[cfg(any(target_os = "macos", target_os = "freebsd"))] {
12 use libc::__error as errno_location;
13 } else if #[cfg(target_os = "haiku")] {
14 use libc::_errnop as errno_location;
15 } else if #[cfg(target_os = "nto")] {
16 use libc::__get_errno_ptr as errno_location;
17 } else if #[cfg(any(all(target_os = "horizon", target_arch = "arm"), target_os = "vita"))] {
18 extern "C" {
19 fn __errno() -> *mut libc::c_int;
21 }
22 use __errno as errno_location;
23 } else if #[cfg(target_os = "aix")] {
24 use libc::_Errno as errno_location;
25 }
26}
27
28cfg_if! {
29 if #[cfg(target_os = "vxworks")] {
30 use libc::errnoGet as get_errno;
31 } else {
32 unsafe fn get_errno() -> libc::c_int { *errno_location() }
33 }
34}
35
36pub(crate) fn last_os_error() -> Error {
37 let errno: libc::c_int = unsafe { get_errno() };
38
39 const _: () = assert!(core::mem::size_of::<libc::c_int>() == core::mem::size_of::<u32>());
41
42 match u32::try_from(errno) {
43 Ok(code) if code != 0 => Error::from_os_error(code),
44 _ => Error::ERRNO_NOT_POSITIVE,
45 }
46}
47
48#[allow(dead_code)]
54pub(crate) fn sys_fill_exact(
55 mut buf: &mut [MaybeUninit<u8>],
56 sys_fill: impl Fn(&mut [MaybeUninit<u8>]) -> libc::ssize_t,
57) -> Result<(), Error> {
58 while !buf.is_empty() {
59 let res = sys_fill(buf);
60 match res {
61 res if res > 0 => {
62 let len = usize::try_from(res).map_err(|_| Error::UNEXPECTED)?;
63 buf = buf.get_mut(len..).ok_or(Error::UNEXPECTED)?;
64 }
65 -1 => {
66 let err = last_os_error();
67 if err.raw_os_error() != Some(libc::EINTR) {
69 return Err(err);
70 }
71 }
72 _ => return Err(Error::UNEXPECTED),
76 }
77 }
78 Ok(())
79}