Skip to main content

dope_core/io/
file.rs

1use o3::marker::ThreadBound;
2use std::ffi::CString;
3use std::fs::File;
4use std::io::{self, Error, ErrorKind};
5use std::os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd};
6
7use crate::backend::Sqe;
8use crate::driver::token::Token;
9
10pub struct RawMetadata {
11    pub len: u64,
12    pub modified: Option<(i64, u32)>,
13    pub regular: bool,
14}
15
16pub struct OsFile {
17    inner: File,
18    _thread: ThreadBound,
19}
20
21impl OsFile {
22    pub fn create(path: &str) -> io::Result<Self> {
23        let inner = File::options()
24            .write(true)
25            .create(true)
26            .truncate(true)
27            .open(path)?;
28        Ok(Self {
29            inner,
30            _thread: ThreadBound::NEW,
31        })
32    }
33
34    pub fn open(path: &str) -> io::Result<Self> {
35        let inner = File::options().read(true).open(path)?;
36        Ok(Self {
37            inner,
38            _thread: ThreadBound::NEW,
39        })
40    }
41
42    pub fn try_len(&self) -> io::Result<u64> {
43        Ok(self.inner.metadata()?.len())
44    }
45
46    pub fn try_is_empty(&self) -> io::Result<bool> {
47        Ok(self.try_len()? == 0)
48    }
49
50    pub fn fd(&self) -> RawFd {
51        self.inner.as_raw_fd()
52    }
53
54    pub fn as_fd(&self) -> BorrowedFd<'_> {
55        self.inner.as_fd()
56    }
57
58    /// # Safety
59    /// `self` must stay open and `buf` stable and unaliased until completion.
60    pub unsafe fn read_at(&self, buf: &mut [u8], offset: u64, op: Token) -> Sqe {
61        unsafe { Sqe::read(self.inner.as_raw_fd(), buf, offset, op) }
62    }
63}
64
65pub struct OpenPath {
66    path: CString,
67}
68
69impl OpenPath {
70    pub fn new(path: &str) -> io::Result<Self> {
71        let path = CString::new(path)
72            .map_err(|_| Error::new(ErrorKind::InvalidInput, "dope: path has interior nul"))?;
73        Ok(Self { path })
74    }
75
76    pub fn as_ptr(&self) -> *const libc::c_char {
77        self.path.as_ptr()
78    }
79
80    /// # Safety
81    /// `self` must remain valid until completion.
82    pub unsafe fn open_at(&self, flags: i32, op: Token) -> Sqe {
83        Sqe::openat(libc::AT_FDCWD, self.path.as_ptr(), flags, 0, op)
84    }
85}
86
87pub const O_RDONLY: i32 = libc::O_RDONLY;
88pub const O_CLOEXEC: i32 = libc::O_CLOEXEC;