1use super::utils::cstr;
2
3use crate::fs::UringOpenOptions;
4use crate::runtime::driver::op::{CancelData, Cancellable, Completable, CqeResult, Op};
5
6use io_uring::{opcode, types};
7use std::ffi::CString;
8use std::io::{self, Error};
9use std::os::fd::FromRawFd;
10use std::path::Path;
11
12#[derive(Debug)]
13pub(crate) struct Open {
14 #[allow(dead_code)]
17 path: CString,
18}
19
20impl Completable for Open {
21 type Output = io::Result<crate::fs::File>;
22 fn complete(self, cqe: CqeResult) -> Self::Output {
23 cqe.result
24 .map(|fd| unsafe { crate::fs::File::from_raw_fd(fd as i32) })
25 }
26
27 fn complete_with_error(self, err: Error) -> Self::Output {
28 Err(err)
29 }
30}
31
32impl Cancellable for Open {
33 fn cancel(self) -> CancelData {
34 CancelData::Open(self)
35 }
36}
37
38impl Op<Open> {
39 pub(crate) fn open(path: &Path, options: &UringOpenOptions) -> io::Result<Op<Open>> {
41 let inner_opt = options;
42 let path = cstr(path)?;
43
44 let custom_flags = inner_opt.custom_flags;
45 let flags = libc::O_CLOEXEC
46 | options.access_mode()?
47 | options.creation_mode()?
48 | (custom_flags & !libc::O_ACCMODE);
49
50 let open_op = opcode::OpenAt::new(types::Fd(libc::AT_FDCWD), path.as_ptr())
51 .flags(flags)
52 .mode(inner_opt.mode)
53 .build();
54
55 let op = unsafe { Op::new(open_op, Open { path }) };
57 Ok(op)
58 }
59}