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)] 8use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; 9#[cfg(target_os = "wasi")] 10use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; 11#[cfg(windows)] 12use 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"))] 22pub 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)] 29pub 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"))] 36pub 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)] 43pub 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"))] 50pub trait AsRawFilelike: AsRawFd { 51 /// Returns the raw value. 52 fn as_raw_filelike(&self) -> RawFilelike; 53} 54 55#[cfg(any(unix, target_os = "wasi"))] 56impl<T: AsRawFd> AsRawFilelike for T { 57 #[inline] 58 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)] 66pub trait AsRawFilelike: AsRawHandle { 67 /// Returns the raw value. 68 fn as_raw_filelike(&self) -> RawFilelike; 69} 70 71#[cfg(windows)] 72impl<T: AsRawHandle> AsRawFilelike for T { 73 #[inline] 74 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"))] 82pub trait AsRawSocketlike: AsRawFd { 83 /// Returns the raw value. 84 fn as_raw_socketlike(&self) -> RawSocketlike; 85} 86 87#[cfg(any(unix, target_os = "wasi"))] 88impl<T: AsRawFd> AsRawSocketlike for T { 89 #[inline] 90 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)] 98pub trait AsRawSocketlike: AsRawSocket { 99 /// Returns the raw value. 100 fn as_raw_socketlike(&self) -> RawSocketlike; 101} 102 103#[cfg(windows)] 104impl<T: AsRawSocket> AsRawSocketlike for T { 105 #[inline] 106 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"))] 114pub trait IntoRawFilelike: IntoRawFd { 115 /// Returns the raw value. 116 fn into_raw_filelike(self) -> RawFilelike; 117} 118 119#[cfg(any(unix, target_os = "wasi"))] 120impl<T: IntoRawFd> IntoRawFilelike for T { 121 #[inline] 122 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)] 130pub trait IntoRawFilelike: IntoRawHandle { 131 /// Returns the raw value. 132 fn into_raw_filelike(self) -> RawFilelike; 133} 134 135#[cfg(windows)] 136impl<T: IntoRawHandle> IntoRawFilelike for T { 137 #[inline] 138 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"))] 146pub trait IntoRawSocketlike: IntoRawFd { 147 /// Returns the raw value. 148 fn into_raw_socketlike(self) -> RawSocketlike; 149} 150 151#[cfg(any(unix, target_os = "wasi"))] 152impl<T: IntoRawFd> IntoRawSocketlike for T { 153 #[inline] 154 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)] 162pub trait IntoRawSocketlike: IntoRawSocket { 163 /// Returns the raw value. 164 fn into_raw_socketlike(self) -> RawSocketlike; 165} 166 167#[cfg(windows)] 168impl<T: IntoRawSocket> IntoRawSocketlike for T { 169 #[inline] 170 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"))] 178pub 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 188 unsafe fn from_raw_filelike(raw: RawFilelike) -> Self; 189} 190 191#[cfg(any(unix, target_os = "wasi"))] 192impl<T: FromRawFd> FromRawFilelike for T { 193 #[inline] 194 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)] 202pub trait FromRawFilelike: FromRawHandle { 203 /// Constructs `Self` from the raw value. 204 unsafe fn from_raw_filelike(raw: RawFilelike) -> Self; 205} 206 207#[cfg(windows)] 208impl<T: FromRawHandle> FromRawFilelike for T { 209 #[inline] 210 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"))] 218pub 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 228 unsafe fn from_raw_socketlike(raw: RawSocketlike) -> Self; 229} 230 231#[cfg(any(unix, target_os = "wasi"))] 232impl<T: FromRawFd> FromRawSocketlike for T { 233 #[inline] 234 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)] 242pub trait FromRawSocketlike: FromRawSocket { 243 /// Constructs `Self` from the raw value. 244 unsafe fn from_raw_socketlike(raw: RawSocketlike) -> Self; 245} 246 247#[cfg(windows)] 248impl<T: FromRawSocket> FromRawSocketlike for T { 249 #[inline] 250 unsafe fn from_raw_socketlike(raw: RawSocketlike) -> Self { 251 Self::from_raw_socket(raw) 252 } 253} 254