1 //! Raw Unix-like file descriptors. 2 3 #![stable(feature = "rust1", since = "1.0.0")] 4 5 use crate::fs; 6 use crate::io; 7 #[cfg(target_os = "hermit")] 8 use crate::os::hermit::io::OwnedFd; 9 #[cfg(not(target_os = "hermit"))] 10 use crate::os::raw; 11 #[cfg(all(doc, not(target_arch = "wasm32")))] 12 use crate::os::unix::io::AsFd; 13 #[cfg(unix)] 14 use crate::os::unix::io::OwnedFd; 15 #[cfg(target_os = "wasi")] 16 use crate::os::wasi::io::OwnedFd; 17 use crate::sys_common::{AsInner, IntoInner}; 18 #[cfg(target_os = "hermit")] 19 use hermit_abi as libc; 20 21 /// Raw file descriptors. 22 #[rustc_allowed_through_unstable_modules] 23 #[stable(feature = "rust1", since = "1.0.0")] 24 #[cfg(not(target_os = "hermit"))] 25 pub type RawFd = raw::c_int; 26 #[rustc_allowed_through_unstable_modules] 27 #[stable(feature = "rust1", since = "1.0.0")] 28 #[cfg(target_os = "hermit")] 29 pub type RawFd = i32; 30 31 /// A trait to extract the raw file descriptor from an underlying object. 32 /// 33 /// This is only available on unix and WASI platforms and must be imported in 34 /// order to call the method. Windows platforms have a corresponding 35 /// `AsRawHandle` and `AsRawSocket` set of traits. 36 #[rustc_allowed_through_unstable_modules] 37 #[stable(feature = "rust1", since = "1.0.0")] 38 pub trait AsRawFd { 39 /// Extracts the raw file descriptor. 40 /// 41 /// This function is typically used to **borrow** an owned file descriptor. 42 /// When used in this way, this method does **not** pass ownership of the 43 /// raw file descriptor to the caller, and the file descriptor is only 44 /// guaranteed to be valid while the original object has not yet been 45 /// destroyed. 46 /// 47 /// However, borrowing is not strictly required. See [`AsFd::as_fd`] 48 /// for an API which strictly borrows a file descriptor. 49 /// 50 /// # Example 51 /// 52 /// ```no_run 53 /// use std::fs::File; 54 /// # use std::io; 55 /// #[cfg(any(unix, target_os = "wasi"))] 56 /// use std::os::fd::{AsRawFd, RawFd}; 57 /// 58 /// let mut f = File::open("foo.txt")?; 59 /// // Note that `raw_fd` is only valid as long as `f` exists. 60 /// #[cfg(any(unix, target_os = "wasi"))] 61 /// let raw_fd: RawFd = f.as_raw_fd(); 62 /// # Ok::<(), io::Error>(()) 63 /// ``` 64 #[stable(feature = "rust1", since = "1.0.0")] as_raw_fd(&self) -> RawFd65 fn as_raw_fd(&self) -> RawFd; 66 } 67 68 /// A trait to express the ability to construct an object from a raw file 69 /// descriptor. 70 #[rustc_allowed_through_unstable_modules] 71 #[stable(feature = "from_raw_os", since = "1.1.0")] 72 pub trait FromRawFd { 73 /// Constructs a new instance of `Self` from the given raw file 74 /// descriptor. 75 /// 76 /// This function is typically used to **consume ownership** of the 77 /// specified file descriptor. When used in this way, the returned object 78 /// will take responsibility for closing it when the object goes out of 79 /// scope. 80 /// 81 /// However, consuming ownership is not strictly required. Use a 82 /// [`From<OwnedFd>::from`] implementation for an API which strictly 83 /// consumes ownership. 84 /// 85 /// # Safety 86 /// 87 /// The `fd` passed in must be a valid and open file descriptor. 88 /// 89 /// # Example 90 /// 91 /// ```no_run 92 /// use std::fs::File; 93 /// # use std::io; 94 /// #[cfg(any(unix, target_os = "wasi"))] 95 /// use std::os::fd::{FromRawFd, IntoRawFd, RawFd}; 96 /// 97 /// let f = File::open("foo.txt")?; 98 /// # #[cfg(any(unix, target_os = "wasi"))] 99 /// let raw_fd: RawFd = f.into_raw_fd(); 100 /// // SAFETY: no other functions should call `from_raw_fd`, so there 101 /// // is only one owner for the file descriptor. 102 /// # #[cfg(any(unix, target_os = "wasi"))] 103 /// let f = unsafe { File::from_raw_fd(raw_fd) }; 104 /// # Ok::<(), io::Error>(()) 105 /// ``` 106 #[stable(feature = "from_raw_os", since = "1.1.0")] from_raw_fd(fd: RawFd) -> Self107 unsafe fn from_raw_fd(fd: RawFd) -> Self; 108 } 109 110 /// A trait to express the ability to consume an object and acquire ownership of 111 /// its raw file descriptor. 112 #[rustc_allowed_through_unstable_modules] 113 #[stable(feature = "into_raw_os", since = "1.4.0")] 114 pub trait IntoRawFd { 115 /// Consumes this object, returning the raw underlying file descriptor. 116 /// 117 /// This function is typically used to **transfer ownership** of the underlying 118 /// file descriptor to the caller. When used in this way, callers are then the unique 119 /// owners of the file descriptor and must close it once it's no longer needed. 120 /// 121 /// However, transferring ownership is not strictly required. Use a 122 /// [`Into<OwnedFd>::into`] implementation for an API which strictly 123 /// transfers ownership. 124 /// 125 /// # Example 126 /// 127 /// ```no_run 128 /// use std::fs::File; 129 /// # use std::io; 130 /// #[cfg(any(unix, target_os = "wasi"))] 131 /// use std::os::fd::{IntoRawFd, RawFd}; 132 /// 133 /// let f = File::open("foo.txt")?; 134 /// #[cfg(any(unix, target_os = "wasi"))] 135 /// let raw_fd: RawFd = f.into_raw_fd(); 136 /// # Ok::<(), io::Error>(()) 137 /// ``` 138 #[stable(feature = "into_raw_os", since = "1.4.0")] into_raw_fd(self) -> RawFd139 fn into_raw_fd(self) -> RawFd; 140 } 141 142 #[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")] 143 impl AsRawFd for RawFd { 144 #[inline] as_raw_fd(&self) -> RawFd145 fn as_raw_fd(&self) -> RawFd { 146 *self 147 } 148 } 149 #[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")] 150 impl IntoRawFd for RawFd { 151 #[inline] into_raw_fd(self) -> RawFd152 fn into_raw_fd(self) -> RawFd { 153 self 154 } 155 } 156 #[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")] 157 impl FromRawFd for RawFd { 158 #[inline] from_raw_fd(fd: RawFd) -> RawFd159 unsafe fn from_raw_fd(fd: RawFd) -> RawFd { 160 fd 161 } 162 } 163 164 #[stable(feature = "rust1", since = "1.0.0")] 165 impl AsRawFd for fs::File { 166 #[inline] as_raw_fd(&self) -> RawFd167 fn as_raw_fd(&self) -> RawFd { 168 self.as_inner().as_raw_fd() 169 } 170 } 171 #[stable(feature = "from_raw_os", since = "1.1.0")] 172 impl FromRawFd for fs::File { 173 #[inline] from_raw_fd(fd: RawFd) -> fs::File174 unsafe fn from_raw_fd(fd: RawFd) -> fs::File { 175 unsafe { fs::File::from(OwnedFd::from_raw_fd(fd)) } 176 } 177 } 178 #[stable(feature = "into_raw_os", since = "1.4.0")] 179 impl IntoRawFd for fs::File { 180 #[inline] into_raw_fd(self) -> RawFd181 fn into_raw_fd(self) -> RawFd { 182 self.into_inner().into_inner().into_raw_fd() 183 } 184 } 185 186 #[stable(feature = "asraw_stdio", since = "1.21.0")] 187 impl AsRawFd for io::Stdin { 188 #[inline] as_raw_fd(&self) -> RawFd189 fn as_raw_fd(&self) -> RawFd { 190 libc::STDIN_FILENO 191 } 192 } 193 194 #[stable(feature = "asraw_stdio", since = "1.21.0")] 195 impl AsRawFd for io::Stdout { 196 #[inline] as_raw_fd(&self) -> RawFd197 fn as_raw_fd(&self) -> RawFd { 198 libc::STDOUT_FILENO 199 } 200 } 201 202 #[stable(feature = "asraw_stdio", since = "1.21.0")] 203 impl AsRawFd for io::Stderr { 204 #[inline] as_raw_fd(&self) -> RawFd205 fn as_raw_fd(&self) -> RawFd { 206 libc::STDERR_FILENO 207 } 208 } 209 210 #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] 211 impl<'a> AsRawFd for io::StdinLock<'a> { 212 #[inline] as_raw_fd(&self) -> RawFd213 fn as_raw_fd(&self) -> RawFd { 214 libc::STDIN_FILENO 215 } 216 } 217 218 #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] 219 impl<'a> AsRawFd for io::StdoutLock<'a> { 220 #[inline] as_raw_fd(&self) -> RawFd221 fn as_raw_fd(&self) -> RawFd { 222 libc::STDOUT_FILENO 223 } 224 } 225 226 #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] 227 impl<'a> AsRawFd for io::StderrLock<'a> { 228 #[inline] as_raw_fd(&self) -> RawFd229 fn as_raw_fd(&self) -> RawFd { 230 libc::STDERR_FILENO 231 } 232 } 233 234 /// This impl allows implementing traits that require `AsRawFd` on Arc. 235 /// ``` 236 /// # #[cfg(any(unix, target_os = "wasi"))] mod group_cfg { 237 /// # #[cfg(target_os = "wasi")] 238 /// # use std::os::wasi::io::AsRawFd; 239 /// # #[cfg(unix)] 240 /// # use std::os::unix::io::AsRawFd; 241 /// use std::net::UdpSocket; 242 /// use std::sync::Arc; 243 /// trait MyTrait: AsRawFd { 244 /// } 245 /// impl MyTrait for Arc<UdpSocket> {} 246 /// impl MyTrait for Box<UdpSocket> {} 247 /// # } 248 /// ``` 249 #[stable(feature = "asrawfd_ptrs", since = "1.63.0")] 250 impl<T: AsRawFd> AsRawFd for crate::sync::Arc<T> { 251 #[inline] as_raw_fd(&self) -> RawFd252 fn as_raw_fd(&self) -> RawFd { 253 (**self).as_raw_fd() 254 } 255 } 256 257 #[stable(feature = "asfd_rc", since = "1.69.0")] 258 impl<T: AsRawFd> AsRawFd for crate::rc::Rc<T> { 259 #[inline] as_raw_fd(&self) -> RawFd260 fn as_raw_fd(&self) -> RawFd { 261 (**self).as_raw_fd() 262 } 263 } 264 265 #[stable(feature = "asrawfd_ptrs", since = "1.63.0")] 266 impl<T: AsRawFd> AsRawFd for Box<T> { 267 #[inline] as_raw_fd(&self) -> RawFd268 fn as_raw_fd(&self) -> RawFd { 269 (**self).as_raw_fd() 270 } 271 } 272