1 //! Portability abstractions over `Raw*`. 2 //! 3 //! On Unix, "everything is a file descriptor". On Windows, file/pipe/process 4 //! handles are distinct from socket descriptors. This file provides a minimal 5 //! layer of portability over this difference. 6 7 #[cfg(unix)] 8 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; 9 #[cfg(target_os = "wasi")] 10 use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; 11 #[cfg(windows)] 12 use std::os::windows::io::{ 13 AsRawHandle, AsRawSocket, FromRawHandle, FromRawSocket, IntoRawHandle, IntoRawSocket, 14 RawHandle, RawSocket, 15 }; 16 17 /// A raw filelike object. 18 /// 19 /// This is a portability abstraction over Unix-like [`RawFd`] and 20 /// Windows' `RawHandle`. 21 #[cfg(any(unix, target_os = "wasi"))] 22 pub type RawFilelike = RawFd; 23 24 /// A raw filelike object. 25 /// 26 /// This is a portability abstraction over Unix-like `RawFd` and 27 /// Windows' [`RawHandle`]. 28 #[cfg(windows)] 29 pub type RawFilelike = RawHandle; 30 31 /// A raw socketlike object. 32 /// 33 /// This is a portability abstraction over Unix-like [`RawFd`] and 34 /// Windows' `RawSocket`. 35 #[cfg(any(unix, target_os = "wasi"))] 36 pub type RawSocketlike = RawFd; 37 38 /// A raw socketlike object. 39 /// 40 /// This is a portability abstraction over Unix-like `RawFd` and 41 /// Windows' [`RawSocket`]. 42 #[cfg(windows)] 43 pub type RawSocketlike = RawSocket; 44 45 /// A portable trait to obtain the raw value of an underlying filelike object. 46 /// 47 /// This is a portability abstraction over Unix-like [`AsRawFd`] and Windows' 48 /// `AsRawHandle`. 49 #[cfg(any(unix, target_os = "wasi"))] 50 pub trait AsRawFilelike: AsRawFd { 51 /// Returns the raw value. as_raw_filelike(&self) -> RawFilelike52 fn as_raw_filelike(&self) -> RawFilelike; 53 } 54 55 #[cfg(any(unix, target_os = "wasi"))] 56 impl<T: AsRawFd> AsRawFilelike for T { 57 #[inline] as_raw_filelike(&self) -> RawFilelike58 fn as_raw_filelike(&self) -> RawFilelike { 59 self.as_raw_fd() 60 } 61 } 62 63 /// This is a portability abstraction over Unix-like `AsRawFd` and Windows' 64 /// [`AsRawHandle`]. 65 #[cfg(windows)] 66 pub trait AsRawFilelike: AsRawHandle { 67 /// Returns the raw value. as_raw_filelike(&self) -> RawFilelike68 fn as_raw_filelike(&self) -> RawFilelike; 69 } 70 71 #[cfg(windows)] 72 impl<T: AsRawHandle> AsRawFilelike for T { 73 #[inline] as_raw_filelike(&self) -> RawFilelike74 fn as_raw_filelike(&self) -> RawFilelike { 75 self.as_raw_handle() 76 } 77 } 78 79 /// This is a portability abstraction over Unix-like [`AsRawFd`] and Windows' 80 /// `AsRawSocket`. 81 #[cfg(any(unix, target_os = "wasi"))] 82 pub trait AsRawSocketlike: AsRawFd { 83 /// Returns the raw value. as_raw_socketlike(&self) -> RawSocketlike84 fn as_raw_socketlike(&self) -> RawSocketlike; 85 } 86 87 #[cfg(any(unix, target_os = "wasi"))] 88 impl<T: AsRawFd> AsRawSocketlike for T { 89 #[inline] as_raw_socketlike(&self) -> RawSocketlike90 fn as_raw_socketlike(&self) -> RawSocketlike { 91 self.as_raw_fd() 92 } 93 } 94 95 /// This is a portability abstraction over Unix-like `AsRawFd` and Windows' 96 /// [`AsRawSocket`]. 97 #[cfg(windows)] 98 pub trait AsRawSocketlike: AsRawSocket { 99 /// Returns the raw value. as_raw_socketlike(&self) -> RawSocketlike100 fn as_raw_socketlike(&self) -> RawSocketlike; 101 } 102 103 #[cfg(windows)] 104 impl<T: AsRawSocket> AsRawSocketlike for T { 105 #[inline] as_raw_socketlike(&self) -> RawSocketlike106 fn as_raw_socketlike(&self) -> RawSocketlike { 107 self.as_raw_socket() 108 } 109 } 110 111 /// This is a portability abstraction over Unix-like [`IntoRawFd`] and Windows' 112 /// `IntoRawHandle`. 113 #[cfg(any(unix, target_os = "wasi"))] 114 pub trait IntoRawFilelike: IntoRawFd { 115 /// Returns the raw value. into_raw_filelike(self) -> RawFilelike116 fn into_raw_filelike(self) -> RawFilelike; 117 } 118 119 #[cfg(any(unix, target_os = "wasi"))] 120 impl<T: IntoRawFd> IntoRawFilelike for T { 121 #[inline] into_raw_filelike(self) -> RawFilelike122 fn into_raw_filelike(self) -> RawFilelike { 123 self.into_raw_fd() 124 } 125 } 126 127 /// This is a portability abstraction over Unix-like `IntoRawFd` and Windows' 128 /// [`IntoRawHandle`]. 129 #[cfg(windows)] 130 pub trait IntoRawFilelike: IntoRawHandle { 131 /// Returns the raw value. into_raw_filelike(self) -> RawFilelike132 fn into_raw_filelike(self) -> RawFilelike; 133 } 134 135 #[cfg(windows)] 136 impl<T: IntoRawHandle> IntoRawFilelike for T { 137 #[inline] into_raw_filelike(self) -> RawFilelike138 fn into_raw_filelike(self) -> RawFilelike { 139 self.into_raw_handle() 140 } 141 } 142 143 /// This is a portability abstraction over Unix-like [`IntoRawFd`] and Windows' 144 /// `IntoRawSocket`. 145 #[cfg(any(unix, target_os = "wasi"))] 146 pub trait IntoRawSocketlike: IntoRawFd { 147 /// Returns the raw value. into_raw_socketlike(self) -> RawSocketlike148 fn into_raw_socketlike(self) -> RawSocketlike; 149 } 150 151 #[cfg(any(unix, target_os = "wasi"))] 152 impl<T: IntoRawFd> IntoRawSocketlike for T { 153 #[inline] into_raw_socketlike(self) -> RawSocketlike154 fn into_raw_socketlike(self) -> RawSocketlike { 155 self.into_raw_fd() 156 } 157 } 158 159 /// This is a portability abstraction over Unix-like `IntoRawFd` and Windows' 160 /// [`IntoRawSocket`]. 161 #[cfg(windows)] 162 pub trait IntoRawSocketlike: IntoRawSocket { 163 /// Returns the raw value. into_raw_socketlike(self) -> RawSocketlike164 fn into_raw_socketlike(self) -> RawSocketlike; 165 } 166 167 #[cfg(windows)] 168 impl<T: IntoRawSocket> IntoRawSocketlike for T { 169 #[inline] into_raw_socketlike(self) -> RawSocketlike170 fn into_raw_socketlike(self) -> RawSocketlike { 171 self.into_raw_socket() 172 } 173 } 174 175 /// This is a portability abstraction over Unix-like [`FromRawFd`] and Windows' 176 /// `FromRawHandle`. 177 #[cfg(any(unix, target_os = "wasi"))] 178 pub trait FromRawFilelike: FromRawFd { 179 /// Constructs `Self` from the raw value. 180 /// 181 /// # Safety 182 /// 183 /// This is `unsafe` for the same reason as [`from_raw_fd`] and 184 /// [`from_raw_handle`]. 185 /// 186 /// [`from_raw_fd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.FromRawFd.html#tymethod.from_raw_fd 187 /// [`from_raw_handle`]: https://doc.rust-lang.org/stable/std/os/windows/io/trait.FromRawHandle.html#tymethod.from_raw_handle from_raw_filelike(raw: RawFilelike) -> Self188 unsafe fn from_raw_filelike(raw: RawFilelike) -> Self; 189 } 190 191 #[cfg(any(unix, target_os = "wasi"))] 192 impl<T: FromRawFd> FromRawFilelike for T { 193 #[inline] from_raw_filelike(raw: RawFilelike) -> Self194 unsafe fn from_raw_filelike(raw: RawFilelike) -> Self { 195 Self::from_raw_fd(raw) 196 } 197 } 198 199 /// This is a portability abstraction over Unix-like `FromRawFd` and Windows' 200 /// [`FromRawHandle`]. 201 #[cfg(windows)] 202 pub trait FromRawFilelike: FromRawHandle { 203 /// Constructs `Self` from the raw value. from_raw_filelike(raw: RawFilelike) -> Self204 unsafe fn from_raw_filelike(raw: RawFilelike) -> Self; 205 } 206 207 #[cfg(windows)] 208 impl<T: FromRawHandle> FromRawFilelike for T { 209 #[inline] from_raw_filelike(raw: RawFilelike) -> Self210 unsafe fn from_raw_filelike(raw: RawFilelike) -> Self { 211 Self::from_raw_handle(raw) 212 } 213 } 214 215 /// This is a portability abstraction over Unix-like [`FromRawFd`] and Windows' 216 /// `FromRawSocket`. 217 #[cfg(any(unix, target_os = "wasi"))] 218 pub trait FromRawSocketlike: FromRawFd { 219 /// Constructs `Self` from the raw value. 220 /// 221 /// # Safety 222 /// 223 /// This is `unsafe` for the same reason as [`from_raw_fd`] and 224 /// [`from_raw_socket`]. 225 /// 226 /// [`from_raw_fd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.FromRawFd.html#tymethod.from_raw_fd 227 /// [`from_raw_socket`]: https://doc.rust-lang.org/stable/std/os/windows/io/trait.FromRawSocket.html#tymethod.from_raw_socket from_raw_socketlike(raw: RawSocketlike) -> Self228 unsafe fn from_raw_socketlike(raw: RawSocketlike) -> Self; 229 } 230 231 #[cfg(any(unix, target_os = "wasi"))] 232 impl<T: FromRawFd> FromRawSocketlike for T { 233 #[inline] from_raw_socketlike(raw: RawSocketlike) -> Self234 unsafe fn from_raw_socketlike(raw: RawSocketlike) -> Self { 235 Self::from_raw_fd(raw) 236 } 237 } 238 239 /// This is a portability abstraction over Unix-like `FromRawFd` and Windows' 240 /// [`FromRawSocket`]. 241 #[cfg(windows)] 242 pub trait FromRawSocketlike: FromRawSocket { 243 /// Constructs `Self` from the raw value. from_raw_socketlike(raw: RawSocketlike) -> Self244 unsafe fn from_raw_socketlike(raw: RawSocketlike) -> Self; 245 } 246 247 #[cfg(windows)] 248 impl<T: FromRawSocket> FromRawSocketlike for T { 249 #[inline] from_raw_socketlike(raw: RawSocketlike) -> Self250 unsafe fn from_raw_socketlike(raw: RawSocketlike) -> Self { 251 Self::from_raw_socket(raw) 252 } 253 } 254