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 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 pub unsafe fn splice_to_pipe(
67 &self,
68 off_in: i64,
69 pipe_write_fd: RawFd,
70 len: u32,
71 op: Token,
72 ) -> Sqe {
73 Sqe::splice_to_pipe(self.inner.as_raw_fd(), off_in, pipe_write_fd, len, op)
74 }
75}
76
77pub struct OpenPath {
78 path: CString,
79}
80
81impl OpenPath {
82 pub fn new(path: &str) -> io::Result<Self> {
83 let path = CString::new(path)
84 .map_err(|_| Error::new(ErrorKind::InvalidInput, "dope: path has interior nul"))?;
85 Ok(Self { path })
86 }
87
88 pub fn as_ptr(&self) -> *const libc::c_char {
89 self.path.as_ptr()
90 }
91
92 pub unsafe fn open_at(&self, flags: i32, op: Token) -> Sqe {
95 Sqe::openat(libc::AT_FDCWD, self.path.as_ptr(), flags, 0, op)
96 }
97}
98
99pub const O_RDONLY: i32 = libc::O_RDONLY;
100pub const O_CLOEXEC: i32 = libc::O_CLOEXEC;