Skip to content

Commit

Permalink
MSRV 1.63: use_file: Clarify I/O safety using BorrowedFd.
Browse files Browse the repository at this point in the history
  • Loading branch information
briansmith committed Jun 17, 2024
1 parent 7d73362 commit c1a4691
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .clippy.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
msrv = "1.60"
msrv = "1.63"
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-22.04, windows-2022]
toolchain: [nightly, beta, stable, "1.60"]
toolchain: [nightly, beta, stable, "1.63"]
# Only Test macOS on stable to reduce macOS CI jobs
include:
# x86_64-apple-darwin.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "getrandom"
version = "0.2.15" # Also update html_root_url in lib.rs when bumping this
edition = "2021"
rust-version = "1.60" # Sync .clippy.toml, tests.yml, and README.md.
rust-version = "1.63" # Sync .clippy.toml, tests.yml, and README.md.
authors = ["The Rand Project Developers"]
license = "MIT OR Apache-2.0"
description = "A small cross-platform library for retrieving random data from system source"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ crate features, WASM support and Custom RNGs see the

## Minimum Supported Rust Version

This crate requires Rust 1.60.0 or later.
This crate requires Rust 1.63.0 or later.

## Platform Support

Expand Down
20 changes: 10 additions & 10 deletions src/use_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ use core::{
sync::atomic::{AtomicI32, Ordering::Relaxed},
};
use std::{
fs, io,
os::fd::{IntoRawFd as _, RawFd},
fs,
io,
// TODO(MSRV 1.66): use `std::os::fd` instead of `std::unix::io`.
os::unix::io::{AsRawFd as _, BorrowedFd, IntoRawFd as _, RawFd},
};

/// For all platforms, we use `/dev/urandom` rather than `/dev/random`.
Expand All @@ -28,14 +30,14 @@ const FILE_PATH: &str = "/dev/urandom";
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let fd = get_rng_fd()?;
sys_fill_exact(dest, |buf| unsafe {
libc::read(fd, buf.as_mut_ptr().cast::<c_void>(), buf.len())
libc::read(fd.as_raw_fd(), buf.as_mut_ptr().cast::<c_void>(), buf.len())
})
}

// Returns the file descriptor for the device file used to retrieve random
// bytes. The file will be opened exactly once. All subsequent calls will
// return the same file descriptor. This file descriptor is never closed.
fn get_rng_fd() -> Result<RawFd, Error> {
fn get_rng_fd() -> Result<BorrowedFd<'static>, Error> {
// std::os::fd::{BorrowedFd, OwnedFd} guarantee that -1 is not a valid file descriptor.
const FD_UNINIT: RawFd = -1;

Expand All @@ -47,15 +49,15 @@ fn get_rng_fd() -> Result<RawFd, Error> {
// `FD.store(fd)` would fail to compile.
static FD: AtomicI32 = AtomicI32::new(FD_UNINIT);

fn get_fd() -> Option<RawFd> {
fn get_fd() -> Option<BorrowedFd<'static>> {
match FD.load(Relaxed) {
FD_UNINIT => None,
val => Some(val),
val => Some(unsafe { BorrowedFd::borrow_raw(val) }),
}
}

#[cold]
fn get_fd_locked() -> Result<RawFd, Error> {
fn get_fd_locked() -> Result<BorrowedFd<'static>, Error> {
// SAFETY: We use the mutex only in this method, and we always unlock it
// before returning, making sure we don't violate the pthread_mutex_t API.
static MUTEX: Mutex = Mutex::new();
Expand All @@ -76,7 +78,7 @@ fn get_rng_fd() -> Result<RawFd, Error> {
debug_assert!(fd != FD_UNINIT);
FD.store(fd, Relaxed);

Ok(fd)
Ok(unsafe { BorrowedFd::borrow_raw(fd) })
}

// Use double-checked locking to avoid acquiring the lock if possible.
Expand Down Expand Up @@ -117,8 +119,6 @@ fn get_rng_fd() -> Result<RawFd, Error> {
// libsodium uses `libc::poll` similarly to this.
#[cfg(any(target_os = "android", target_os = "linux"))]
fn wait_until_rng_ready() -> Result<(), Error> {
use std::os::unix::io::AsRawFd as _;

let file = fs::File::open("/dev/random").map_err(map_io_error)?;
let mut pfd = libc::pollfd {
fd: file.as_raw_fd(),
Expand Down

0 comments on commit c1a4691

Please sign in to comment.