use std::os::fd;
use crate::{Errno, kernel};
pub trait Adopt: fd::FromRawFd + Sized {
unsafe fn try_adopt<E: From<Errno>>(
raw: fd::RawFd,
errno: impl FnOnce() -> Errno,
) -> Result<Self, E> {
let value = unsafe { kernel::raw::Status::new(raw).try_value::<E>(errno) }?;
Ok(unsafe { Self::from_raw_fd(value.get()) })
}
}
impl<T: fd::FromRawFd> Adopt for T {}
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct Pair([fd::RawFd; 2]);
impl Pair {
pub const fn new(raw: [fd::RawFd; 2]) -> Self {
Self(raw)
}
pub unsafe fn try_adopt<E: From<Errno>>(
self,
raw: libc::c_int,
errno: impl FnOnce() -> Errno,
) -> Result<(fd::OwnedFd, fd::OwnedFd), E> {
unsafe { kernel::raw::Status::new(raw).try_zero::<E>(errno) }?;
let [left, right] = self.0;
Ok(unsafe {
(
<fd::OwnedFd as fd::FromRawFd>::from_raw_fd(left),
<fd::OwnedFd as fd::FromRawFd>::from_raw_fd(right),
)
})
}
}