1use core::marker::PhantomData;
2
3use rusl::platform::{Fd, OpenFlags};
4use rusl::unistd::fcntl_set_file_status;
5
6pub type RawFd = Fd;
7
8#[repr(transparent)]
9#[derive(Debug)]
10pub struct OwnedFd(pub(crate) RawFd);
11
12impl OwnedFd {
13 #[must_use]
17 pub const unsafe fn from_raw(raw: RawFd) -> Self {
18 Self(raw)
19 }
20
21 #[inline]
25 pub fn set_nonblocking(&self) -> crate::error::Result<()> {
26 set_fd_nonblocking(self.as_raw_fd())
27 }
28}
29
30impl AsRawFd for OwnedFd {
31 #[inline]
32 fn as_raw_fd(&self) -> RawFd {
33 self.0
34 }
35}
36
37impl Drop for OwnedFd {
38 fn drop(&mut self) {
39 let _ = rusl::unistd::close(self.0);
41 }
42}
43
44#[repr(transparent)]
45#[derive(Debug, Copy, Clone)]
46pub struct BorrowedFd<'fd> {
47 pub(crate) fd: RawFd,
48 _pd: PhantomData<&'fd OwnedFd>,
49}
50
51impl BorrowedFd<'_> {
52 pub(crate) fn new(fd: RawFd) -> Self {
53 Self {
54 fd,
55 _pd: PhantomData,
56 }
57 }
58}
59
60impl AsRawFd for BorrowedFd<'_> {
61 #[inline]
62 fn as_raw_fd(&self) -> RawFd {
63 self.fd
64 }
65}
66
67pub trait AsRawFd {
68 fn as_raw_fd(&self) -> RawFd;
69}
70
71#[inline]
72pub(crate) fn set_fd_nonblocking(raw_fd: RawFd) -> crate::error::Result<()> {
73 let orig = rusl::unistd::fcntl_get_file_status(raw_fd)?;
74 fcntl_set_file_status(raw_fd, orig | OpenFlags::O_NONBLOCK)?;
75 Ok(())
76}