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 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 Ok(unsafe { crate::io::raw::Buffer::try_native::<S, E>(output, raw)?.assume_init_mut() })
29}
30
31pub 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
55pub unsafe trait Completion {
59 type Outcome;
60 type Invalid;
61
62 unsafe fn open(outcome: Self::Outcome) -> Result<Opened, Self::Invalid>;
66}