aboutsummaryrefslogtreecommitdiff
path: root/src/util_libc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/util_libc.rs')
-rw-r--r--src/util_libc.rs49
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);
}