1 //! Windows-specific extensions to general I/O primitives.
3 #![stable(feature = "rust1", since = "1.0.0")]
9 use crate::os
::windows
::io
::{AsHandle, AsSocket}
;
10 use crate::os
::windows
::io
::{OwnedHandle, OwnedSocket}
;
11 use crate::os
::windows
::raw
;
15 use crate::sys_common
::{self, AsInner, FromInner, IntoInner}
;
18 #[stable(feature = "rust1", since = "1.0.0")]
19 pub type RawHandle
= raw
::HANDLE
;
22 #[stable(feature = "rust1", since = "1.0.0")]
23 pub type RawSocket
= raw
::SOCKET
;
25 /// Extracts raw handles.
26 #[stable(feature = "rust1", since = "1.0.0")]
27 pub trait AsRawHandle
{
28 /// Extracts the raw handle.
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.
35 /// This function may return null, such as when called on [`Stdin`],
36 /// [`Stdout`], or [`Stderr`] when the console is detached.
38 /// However, borrowing is not strictly required. See [`AsHandle::as_handle`]
39 /// for an API which strictly borrows a handle.
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
;
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.
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
59 /// However, consuming ownership is not strictly required. Use a
60 /// `From<OwnedHandle>::from` implementation for an API which strictly
61 /// consumes ownership.
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).
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.
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;
79 /// A trait to express the ability to consume an object and acquire ownership of
81 #[stable(feature = "into_raw_os", since = "1.4.0")]
82 pub trait IntoRawHandle
{
83 /// Consumes this object, returning the raw underlying handle.
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.
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
;
96 #[stable(feature = "rust1", since = "1.0.0")]
97 impl AsRawHandle
for fs
::File
{
99 fn as_raw_handle(&self) -> RawHandle
{
100 self.as_inner().as_raw_handle() as RawHandle
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 }
)
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 }
)
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 }
)
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 }
)
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 }
)
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 }
)
146 // Translate a handle returned from `GetStdHandle` into a handle to return to
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 }
158 #[stable(feature = "from_raw_os", since = "1.1.0")]
159 impl FromRawHandle
for fs
::File
{
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
),
169 #[stable(feature = "into_raw_os", since = "1.4.0")]
170 impl IntoRawHandle
for fs
::File
{
172 fn into_raw_handle(self) -> RawHandle
{
173 self.into_inner().into_raw_handle() as *mut _
177 /// Extracts raw sockets.
178 #[stable(feature = "rust1", since = "1.0.0")]
179 pub trait AsRawSocket
{
180 /// Extracts the raw socket.
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.
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
;
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.
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
204 /// However, consuming ownership is not strictly required. Use a
205 /// `From<OwnedSocket>::from` implementation for an API which strictly
206 /// consumes ownership.
210 /// The `socket` passed in must:
211 /// - be a valid an open socket,
212 /// - be a socket that may be freed via [`closesocket`].
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;
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.
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.
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
;
236 #[stable(feature = "rust1", since = "1.0.0")]
237 impl AsRawSocket
for net
::TcpStream
{
239 fn as_raw_socket(&self) -> RawSocket
{
240 self.as_inner().socket().as_raw_socket()
243 #[stable(feature = "rust1", since = "1.0.0")]
244 impl AsRawSocket
for net
::TcpListener
{
246 fn as_raw_socket(&self) -> RawSocket
{
247 self.as_inner().socket().as_raw_socket()
250 #[stable(feature = "rust1", since = "1.0.0")]
251 impl AsRawSocket
for net
::UdpSocket
{
253 fn as_raw_socket(&self) -> RawSocket
{
254 self.as_inner().socket().as_raw_socket()
258 #[stable(feature = "from_raw_os", since = "1.1.0")]
259 impl FromRawSocket
for net
::TcpStream
{
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
))
266 #[stable(feature = "from_raw_os", since = "1.1.0")]
267 impl FromRawSocket
for net
::TcpListener
{
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
))
274 #[stable(feature = "from_raw_os", since = "1.1.0")]
275 impl FromRawSocket
for net
::UdpSocket
{
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
))
283 #[stable(feature = "into_raw_os", since = "1.4.0")]
284 impl IntoRawSocket
for net
::TcpStream
{
286 fn into_raw_socket(self) -> RawSocket
{
287 self.into_inner().into_socket().into_inner().into_raw_socket()
291 #[stable(feature = "into_raw_os", since = "1.4.0")]
292 impl IntoRawSocket
for net
::TcpListener
{
294 fn into_raw_socket(self) -> RawSocket
{
295 self.into_inner().into_socket().into_inner().into_raw_socket()
299 #[stable(feature = "into_raw_os", since = "1.4.0")]
300 impl IntoRawSocket
for net
::UdpSocket
{
302 fn into_raw_socket(self) -> RawSocket
{
303 self.into_inner().into_socket().into_inner().into_raw_socket()