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