use rustix::fs::*;
use crate::op::*;
pub struct OpenFile<S: AsFd> {
pub(crate) dirfd: S,
pub(crate) path: CString,
pub(crate) flags: OFlags,
pub(crate) mode: Mode,
pub(crate) opened_fd: Option<OwnedFd>,
}
impl<S: AsFd> OpenFile<S> {
pub fn new(dirfd: S, path: CString, flags: OFlags, mode: Mode) -> Self {
Self {
dirfd,
path,
flags,
mode,
opened_fd: None,
}
}
pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
self.opened_fd = Some(openat(
self.dirfd.as_fd(),
&self.path,
self.flags | OFlags::CLOEXEC,
self.mode,
)?);
Ok(0)
}
}
impl<S: AsFd> IntoInner for OpenFile<S> {
type Inner = OwnedFd;
fn into_inner(self) -> Self::Inner {
self.opened_fd.expect("file not opened")
}
}
impl CloseFile {
pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
unsafe { ManuallyDrop::drop(&mut self.fd) };
Ok(0)
}
}
#[derive(Debug)]
pub struct TruncateFile<S: AsFd> {
pub(crate) fd: S,
pub(crate) size: u64,
}
impl<S: AsFd> TruncateFile<S> {
pub fn new(fd: S, size: u64) -> Self {
Self { fd, size }
}
pub(crate) fn call(&self) -> io::Result<usize> {
ftruncate(self.fd.as_fd(), self.size)?;
Ok(0)
}
}
#[doc(hidden)]
#[derive(Default)]
pub struct VectoredControl {
pub(crate) slices: Vec<SysSlice>,
}
pub struct ReadVectoredAt<T: IoVectoredBufMut, S> {
pub(crate) fd: S,
pub(crate) offset: u64,
pub(crate) buffer: T,
}
impl<T: IoVectoredBufMut, S> ReadVectoredAt<T, S> {
pub fn new(fd: S, offset: u64, buffer: T) -> Self {
Self { fd, offset, buffer }
}
}
impl<T: IoVectoredBufMut, S> IntoInner for ReadVectoredAt<T, S> {
type Inner = T;
fn into_inner(self) -> Self::Inner {
self.buffer
}
}
pub struct WriteVectoredAt<T: IoVectoredBuf, S> {
pub(crate) fd: S,
pub(crate) offset: u64,
pub(crate) buffer: T,
}
impl<T: IoVectoredBuf, S> WriteVectoredAt<T, S> {
pub fn new(fd: S, offset: u64, buffer: T) -> Self {
Self { fd, offset, buffer }
}
}
impl<T: IoVectoredBuf, S> IntoInner for WriteVectoredAt<T, S> {
type Inner = T;
fn into_inner(self) -> Self::Inner {
self.buffer
}
}
pub struct ReadVectored<T: IoVectoredBufMut, S> {
pub(crate) fd: S,
pub(crate) buffer: T,
}
impl<T: IoVectoredBufMut, S> ReadVectored<T, S> {
pub fn new(fd: S, buffer: T) -> Self {
Self { fd, buffer }
}
}
impl<T: IoVectoredBufMut, S> IntoInner for ReadVectored<T, S> {
type Inner = T;
fn into_inner(self) -> Self::Inner {
self.buffer
}
}
pub struct WriteVectored<T: IoVectoredBuf, S> {
pub(crate) fd: S,
pub(crate) buffer: T,
}
impl<T: IoVectoredBuf, S> WriteVectored<T, S> {
pub fn new(fd: S, buffer: T) -> Self {
Self { fd, buffer }
}
}
impl<T: IoVectoredBuf, S> IntoInner for WriteVectored<T, S> {
type Inner = T;
fn into_inner(self) -> Self::Inner {
self.buffer
}
}
pub struct Unlink<S: AsFd> {
pub(crate) dirfd: S,
pub(crate) path: CString,
pub(crate) dir: bool,
}
impl<S: AsFd> Unlink<S> {
pub fn new(dirfd: S, path: CString, dir: bool) -> Self {
Self { dirfd, path, dir }
}
pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
let flags = if self.dir {
AtFlags::REMOVEDIR
} else {
AtFlags::empty()
};
unlinkat(self.dirfd.as_fd(), &self.path, flags)?;
Ok(0)
}
}
pub struct CreateDir<S: AsFd> {
pub(crate) dirfd: S,
pub(crate) path: CString,
pub(crate) mode: Mode,
}
impl<S: AsFd> CreateDir<S> {
pub fn new(dirfd: S, path: CString, mode: Mode) -> Self {
Self { dirfd, path, mode }
}
pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
mkdirat(self.dirfd.as_fd(), &self.path, self.mode)?;
Ok(0)
}
}
pub struct Rename<S1: AsFd, S2: AsFd> {
pub(crate) old_dirfd: S1,
pub(crate) old_path: CString,
pub(crate) new_dirfd: S2,
pub(crate) new_path: CString,
}
impl<S1: AsFd, S2: AsFd> Rename<S1, S2> {
pub fn new(old_dirfd: S1, old_path: CString, new_dirfd: S2, new_path: CString) -> Self {
Self {
old_dirfd,
old_path,
new_dirfd,
new_path,
}
}
pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
renameat(
self.old_dirfd.as_fd(),
&self.old_path,
self.new_dirfd.as_fd(),
&self.new_path,
)?;
Ok(0)
}
}
pub struct Symlink<S: AsFd> {
pub(crate) source: CString,
pub(crate) dirfd: S,
pub(crate) target: CString,
}
impl<S: AsFd> Symlink<S> {
pub fn new(source: CString, dirfd: S, target: CString) -> Self {
Self {
source,
dirfd,
target,
}
}
pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
symlinkat(&self.source, self.dirfd.as_fd(), &self.target)?;
Ok(0)
}
}
pub struct HardLink<S1: AsFd, S2: AsFd> {
pub(crate) source_dirfd: S1,
pub(crate) source: CString,
pub(crate) target_dirfd: S2,
pub(crate) target: CString,
}
impl<S1: AsFd, S2: AsFd> HardLink<S1, S2> {
pub fn new(source_dirfd: S1, source: CString, target_dirfd: S2, target: CString) -> Self {
Self {
source_dirfd,
source,
target_dirfd,
target,
}
}
pub(crate) fn call(&mut self, _: &mut ()) -> io::Result<usize> {
linkat(
self.source_dirfd.as_fd(),
&self.source,
self.target_dirfd.as_fd(),
&self.target,
AtFlags::empty(),
)?;
Ok(0)
}
}
pub struct PollOnce<S> {
pub(crate) fd: S,
pub(crate) interest: Interest,
}
impl<S> PollOnce<S> {
pub fn new(fd: S, interest: Interest) -> Self {
Self { fd, interest }
}
}
impl<S> IntoInner for PollOnce<S> {
type Inner = S;
fn into_inner(self) -> Self::Inner {
self.fd
}
}
pub struct Pipe {
pub(crate) fds: [Option<OwnedFd>; 2],
}
const _: () = assert!(std::mem::size_of::<Option<OwnedFd>>() == std::mem::size_of::<RawFd>());
impl Pipe {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self { fds: [None, None] }
}
pub(crate) fn call(&mut self) -> io::Result<usize> {
self.fds = mk_pipe()?;
Ok(0)
}
}
impl IntoInner for Pipe {
type Inner = (OwnedFd, OwnedFd);
fn into_inner(self) -> Self::Inner {
let [read_fd, write_fd] = self.fds;
let read_fd = read_fd.expect("pipe not created");
let write_fd = write_fd.expect("pipe not created");
(read_fd, write_fd)
}
}