mapped_file/file/
managed.rs1use super::*;
6use std::{
7 ops,
8};
9use libc::{
10 dup, dup2,
11 close,
12};
13
14#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
15#[repr(transparent)]
16pub struct ManagedFD(UnmanagedFD);
17
18impl Clone for ManagedFD {
19 fn clone(&self) -> Self {
20 Self(unsafe { UnmanagedFD::new_unchecked( c_try!(dup(self.0.get()) => if |x| x < 0; "dup(): failed to duplicate file descriptor {}", self.0.get()) ) })
21 }
22 fn clone_from(&mut self, source: &Self) {
23 c_try!(dup2(self.0.get(), source.0.get()) => -1; "dup2(): failed to set file descriptor {} to alias {}", self.0.get(), source.0.get());
24 }
25}
26
27impl ManagedFD
28{
29 #[inline]
30 pub const unsafe fn take_unchecked(fd: RawFd) -> Self
31 {
32 Self(UnmanagedFD::new_unchecked(fd))
33 }
34
35 #[inline]
37 pub fn alias(file: &(impl AsRawFd + ?Sized)) -> io::Result<Self>
38 {
39 let r = unsafe { libc::dup(file.as_raw_fd()) };
40 if let Some(r) = UnmanagedFD::new_raw(r) {
41 Ok(Self(r))
42 } else {
43 Err(io::Error::last_os_error())
44 }
45 }
46
47 #[inline]
48 pub const fn take_raw(fd: RawFd) -> Self
49 {
50 assert!(fd>=0, "Invalid file descriptor");
51 unsafe {
52 Self::take_unchecked(fd)
53 }
54 }
55
56 #[inline]
57 pub const fn take(fd: UnmanagedFD) -> Self
58 {
59 Self(fd)
60 }
61
62 #[inline]
63 pub fn detach(self) -> UnmanagedFD
64 {
65 let v = self.0.clone();
66 std::mem::forget(self);
67 v
68 }
69}
70
71impl ops::Drop for ManagedFD
72{
73 fn drop(&mut self) {
74 unsafe {
75 close(self.0.get());
76 }
77 }
78}
79
80impl AsRawFd for ManagedFD
81{
82 #[inline]
83 fn as_raw_fd(&self) -> RawFd {
84 self.0.get()
85 }
86}
87
88impl FromRawFd for ManagedFD
89{
90 #[inline]
91 unsafe fn from_raw_fd(fd: RawFd) -> Self {
92 Self(UnmanagedFD::new_unchecked(fd))
93 }
94}
95
96impl IntoRawFd for ManagedFD
97{
98 #[inline]
99 fn into_raw_fd(self) -> RawFd {
100 let raw = self.0.get();
101 std::mem::forget(self);
102 raw
103 }
104}
105
106impl From<ManagedFD> for std::fs::File
107{
108 #[inline]
109 fn from(from: ManagedFD) -> Self
110 {
111 unsafe {
112 Self::from_raw_fd(from.into_raw_fd())
113 }
114 }
115}
116
117raw::impl_io_for_fd!(ManagedFD => .0.get());