-
Notifications
You must be signed in to change notification settings - Fork 226
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(op, fs): ✨ Intergated
statx
into monoio (#268)
* feat(op, fs): ✨ Intergated `statx` into monoio * feat(op, fs): ✨ Intergated `statx` into monoio * fix(op, fs): 🐛 fix some platform-specific bug * fix(op, fs): 🐛 fix some platform-specific bug * docs(fs): update permissions doc * fix(op, fs): 🐛 fix some platform-specific bug * fix(fs): 🐛 remove `unwrap` call that will cause panic * feat: ✨ make `Statx`(actually is stat) support macos * feat: ✨ make `Statx`(actually is stat) support macos * fix(tests): 🐛 disable tests on windows * ci: 📌 upgrade the cross version with latest git branch upgrade the cross version with latest git branch, to fix some linker error when CI * refactor: refact the impl structure for different os * cross * refactor: refact the impl structure for different os
- Loading branch information
Showing
10 changed files
with
1,106 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
use std::{ffi::CString, mem::MaybeUninit, path::Path}; | ||
|
||
#[cfg(all(target_os = "linux", feature = "iouring"))] | ||
use io_uring::{opcode, types}; | ||
#[cfg(target_os = "linux")] | ||
use libc::statx; | ||
|
||
use super::{Op, OpAble}; | ||
#[cfg(any(feature = "legacy", feature = "poll-io"))] | ||
use crate::driver::ready::Direction; | ||
use crate::driver::{shared_fd::SharedFd, util::cstr}; | ||
|
||
#[derive(Debug)] | ||
pub(crate) struct Statx<T> { | ||
inner: T, | ||
#[cfg(target_os = "linux")] | ||
flags: i32, | ||
#[cfg(target_os = "linux")] | ||
statx_buf: Box<MaybeUninit<statx>>, | ||
#[cfg(target_os = "macos")] | ||
stat_buf: Box<MaybeUninit<libc::stat>>, | ||
#[cfg(target_os = "macos")] | ||
follow_symlinks: bool, | ||
} | ||
|
||
type FdStatx = Statx<SharedFd>; | ||
|
||
impl Op<FdStatx> { | ||
/// submit a statx operation | ||
#[cfg(target_os = "linux")] | ||
pub(crate) fn statx_using_fd(fd: &SharedFd, flags: i32) -> std::io::Result<Self> { | ||
Op::submit_with(Statx { | ||
inner: fd.clone(), | ||
flags, | ||
statx_buf: Box::new(MaybeUninit::uninit()), | ||
}) | ||
} | ||
|
||
#[cfg(target_os = "linux")] | ||
pub(crate) async fn statx_result(self) -> std::io::Result<statx> { | ||
let complete = self.await; | ||
complete.meta.result?; | ||
|
||
Ok(unsafe { MaybeUninit::assume_init(*complete.data.statx_buf) }) | ||
} | ||
|
||
#[cfg(target_os = "macos")] | ||
pub(crate) fn statx_using_fd(fd: &SharedFd, follow_symlinks: bool) -> std::io::Result<Self> { | ||
Op::submit_with(Statx { | ||
inner: fd.clone(), | ||
follow_symlinks, | ||
stat_buf: Box::new(MaybeUninit::uninit()), | ||
}) | ||
} | ||
|
||
#[cfg(target_os = "macos")] | ||
pub(crate) async fn statx_result(self) -> std::io::Result<libc::stat> { | ||
let complete = self.await; | ||
complete.meta.result?; | ||
|
||
Ok(unsafe { MaybeUninit::assume_init(*complete.data.stat_buf) }) | ||
} | ||
} | ||
|
||
impl OpAble for FdStatx { | ||
#[cfg(all(target_os = "linux", feature = "iouring"))] | ||
fn uring_op(&mut self) -> io_uring::squeue::Entry { | ||
use std::os::fd::AsRawFd; | ||
|
||
let statxbuf = self.statx_buf.as_mut_ptr() as *mut _; | ||
|
||
opcode::Statx::new(types::Fd(self.inner.as_raw_fd()), c"".as_ptr(), statxbuf) | ||
.flags(libc::AT_EMPTY_PATH | libc::AT_STATX_SYNC_AS_STAT) | ||
.mask(libc::STATX_ALL) | ||
.build() | ||
} | ||
|
||
#[cfg(any(feature = "legacy", feature = "poll-io"))] | ||
fn legacy_interest(&self) -> Option<(crate::driver::ready::Direction, usize)> { | ||
self.inner | ||
.registered_index() | ||
.map(|idx| (Direction::Read, idx)) | ||
} | ||
|
||
#[cfg(all(any(feature = "legacy", feature = "poll-io"), target_os = "linux"))] | ||
fn legacy_call(&mut self) -> std::io::Result<u32> { | ||
use std::os::fd::AsRawFd; | ||
|
||
use crate::syscall_u32; | ||
|
||
syscall_u32!(statx( | ||
self.inner.as_raw_fd(), | ||
c"".as_ptr(), | ||
libc::AT_EMPTY_PATH, | ||
libc::STATX_ALL, | ||
self.statx_buf.as_mut_ptr() as *mut _ | ||
)) | ||
} | ||
|
||
#[cfg(all(any(feature = "legacy", feature = "poll-io"), windows))] | ||
fn legacy_call(&mut self) -> std::io::Result<u32> { | ||
unimplemented!() | ||
} | ||
|
||
#[cfg(all(any(feature = "legacy", feature = "poll-io"), target_os = "macos"))] | ||
fn legacy_call(&mut self) -> std::io::Result<u32> { | ||
use std::os::fd::AsRawFd; | ||
|
||
use crate::syscall_u32; | ||
|
||
syscall_u32!(fstat( | ||
self.inner.as_raw_fd(), | ||
self.stat_buf.as_mut_ptr() as *mut _ | ||
)) | ||
} | ||
} | ||
|
||
type PathStatx = Statx<CString>; | ||
|
||
impl Op<PathStatx> { | ||
/// submit a statx operation | ||
#[cfg(target_os = "linux")] | ||
pub(crate) fn statx_using_path<P: AsRef<Path>>(path: P, flags: i32) -> std::io::Result<Self> { | ||
let path = cstr(path.as_ref())?; | ||
Op::submit_with(Statx { | ||
inner: path, | ||
flags, | ||
statx_buf: Box::new(MaybeUninit::uninit()), | ||
}) | ||
} | ||
|
||
#[cfg(target_os = "linux")] | ||
pub(crate) async fn statx_result(self) -> std::io::Result<statx> { | ||
let complete = self.await; | ||
complete.meta.result?; | ||
|
||
Ok(unsafe { MaybeUninit::assume_init(*complete.data.statx_buf) }) | ||
} | ||
|
||
#[cfg(target_os = "macos")] | ||
pub(crate) fn statx_using_path<P: AsRef<Path>>( | ||
path: P, | ||
follow_symlinks: bool, | ||
) -> std::io::Result<Self> { | ||
let path = cstr(path.as_ref())?; | ||
Op::submit_with(Statx { | ||
inner: path, | ||
follow_symlinks, | ||
stat_buf: Box::new(MaybeUninit::uninit()), | ||
}) | ||
} | ||
|
||
#[cfg(target_os = "macos")] | ||
pub(crate) async fn statx_result(self) -> std::io::Result<libc::stat> { | ||
let complete = self.await; | ||
complete.meta.result?; | ||
|
||
Ok(unsafe { MaybeUninit::assume_init(*complete.data.stat_buf) }) | ||
} | ||
} | ||
|
||
impl OpAble for PathStatx { | ||
#[cfg(all(target_os = "linux", feature = "iouring"))] | ||
fn uring_op(&mut self) -> io_uring::squeue::Entry { | ||
let statxbuf = self.statx_buf.as_mut_ptr() as *mut _; | ||
|
||
opcode::Statx::new(types::Fd(libc::AT_FDCWD), self.inner.as_ptr(), statxbuf) | ||
.flags(self.flags) | ||
.mask(libc::STATX_ALL) | ||
.build() | ||
} | ||
|
||
#[cfg(any(feature = "legacy", feature = "poll-io"))] | ||
fn legacy_interest(&self) -> Option<(crate::driver::ready::Direction, usize)> { | ||
None | ||
} | ||
|
||
#[cfg(all(any(feature = "legacy", feature = "poll-io"), target_os = "linux"))] | ||
fn legacy_call(&mut self) -> std::io::Result<u32> { | ||
use crate::syscall_u32; | ||
|
||
syscall_u32!(statx( | ||
libc::AT_FDCWD, | ||
self.inner.as_ptr(), | ||
self.flags, | ||
libc::STATX_ALL, | ||
self.statx_buf.as_mut_ptr() as *mut _ | ||
)) | ||
} | ||
|
||
#[cfg(all(any(feature = "legacy", feature = "poll-io"), windows))] | ||
fn legacy_call(&mut self) -> std::io::Result<u32> { | ||
unimplemented!() | ||
} | ||
|
||
#[cfg(all(any(feature = "legacy", feature = "poll-io"), target_os = "macos"))] | ||
fn legacy_call(&mut self) -> std::io::Result<u32> { | ||
use crate::syscall_u32; | ||
|
||
if self.follow_symlinks { | ||
syscall_u32!(stat( | ||
self.inner.as_ptr(), | ||
self.stat_buf.as_mut_ptr() as *mut _ | ||
)) | ||
} else { | ||
syscall_u32!(lstat( | ||
self.inner.as_ptr(), | ||
self.stat_buf.as_mut_ptr() as *mut _ | ||
)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
use std::{fmt::Debug, os::unix::fs::FileTypeExt}; | ||
|
||
use libc::mode_t; | ||
|
||
/// A structure representing a type of file with accessors for each file type. | ||
#[derive(PartialEq, Eq, Clone, Copy, Hash)] | ||
pub struct FileType { | ||
pub(crate) mode: mode_t, | ||
} | ||
|
||
#[cfg(unix)] | ||
impl FileType { | ||
/// Returns `true` if this file type is a directory. | ||
pub fn is_dir(&self) -> bool { | ||
self.is(libc::S_IFDIR) | ||
} | ||
|
||
/// Returns `true` if this file type is a regular file. | ||
pub fn is_file(&self) -> bool { | ||
self.is(libc::S_IFREG) | ||
} | ||
|
||
/// Returns `true` if this file type is a symbolic link. | ||
pub fn is_symlink(&self) -> bool { | ||
self.is(libc::S_IFLNK) | ||
} | ||
|
||
pub(crate) fn is(&self, mode: mode_t) -> bool { | ||
self.masked() == mode | ||
} | ||
|
||
fn masked(&self) -> mode_t { | ||
self.mode & libc::S_IFMT | ||
} | ||
} | ||
|
||
impl FileTypeExt for FileType { | ||
fn is_block_device(&self) -> bool { | ||
self.is(libc::S_IFBLK) | ||
} | ||
|
||
fn is_char_device(&self) -> bool { | ||
self.is(libc::S_IFCHR) | ||
} | ||
|
||
fn is_fifo(&self) -> bool { | ||
self.is(libc::S_IFIFO) | ||
} | ||
|
||
fn is_socket(&self) -> bool { | ||
self.is(libc::S_IFSOCK) | ||
} | ||
} | ||
|
||
impl Debug for FileType { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.debug_struct("FileType") | ||
.field("is_file", &self.is_file()) | ||
.field("is_dir", &self.is_dir()) | ||
.field("is_symlink", &self.is_symlink()) | ||
.finish_non_exhaustive() | ||
} | ||
} |
Oops, something went wrong.