1use std::io;
2use std::os::fd::{AsRawFd, FromRawFd, OwnedFd, RawFd};
3
4pub fn take_fd(fd: RawFd) -> FdHandle {
5 assert!(
6 fd >= 0,
7 "dope invariant violated: io result cannot be negative"
8 );
9 unsafe { FdHandle::from_raw(fd) }
10}
11
12#[derive(Clone, Copy, Debug)]
13pub struct Fd {
14 fd: RawFd,
15}
16
17impl Fd {
18 #[must_use]
19 pub const fn new(fd: RawFd) -> Self {
20 Self { fd }
21 }
22}
23
24impl AsRawFd for Fd {
25 fn as_raw_fd(&self) -> RawFd {
26 self.fd
27 }
28}
29
30#[derive(Clone, Copy, Debug)]
31pub struct FixedFd {
32 fd: RawFd,
33 fixed: u32,
34}
35
36impl FixedFd {
37 #[must_use]
38 pub const fn new(fd: RawFd, fixed: u32) -> Self {
39 Self { fd, fixed }
40 }
41
42 pub const fn fixed_index(self) -> u32 {
43 self.fixed
44 }
45
46 pub const fn as_fd(self) -> Fd {
47 Fd::new(self.fd)
48 }
49}
50
51#[derive(Debug)]
52pub struct FdHandle {
53 fd: OwnedFd,
54}
55
56impl FdHandle {
57 #[must_use]
60 pub unsafe fn from_raw(fd: RawFd) -> Self {
61 Self {
62 fd: unsafe { OwnedFd::from_raw_fd(fd) },
63 }
64 }
65
66 #[must_use]
67 pub fn into_owned(self) -> OwnedFd {
68 self.fd
69 }
70
71 pub fn try_clone(&self) -> io::Result<Self> {
72 Ok(Self::from(self.fd.try_clone()?))
73 }
74
75 pub fn as_fd(&self) -> Fd {
76 Fd::new(self.fd.as_raw_fd())
77 }
78
79 pub fn fixed_io(&self, fixed: u32) -> FixedFd {
80 FixedFd::new(self.fd.as_raw_fd(), fixed)
81 }
82}
83
84impl From<OwnedFd> for FdHandle {
85 fn from(fd: OwnedFd) -> Self {
86 Self { fd }
87 }
88}
89
90impl AsRawFd for FdHandle {
91 fn as_raw_fd(&self) -> RawFd {
92 self.fd.as_raw_fd()
93 }
94}