Skip to main content

dope_sys/io/file/
raw.rs

1use std::{mem::MaybeUninit, os::fd};
2
3use crate::{
4    Errno,
5    io::file::{self, Opened},
6    kernel,
7};
8
9pub(super) fn read_at<'a, S: kernel::raw::Source + ?Sized, E: From<Errno>>(
10    file: fd::BorrowedFd<'_>,
11    output: &'a mut [MaybeUninit<u8>],
12    offset: file::Offset,
13) -> Result<&'a mut [u8], E> {
14    use fd::AsRawFd as _;
15
16    const { assert!(libc::off_t::MAX as u64 == i64::MAX as u64) };
17    // SAFETY: the descriptor stays borrowed, output owns its writable extent,
18    // and the admitted nonnegative offset fits the ABI.
19    let raw = unsafe {
20        libc::pread(
21            file.as_raw_fd(),
22            output.as_mut_ptr().cast(),
23            output.len(),
24            offset.get() as libc::off_t,
25        )
26    };
27    // SAFETY: pread returns -1 or initializes at most this exact extent.
28    Ok(unsafe { crate::io::raw::Buffer::try_native::<S, E>(output, raw)?.assume_init_mut() })
29}
30
31/// # Safety
32/// The live descriptor remains unchanged until stream drop.
33/// Returned names retain exclusive storage until their borrows end.
34pub unsafe trait Directory: kernel::raw::Source {
35    type Stream;
36
37    fn open_dir<E: From<Errno>>(path: &std::ffi::CStr) -> Result<Self::Stream, file::OpenError<E>>
38    where
39        Self: file::File,
40    {
41        let file = Self::open(
42            path,
43            file::Open::DIRECTORY | file::Open::CLOSE_ON_EXEC,
44            file::Mode::new(0),
45        )
46        .map_err(file::OpenError::Syscall)?;
47        Self::from_fd(file)
48    }
49
50    fn from_fd<E: From<Errno>>(file: fd::OwnedFd) -> Result<Self::Stream, file::OpenError<E>>;
51    fn descriptor(stream: &Self::Stream) -> kernel::raw::Descriptor;
52    fn next(stream: &mut Self::Stream) -> Result<Option<file::Entry<'_>>, Errno>;
53}
54
55/// # Safety
56/// Each decoded success retains the uniquely transferred descriptor until
57/// delivery or reclamation.
58pub unsafe trait Completion {
59    type Outcome;
60    type Invalid;
61
62    /// # Safety
63    /// A successful outcome transfers one live descriptor from a completed
64    /// open operation. Its descriptor has not been decoded or reclaimed before.
65    unsafe fn open(outcome: Self::Outcome) -> Result<Opened, Self::Invalid>;
66}