tiny_std/unix/
fd.rs

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    /// Create an `OwnedFd` from a `RawFd`
14    /// # Safety
15    /// `fd` is valid and not used elsewhere, see `File::from_raw_fd`
16    #[must_use]
17    pub const unsafe fn from_raw(raw: RawFd) -> Self {
18        Self(raw)
19    }
20
21    /// Sets this owned FD as non-blocking
22    /// # Errors
23    /// This FD is invalid, through unsafe creation
24    #[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        // Best attempt
40        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}