Skip to content

Commit

Permalink
Move open_readonly function to use_file (#523)
Browse files Browse the repository at this point in the history
  • Loading branch information
newpavlov authored Oct 16, 2024
1 parent bce46e2 commit bafc6e0
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 36 deletions.
31 changes: 28 additions & 3 deletions src/use_file.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Implementations that just need to read from a file
use crate::{
util_libc::{open_readonly, sys_fill_exact},
util_libc::{last_os_error, sys_fill_exact},
Error,
};
use core::{
Expand Down Expand Up @@ -47,6 +47,32 @@ pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
})
}

/// Open a file in read-only mode.
///
/// # Panics
/// If `path` does not contain any zeros.
// TODO: Move `path` to `CStr` and use `CStr::from_bytes_until_nul` (MSRV 1.69)
// or C-string literals (MSRV 1.77) for statics
fn open_readonly(path: &[u8]) -> Result<libc::c_int, Error> {
assert!(path.iter().any(|&b| b == 0));
loop {
let fd = unsafe {
libc::open(
path.as_ptr().cast::<libc::c_char>(),
libc::O_RDONLY | libc::O_CLOEXEC,
)
};
if fd >= 0 {
return Ok(fd);
}
let err = last_os_error();
// We should try again if open() was interrupted.
if err.raw_os_error() != Some(libc::EINTR) {
return Err(err);
}
}
}

#[cold]
fn open_or_wait() -> Result<libc::c_int, Error> {
loop {
Expand Down Expand Up @@ -116,8 +142,7 @@ mod sync {

#[cfg(any(target_os = "android", target_os = "linux"))]
mod sync {
use super::{Error, FD, FD_ONGOING_INIT};
use crate::util_libc::{last_os_error, open_readonly};
use super::{last_os_error, open_readonly, Error, FD, FD_ONGOING_INIT};

/// Wait for atomic `FD` to change value from `FD_ONGOING_INIT` to something else.
///
Expand Down
41 changes: 8 additions & 33 deletions src/util_libc.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![allow(dead_code)]
use crate::Error;
use core::mem::MaybeUninit;

Expand Down Expand Up @@ -34,7 +33,7 @@ cfg_if! {
}
}

pub fn last_os_error() -> Error {
pub(crate) fn last_os_error() -> Error {
let errno: libc::c_int = unsafe { get_errno() };

// c_int-to-u32 conversion is lossless for nonnegative values if they are the same size.
Expand All @@ -46,10 +45,13 @@ pub fn last_os_error() -> Error {
}
}

// Fill a buffer by repeatedly invoking a system call. The `sys_fill` function:
// - should return -1 and set errno on failure
// - should return the number of bytes written on success
pub fn sys_fill_exact(
/// Fill a buffer by repeatedly invoking `sys_fill`.
///
/// The `sys_fill` function:
/// - should return -1 and set errno on failure
/// - should return the number of bytes written on success
#[allow(dead_code)]
pub(crate) fn sys_fill_exact(
mut buf: &mut [MaybeUninit<u8>],
sys_fill: impl Fn(&mut [MaybeUninit<u8>]) -> libc::ssize_t,
) -> Result<(), Error> {
Expand All @@ -75,30 +77,3 @@ pub fn sys_fill_exact(
}
Ok(())
}

/// Open a file in read-only mode.
///
/// # Panics
/// If `path` does not contain any zeros.
// TODO: Move `path` to `CStr` and use `CStr::from_bytes_until_nul` (MSRV 1.69)
// or C-string literals (MSRV 1.77) for statics
#[inline(always)]
pub fn open_readonly(path: &[u8]) -> Result<libc::c_int, Error> {
assert!(path.iter().any(|&b| b == 0));
loop {
let fd = unsafe {
libc::open(
path.as_ptr().cast::<libc::c_char>(),
libc::O_RDONLY | libc::O_CLOEXEC,
)
};
if fd >= 0 {
return Ok(fd);
}
let err = last_os_error();
// We should try again if open() was interrupted.
if err.raw_os_error() != Some(libc::EINTR) {
return Err(err);
}
}
}

0 comments on commit bafc6e0

Please sign in to comment.