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 {
29 crate::io::raw::Buffer::try_native(output, raw, || kernel::raw::Code::last::<S>().into())?
30 .assume_init_mut()
31 })
32}
33
34pub unsafe trait Directory: kernel::raw::Source {
38 type Stream;
39
40 fn open_dir<E: From<Errno>>(path: &std::ffi::CStr) -> Result<Self::Stream, file::OpenError<E>>
41 where
42 Self: file::File,
43 {
44 let file = Self::open(
45 path,
46 file::Open::DIRECTORY | file::Open::CLOSE_ON_EXEC,
47 file::Mode::new(0),
48 )
49 .map_err(file::OpenError::Syscall)?;
50 Self::from_fd(file)
51 }
52
53 fn from_fd<E: From<Errno>>(file: fd::OwnedFd) -> Result<Self::Stream, file::OpenError<E>>;
54 fn descriptor(stream: &Self::Stream) -> kernel::raw::Descriptor;
55 fn next<E: From<Errno>>(
56 stream: &mut Self::Stream,
57 ) -> Result<Option<file::Entry<'_>>, file::ReadError<E>>;
58}
59
60pub unsafe trait Completion {
64 type Outcome;
65 type Invalid;
66
67 unsafe fn open(outcome: Self::Outcome) -> Result<Opened, Self::Invalid>;
71
72 fn close(file: fd::OwnedFd) -> Result<(), Errno>;
73}