#![forbid(unsafe_op_in_unsafe_fn)]
use std::{
os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd},
path::PathBuf,
sync::Arc,
};
#[derive(Debug, Clone)]
pub struct DeviceFd(Arc<OwnedFd>);
impl PartialEq for DeviceFd {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.0.as_raw_fd() == other.0.as_raw_fd()
}
}
impl AsFd for DeviceFd {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_fd()
}
}
impl AsRawFd for DeviceFd {
#[inline]
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}
impl FromRawFd for DeviceFd {
#[inline]
unsafe fn from_raw_fd(fd: RawFd) -> Self {
DeviceFd(Arc::new(unsafe { OwnedFd::from_raw_fd(fd) }))
}
}
impl From<OwnedFd> for DeviceFd {
#[inline]
fn from(fd: OwnedFd) -> Self {
DeviceFd(Arc::new(fd))
}
}
impl TryInto<OwnedFd> for DeviceFd {
type Error = DeviceFd;
#[inline]
fn try_into(self) -> Result<OwnedFd, Self::Error> {
Arc::try_unwrap(self.0).map_err(DeviceFd)
}
}
pub trait DevPath {
fn dev_path(&self) -> Option<PathBuf>;
}
impl<A: AsFd> DevPath for A {
fn dev_path(&self) -> Option<PathBuf> {
use std::fs;
fs::read_link(format!("/proc/self/fd/{:?}", self.as_fd().as_raw_fd())).ok()
}
}