monoio/fs/file/
unix.rs

1use std::{
2    fs::File as StdFile,
3    io,
4    os::fd::{AsRawFd, IntoRawFd, RawFd},
5};
6
7#[cfg(all(not(feature = "iouring"), feature = "sync"))]
8pub(crate) use asyncified::*;
9#[cfg(any(feature = "iouring", not(feature = "sync")))]
10pub(crate) use iouring::*;
11
12use super::File;
13use crate::{
14    buf::{IoBuf, IoBufMut, IoVecBuf, IoVecBufMut},
15    driver::{op::Op, shared_fd::SharedFd},
16    fs::{metadata::FileAttr, Metadata},
17};
18
19impl File {
20    /// Converts a [`std::fs::File`] to a [`monoio::fs::File`](File).
21    ///
22    /// # Examples
23    ///
24    /// ```no_run
25    /// // This line could block. It is not recommended to do this on the monoio
26    /// // runtime.
27    /// let std_file = std::fs::File::open("foo.txt").unwrap();
28    /// let file = monoio::fs::File::from_std(std_file);
29    /// ```
30    pub fn from_std(std: StdFile) -> std::io::Result<File> {
31        Ok(File {
32            fd: SharedFd::new_without_register(std.into_raw_fd()),
33        })
34    }
35
36    /// Queries metadata about the underlying file.
37    ///
38    /// # Examples
39    ///
40    /// ```no_run
41    /// use monoio::fs::File;
42    ///
43    /// #[monoio::main]
44    /// async fn main() -> std::io::Result<()> {
45    ///     let mut f = File::open("foo.txt").await?;
46    ///     let metadata = f.metadata().await?;
47    ///     Ok(())
48    /// }
49    /// ```
50    pub async fn metadata(&self) -> io::Result<Metadata> {
51        metadata(self.fd.clone()).await
52    }
53}
54
55impl AsRawFd for File {
56    fn as_raw_fd(&self) -> RawFd {
57        self.fd.raw_fd()
58    }
59}
60
61pub(crate) async fn metadata(fd: SharedFd) -> std::io::Result<Metadata> {
62    #[cfg(target_os = "linux")]
63    let flags = libc::AT_STATX_SYNC_AS_STAT | libc::AT_EMPTY_PATH;
64    #[cfg(target_os = "linux")]
65    let op = Op::statx_using_fd(fd, flags)?;
66    #[cfg(any(target_os = "macos", target_os = "freebsd"))]
67    let op = Op::statx_using_fd(fd, true)?;
68
69    op.result().await.map(FileAttr::from).map(Metadata)
70}
71
72#[cfg(any(feature = "iouring", not(feature = "sync")))]
73mod iouring {
74    use super::*;
75    use crate::uring_op;
76
77    uring_op!(read<IoBufMut>(read, buf));
78    uring_op!(read_at<IoBufMut>(read_at, buf, pos: u64));
79    uring_op!(read_vectored<IoVecBufMut>(readv, buf_vec));
80
81    uring_op!(write<IoBuf>(write, buf));
82    uring_op!(write_at<IoBuf>(write_at, buf, pos: u64));
83    uring_op!(write_vectored<IoVecBuf>(writev, buf_vec));
84}
85
86#[cfg(all(not(feature = "iouring"), feature = "sync"))]
87mod asyncified {
88    use super::*;
89    use crate::{
90        asyncify_op,
91        driver::op::{read, write},
92    };
93
94    asyncify_op!(R, read<IoBufMut>(read::read, IoBufMut::write_ptr, IoBufMut::bytes_total));
95    asyncify_op!(R, read_at<IoBufMut>(read::read_at, IoBufMut::write_ptr, IoBufMut::bytes_total, pos: u64));
96    asyncify_op!(R, read_vectored<IoVecBufMut>(read::read_vectored, IoVecBufMut::write_iovec_ptr, IoVecBufMut::write_iovec_len));
97
98    asyncify_op!(W, write<IoBuf>(write::write, IoBuf::read_ptr, IoBuf::bytes_init));
99    asyncify_op!(W, write_at<IoBuf>(write::write_at, IoBuf::read_ptr, IoBuf::bytes_init, pos: u64));
100    asyncify_op!(W, write_vectored<IoVecBuf>(write::write_vectored, IoVecBuf::read_iovec_ptr, IoVecBuf::read_iovec_len));
101}