]> git.proxmox.com Git - rustc.git/blob - library/std/src/os/windows/io/raw.rs
New upstream version 1.62.1+dfsg1
[rustc.git] / library / std / src / os / windows / io / raw.rs
1 //! Windows-specific extensions to general I/O primitives.
2
3 #![stable(feature = "rust1", since = "1.0.0")]
4
5 use crate::fs;
6 use crate::io;
7 use crate::net;
8 #[cfg(doc)]
9 use crate::os::windows::io::{AsHandle, AsSocket};
10 use crate::os::windows::io::{OwnedHandle, OwnedSocket};
11 use crate::os::windows::raw;
12 use crate::ptr;
13 use crate::sys;
14 use crate::sys::c;
15 use crate::sys_common::{self, AsInner, FromInner, IntoInner};
16
17 /// Raw HANDLEs.
18 #[stable(feature = "rust1", since = "1.0.0")]
19 pub type RawHandle = raw::HANDLE;
20
21 /// Raw SOCKETs.
22 #[stable(feature = "rust1", since = "1.0.0")]
23 pub type RawSocket = raw::SOCKET;
24
25 /// Extracts raw handles.
26 #[stable(feature = "rust1", since = "1.0.0")]
27 pub trait AsRawHandle {
28 /// Extracts the raw handle.
29 ///
30 /// This function is typically used to **borrow** an owned handle.
31 /// When used in this way, this method does **not** pass ownership of the
32 /// raw handle to the caller, and the handle is only guaranteed
33 /// to be valid while the original object has not yet been destroyed.
34 ///
35 /// This function may return null, such as when called on [`Stdin`],
36 /// [`Stdout`], or [`Stderr`] when the console is detached.
37 ///
38 /// However, borrowing is not strictly required. See [`AsHandle::as_handle`]
39 /// for an API which strictly borrows a handle.
40 ///
41 /// [`Stdin`]: io::Stdin
42 /// [`Stdout`]: io::Stdout
43 /// [`Stderr`]: io::Stderr
44 #[stable(feature = "rust1", since = "1.0.0")]
45 fn as_raw_handle(&self) -> RawHandle;
46 }
47
48 /// Construct I/O objects from raw handles.
49 #[stable(feature = "from_raw_os", since = "1.1.0")]
50 pub trait FromRawHandle {
51 /// Constructs a new I/O object from the specified raw handle.
52 ///
53 /// This function is typically used to **consume ownership** of the handle
54 /// given, passing responsibility for closing the handle to the returned
55 /// object. When used in this way, the returned object
56 /// will take responsibility for closing it when the object goes out of
57 /// scope.
58 ///
59 /// However, consuming ownership is not strictly required. Use a
60 /// `From<OwnedHandle>::from` implementation for an API which strictly
61 /// consumes ownership.
62 ///
63 /// # Safety
64 ///
65 /// The `handle` passed in must:
66 /// - be a valid an open handle,
67 /// - be a handle for a resource that may be freed via [`CloseHandle`]
68 /// (as opposed to `RegCloseKey` or other close functions).
69 ///
70 /// Note that the handle *may* have the value `INVALID_HANDLE_VALUE` (-1),
71 /// which is sometimes a valid handle value. See [here] for the full story.
72 ///
73 /// [`CloseHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle
74 /// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
75 #[stable(feature = "from_raw_os", since = "1.1.0")]
76 unsafe fn from_raw_handle(handle: RawHandle) -> Self;
77 }
78
79 /// A trait to express the ability to consume an object and acquire ownership of
80 /// its raw `HANDLE`.
81 #[stable(feature = "into_raw_os", since = "1.4.0")]
82 pub trait IntoRawHandle {
83 /// Consumes this object, returning the raw underlying handle.
84 ///
85 /// This function is typically used to **transfer ownership** of the underlying
86 /// handle to the caller. When used in this way, callers are then the unique
87 /// owners of the handle and must close it once it's no longer needed.
88 ///
89 /// However, transferring ownership is not strictly required. Use a
90 /// `Into<OwnedHandle>::into` implementation for an API which strictly
91 /// transfers ownership.
92 #[stable(feature = "into_raw_os", since = "1.4.0")]
93 fn into_raw_handle(self) -> RawHandle;
94 }
95
96 #[stable(feature = "rust1", since = "1.0.0")]
97 impl AsRawHandle for fs::File {
98 #[inline]
99 fn as_raw_handle(&self) -> RawHandle {
100 self.as_inner().as_raw_handle() as RawHandle
101 }
102 }
103
104 #[stable(feature = "asraw_stdio", since = "1.21.0")]
105 impl AsRawHandle for io::Stdin {
106 fn as_raw_handle(&self) -> RawHandle {
107 stdio_handle(unsafe { c::GetStdHandle(c::STD_INPUT_HANDLE) as RawHandle })
108 }
109 }
110
111 #[stable(feature = "asraw_stdio", since = "1.21.0")]
112 impl AsRawHandle for io::Stdout {
113 fn as_raw_handle(&self) -> RawHandle {
114 stdio_handle(unsafe { c::GetStdHandle(c::STD_OUTPUT_HANDLE) as RawHandle })
115 }
116 }
117
118 #[stable(feature = "asraw_stdio", since = "1.21.0")]
119 impl AsRawHandle for io::Stderr {
120 fn as_raw_handle(&self) -> RawHandle {
121 stdio_handle(unsafe { c::GetStdHandle(c::STD_ERROR_HANDLE) as RawHandle })
122 }
123 }
124
125 #[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
126 impl<'a> AsRawHandle for io::StdinLock<'a> {
127 fn as_raw_handle(&self) -> RawHandle {
128 stdio_handle(unsafe { c::GetStdHandle(c::STD_INPUT_HANDLE) as RawHandle })
129 }
130 }
131
132 #[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
133 impl<'a> AsRawHandle for io::StdoutLock<'a> {
134 fn as_raw_handle(&self) -> RawHandle {
135 stdio_handle(unsafe { c::GetStdHandle(c::STD_OUTPUT_HANDLE) as RawHandle })
136 }
137 }
138
139 #[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
140 impl<'a> AsRawHandle for io::StderrLock<'a> {
141 fn as_raw_handle(&self) -> RawHandle {
142 stdio_handle(unsafe { c::GetStdHandle(c::STD_ERROR_HANDLE) as RawHandle })
143 }
144 }
145
146 // Translate a handle returned from `GetStdHandle` into a handle to return to
147 // the user.
148 fn stdio_handle(raw: RawHandle) -> RawHandle {
149 // `GetStdHandle` isn't expected to actually fail, so when it returns
150 // `INVALID_HANDLE_VALUE`, it means we were launched from a parent which
151 // didn't provide us with stdio handles, such as a parent with a detached
152 // console. In that case, return null to the user, which is consistent
153 // with what they'd get in the parent, and which avoids the problem that
154 // `INVALID_HANDLE_VALUE` aliases the current process handle.
155 if raw == c::INVALID_HANDLE_VALUE { ptr::null_mut() } else { raw }
156 }
157
158 #[stable(feature = "from_raw_os", since = "1.1.0")]
159 impl FromRawHandle for fs::File {
160 #[inline]
161 unsafe fn from_raw_handle(handle: RawHandle) -> fs::File {
162 let handle = handle as c::HANDLE;
163 fs::File::from_inner(sys::fs::File::from_inner(FromInner::from_inner(
164 OwnedHandle::from_raw_handle(handle),
165 )))
166 }
167 }
168
169 #[stable(feature = "into_raw_os", since = "1.4.0")]
170 impl IntoRawHandle for fs::File {
171 #[inline]
172 fn into_raw_handle(self) -> RawHandle {
173 self.into_inner().into_raw_handle() as *mut _
174 }
175 }
176
177 /// Extracts raw sockets.
178 #[stable(feature = "rust1", since = "1.0.0")]
179 pub trait AsRawSocket {
180 /// Extracts the raw socket.
181 ///
182 /// This function is typically used to **borrow** an owned socket.
183 /// When used in this way, this method does **not** pass ownership of the
184 /// raw socket to the caller, and the socket is only guaranteed
185 /// to be valid while the original object has not yet been destroyed.
186 ///
187 /// However, borrowing is not strictly required. See [`AsSocket::as_socket`]
188 /// for an API which strictly borrows a socket.
189 #[stable(feature = "rust1", since = "1.0.0")]
190 fn as_raw_socket(&self) -> RawSocket;
191 }
192
193 /// Creates I/O objects from raw sockets.
194 #[stable(feature = "from_raw_os", since = "1.1.0")]
195 pub trait FromRawSocket {
196 /// Constructs a new I/O object from the specified raw socket.
197 ///
198 /// This function is typically used to **consume ownership** of the socket
199 /// given, passing responsibility for closing the socket to the returned
200 /// object. When used in this way, the returned object
201 /// will take responsibility for closing it when the object goes out of
202 /// scope.
203 ///
204 /// However, consuming ownership is not strictly required. Use a
205 /// `From<OwnedSocket>::from` implementation for an API which strictly
206 /// consumes ownership.
207 ///
208 /// # Safety
209 ///
210 /// The `socket` passed in must:
211 /// - be a valid an open socket,
212 /// - be a socket that may be freed via [`closesocket`].
213 ///
214 /// [`closesocket`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-closesocket
215 #[stable(feature = "from_raw_os", since = "1.1.0")]
216 unsafe fn from_raw_socket(sock: RawSocket) -> Self;
217 }
218
219 /// A trait to express the ability to consume an object and acquire ownership of
220 /// its raw `SOCKET`.
221 #[stable(feature = "into_raw_os", since = "1.4.0")]
222 pub trait IntoRawSocket {
223 /// Consumes this object, returning the raw underlying socket.
224 ///
225 /// This function is typically used to **transfer ownership** of the underlying
226 /// socket to the caller. When used in this way, callers are then the unique
227 /// owners of the socket and must close it once it's no longer needed.
228 ///
229 /// However, transferring ownership is not strictly required. Use a
230 /// `Into<OwnedSocket>::into` implementation for an API which strictly
231 /// transfers ownership.
232 #[stable(feature = "into_raw_os", since = "1.4.0")]
233 fn into_raw_socket(self) -> RawSocket;
234 }
235
236 #[stable(feature = "rust1", since = "1.0.0")]
237 impl AsRawSocket for net::TcpStream {
238 #[inline]
239 fn as_raw_socket(&self) -> RawSocket {
240 self.as_inner().socket().as_raw_socket()
241 }
242 }
243 #[stable(feature = "rust1", since = "1.0.0")]
244 impl AsRawSocket for net::TcpListener {
245 #[inline]
246 fn as_raw_socket(&self) -> RawSocket {
247 self.as_inner().socket().as_raw_socket()
248 }
249 }
250 #[stable(feature = "rust1", since = "1.0.0")]
251 impl AsRawSocket for net::UdpSocket {
252 #[inline]
253 fn as_raw_socket(&self) -> RawSocket {
254 self.as_inner().socket().as_raw_socket()
255 }
256 }
257
258 #[stable(feature = "from_raw_os", since = "1.1.0")]
259 impl FromRawSocket for net::TcpStream {
260 #[inline]
261 unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
262 let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock));
263 net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(sock))
264 }
265 }
266 #[stable(feature = "from_raw_os", since = "1.1.0")]
267 impl FromRawSocket for net::TcpListener {
268 #[inline]
269 unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpListener {
270 let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock));
271 net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(sock))
272 }
273 }
274 #[stable(feature = "from_raw_os", since = "1.1.0")]
275 impl FromRawSocket for net::UdpSocket {
276 #[inline]
277 unsafe fn from_raw_socket(sock: RawSocket) -> net::UdpSocket {
278 let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock));
279 net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(sock))
280 }
281 }
282
283 #[stable(feature = "into_raw_os", since = "1.4.0")]
284 impl IntoRawSocket for net::TcpStream {
285 #[inline]
286 fn into_raw_socket(self) -> RawSocket {
287 self.into_inner().into_socket().into_inner().into_raw_socket()
288 }
289 }
290
291 #[stable(feature = "into_raw_os", since = "1.4.0")]
292 impl IntoRawSocket for net::TcpListener {
293 #[inline]
294 fn into_raw_socket(self) -> RawSocket {
295 self.into_inner().into_socket().into_inner().into_raw_socket()
296 }
297 }
298
299 #[stable(feature = "into_raw_os", since = "1.4.0")]
300 impl IntoRawSocket for net::UdpSocket {
301 #[inline]
302 fn into_raw_socket(self) -> RawSocket {
303 self.into_inner().into_socket().into_inner().into_raw_socket()
304 }
305 }