use crate::{
capi,
flags::OpenFlags,
tests::{
capi::utils::{self as capi_utils, CapiError},
traits::HandleImpl,
},
};
use std::{
fs::File,
os::unix::io::{AsFd, BorrowedFd, OwnedFd},
};
#[derive(Debug)]
pub struct CapiHandle {
inner: OwnedFd,
}
impl CapiHandle {
fn from_fd(fd: impl Into<OwnedFd>) -> Self {
Self { inner: fd.into() }
}
fn try_clone(&self) -> Result<Self, anyhow::Error> {
Ok(Self::from_fd(self.inner.try_clone()?))
}
fn reopen(&self, flags: impl Into<OpenFlags>) -> Result<File, CapiError> {
let fd = self.inner.as_fd();
let flags = flags.into();
capi_utils::call_capi_fd(|| capi::core::pathrs_reopen(fd.into(), flags.bits()))
.map(File::from)
}
}
impl AsFd for CapiHandle {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.as_fd()
}
}
impl From<CapiHandle> for OwnedFd {
fn from(handle: CapiHandle) -> Self {
handle.inner
}
}
impl HandleImpl for CapiHandle {
type Cloned = CapiHandle;
type Error = CapiError;
fn from_fd(fd: impl Into<OwnedFd>) -> Self::Cloned {
Self::Cloned::from_fd(fd)
}
fn try_clone(&self) -> Result<Self::Cloned, anyhow::Error> {
self.try_clone()
}
fn reopen(&self, flags: impl Into<OpenFlags>) -> Result<File, Self::Error> {
self.reopen(flags)
}
}
impl HandleImpl for &CapiHandle {
type Cloned = CapiHandle;
type Error = CapiError;
fn from_fd(fd: impl Into<OwnedFd>) -> Self::Cloned {
Self::Cloned::from_fd(fd)
}
fn try_clone(&self) -> Result<Self::Cloned, anyhow::Error> {
CapiHandle::try_clone(self)
}
fn reopen(&self, flags: impl Into<OpenFlags>) -> Result<File, Self::Error> {
CapiHandle::reopen(self, flags)
}
}