diff options
Diffstat (limited to 'src/util_libc.rs')
-rw-r--r-- | src/util_libc.rs | 49 |
1 files changed, 21 insertions, 28 deletions
diff --git a/src/util_libc.rs b/src/util_libc.rs index d057071..0b792c3 100644 --- a/src/util_libc.rs +++ b/src/util_libc.rs @@ -1,13 +1,7 @@ -// Copyright 2019 Developers of the Rand project. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. #![allow(dead_code)] use crate::Error; use core::{ + mem::MaybeUninit, num::NonZeroU32, ptr::NonNull, sync::atomic::{fence, AtomicPtr, Ordering}, @@ -17,7 +11,7 @@ use libc::c_void; cfg_if! { if #[cfg(any(target_os = "netbsd", target_os = "openbsd", target_os = "android"))] { use libc::__errno as errno_location; - } else if #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "redox"))] { + } else if #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "hurd", target_os = "redox"))] { use libc::__errno_location as errno_location; } else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] { use libc::___errno as errno_location; @@ -25,12 +19,16 @@ cfg_if! { use libc::__error as errno_location; } else if #[cfg(target_os = "haiku")] { use libc::_errnop as errno_location; - } else if #[cfg(all(target_os = "horizon", target_arch = "arm"))] { + } else if #[cfg(target_os = "nto")] { + use libc::__get_errno_ptr as errno_location; + } else if #[cfg(any(all(target_os = "horizon", target_arch = "arm"), target_os = "vita"))] { extern "C" { // Not provided by libc: https://github.com/rust-lang/libc/issues/1995 fn __errno() -> *mut libc::c_int; } use __errno as errno_location; + } else if #[cfg(target_os = "aix")] { + use libc::_Errno as errno_location; } } @@ -59,21 +57,24 @@ pub fn last_os_error() -> Error { // - should return -1 and set errno on failure // - should return the number of bytes written on success pub fn sys_fill_exact( - mut buf: &mut [u8], - sys_fill: impl Fn(&mut [u8]) -> libc::ssize_t, + mut buf: &mut [MaybeUninit<u8>], + sys_fill: impl Fn(&mut [MaybeUninit<u8>]) -> libc::ssize_t, ) -> Result<(), Error> { while !buf.is_empty() { let res = sys_fill(buf); - if res < 0 { - let err = last_os_error(); - // We should try again if the call was interrupted. - if err.raw_os_error() != Some(libc::EINTR) { - return Err(err); + match res { + res if res > 0 => buf = buf.get_mut(res as usize..).ok_or(Error::UNEXPECTED)?, + -1 => { + let err = last_os_error(); + // We should try again if the call was interrupted. + if err.raw_os_error() != Some(libc::EINTR) { + return Err(err); + } } - } else { - // We don't check for EOF (ret = 0) as the data we are reading + // Negative return codes not equal to -1 should be impossible. + // EOF (ret = 0) should be impossible, as the data we are reading // should be an infinite stream of random bytes. - buf = &mut buf[(res as usize)..]; + _ => return Err(Error::UNEXPECTED), } } Ok(()) @@ -135,19 +136,11 @@ impl Weak { } } -cfg_if! { - if #[cfg(any(target_os = "linux", target_os = "emscripten"))] { - use libc::open64 as open; - } else { - use libc::open; - } -} - // SAFETY: path must be null terminated, FD must be manually closed. pub unsafe fn open_readonly(path: &str) -> Result<libc::c_int, Error> { debug_assert_eq!(path.as_bytes().last(), Some(&0)); loop { - let fd = open(path.as_ptr() as *const _, libc::O_RDONLY | libc::O_CLOEXEC); + let fd = libc::open(path.as_ptr() as *const _, libc::O_RDONLY | libc::O_CLOEXEC); if fd >= 0 { return Ok(fd); } |