Skip to content

Commit 0ef06e7

Browse files
authored
Rollup merge of rust-lang#93562 - sunfishcode:sunfishcode/io-docs, r=joshtriplett
Update the documentation for `{As,Into,From}Raw{Fd,Handle,Socket}`. This change weakens the descriptions of the `{as,into,from}_raw_{fd,handle,socket}` descriptions from saying that they *do* express ownership relations to say that they are *typically used* in ways that express ownership relations. This is needed since, for example, std's own [`RawFd`] implements `{As,From,Into}Fd` without any of the ownership relationships. This adds proper `# Safety` comments to `from_raw_{fd,handle,socket}`, adds the requirement that raw handles be not opened with the `FILE_FLAG_OVERLAPPED` flag, and merges the `OwnedHandle::from_raw_handle` comment into the main `FromRawHandle::from_raw_handle` comment. And, this changes `HandleOrNull` and `HandleOrInvalid` to not implement `FromRawHandle`, since they are intended for limited use in FFI situations, and not for generic use, and they have constraints that are stronger than the those of `FromRawHandle`. [`RawFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/type.RawFd.html
2 parents 0d6881c + ba6050f commit 0ef06e7

File tree

4 files changed

+115
-72
lines changed

4 files changed

+115
-72
lines changed

library/std/src/os/fd/raw.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
use crate::fs;
66
use crate::io;
77
use crate::os::raw;
8+
#[cfg(all(doc, unix))]
9+
use crate::os::unix::io::AsFd;
10+
#[cfg(all(doc, target_os = "wasi"))]
11+
use crate::os::unix::io::AsFd;
812
#[cfg(unix)]
913
use crate::os::unix::io::OwnedFd;
1014
#[cfg(target_os = "wasi")]
@@ -24,9 +28,14 @@ pub type RawFd = raw::c_int;
2428
pub trait AsRawFd {
2529
/// Extracts the raw file descriptor.
2630
///
27-
/// This method does **not** pass ownership of the raw file descriptor
28-
/// to the caller. The descriptor is only guaranteed to be valid while
29-
/// the original object has not yet been destroyed.
31+
/// This function is typically used to **borrow** an owned file descriptor.
32+
/// When used in this way, this method does **not** pass ownership of the
33+
/// raw file descriptor to the caller, and the file descriptor is only
34+
/// guaranteed to be valid while the original object has not yet been
35+
/// destroyed.
36+
///
37+
/// However, borrowing is not strictly required. See [`AsFd::as_fd`]
38+
/// for an API which strictly borrows a file descriptor.
3039
///
3140
/// # Example
3241
///
@@ -55,15 +64,18 @@ pub trait FromRawFd {
5564
/// Constructs a new instance of `Self` from the given raw file
5665
/// descriptor.
5766
///
58-
/// This function **consumes ownership** of the specified file
59-
/// descriptor. The returned object will take responsibility for closing
60-
/// it when the object goes out of scope.
67+
/// This function is typically used to **consume ownership** of the
68+
/// specified file descriptor. When used in this way, the returned object
69+
/// will take responsibility for closing it when the object goes out of
70+
/// scope.
71+
///
72+
/// However, consuming ownership is not strictly required. Use a
73+
/// [`From<OwnedFd>::from`] implementation for an API which strictly
74+
/// consumes ownership.
6175
///
62-
/// This function is also unsafe as the primitives currently returned
63-
/// have the contract that they are the sole owner of the file
64-
/// descriptor they are wrapping. Usage of this function could
65-
/// accidentally allow violating this contract which can cause memory
66-
/// unsafety in code that relies on it being true.
76+
/// # Safety
77+
///
78+
/// The `fd` passed in must be a valid an open file descriptor.
6779
///
6880
/// # Example
6981
///
@@ -94,9 +106,13 @@ pub trait FromRawFd {
94106
pub trait IntoRawFd {
95107
/// Consumes this object, returning the raw underlying file descriptor.
96108
///
97-
/// This function **transfers ownership** of the underlying file descriptor
98-
/// to the caller. Callers are then the unique owners of the file descriptor
99-
/// and must close the descriptor once it's no longer needed.
109+
/// This function is typically used to **transfer ownership** of the underlying
110+
/// file descriptor to the caller. When used in this way, callers are then the unique
111+
/// owners of the file descriptor and must close it once it's no longer needed.
112+
///
113+
/// However, transferring ownership is not strictly required. Use a
114+
/// [`Into<OwnedFd>::into`] implementation for an API which strictly
115+
/// transfers ownership.
100116
///
101117
/// # Example
102118
///

library/std/src/os/windows/io/handle.rs

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -214,29 +214,13 @@ impl IntoRawHandle for OwnedHandle {
214214
}
215215

216216
impl FromRawHandle for OwnedHandle {
217-
/// Constructs a new instance of `Self` from the given raw handle.
218-
///
219-
/// # Safety
220-
///
221-
/// The resource pointed to by `handle` must be open and suitable for
222-
/// assuming ownership. The resource must not require any cleanup other
223-
/// than `CloseHandle`.
224-
///
225-
/// In particular, it must not be used with handles to open registry
226-
/// keys which need to be closed with [`RegCloseKey`] instead.
227-
///
228-
/// Note that it *may* have the value `INVALID_HANDLE_VALUE` (-1), which is
229-
/// sometimes a valid handle value. See [here] for the full story.
230-
///
231-
/// [`RegCloseKey`]: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regclosekey
232-
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
233217
#[inline]
234218
unsafe fn from_raw_handle(handle: RawHandle) -> Self {
235219
Self { handle }
236220
}
237221
}
238222

239-
impl FromRawHandle for HandleOrNull {
223+
impl HandleOrNull {
240224
/// Constructs a new instance of `Self` from the given `RawHandle` returned
241225
/// from a Windows API that uses null to indicate failure, such as
242226
/// `CreateThread`.
@@ -246,18 +230,18 @@ impl FromRawHandle for HandleOrNull {
246230
///
247231
/// # Safety
248232
///
249-
/// The resource pointed to by `handle` must be either open and otherwise
250-
/// unowned, or null. Note that not all Windows APIs use null for errors;
251-
/// see [here] for the full story.
233+
/// The passed `handle` value must either satisfy the safety requirements
234+
/// of [`FromRawHandle::from_raw_handle`], or be null. Note that not all
235+
/// Windows APIs use null for errors; see [here] for the full story.
252236
///
253237
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
254238
#[inline]
255-
unsafe fn from_raw_handle(handle: RawHandle) -> Self {
239+
pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
256240
Self(OwnedHandle::from_raw_handle(handle))
257241
}
258242
}
259243

260-
impl FromRawHandle for HandleOrInvalid {
244+
impl HandleOrInvalid {
261245
/// Constructs a new instance of `Self` from the given `RawHandle` returned
262246
/// from a Windows API that uses `INVALID_HANDLE_VALUE` to indicate
263247
/// failure, such as `CreateFileW`.
@@ -267,14 +251,14 @@ impl FromRawHandle for HandleOrInvalid {
267251
///
268252
/// # Safety
269253
///
270-
/// The resource pointed to by `handle` must be either open and otherwise
271-
/// unowned, null, or equal to `INVALID_HANDLE_VALUE` (-1). Note that not
272-
/// all Windows APIs use `INVALID_HANDLE_VALUE` for errors; see [here] for
273-
/// the full story.
254+
/// The passed `handle` value must either satisfy the safety requirements
255+
/// of [`FromRawHandle::from_raw_handle`], or be
256+
/// `INVALID_HANDLE_VALUE` (-1). Note that not all Windows APIs use
257+
/// `INVALID_HANDLE_VALUE` for errors; see [here] for the full story.
274258
///
275259
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
276260
#[inline]
277-
unsafe fn from_raw_handle(handle: RawHandle) -> Self {
261+
pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
278262
Self(OwnedHandle::from_raw_handle(handle))
279263
}
280264
}

library/std/src/os/windows/io/raw.rs

Lines changed: 74 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
use crate::fs;
66
use crate::io;
77
use crate::net;
8+
#[cfg(doc)]
9+
use crate::os::windows::io::{AsHandle, AsSocket};
810
use crate::os::windows::io::{OwnedHandle, OwnedSocket};
911
use crate::os::windows::raw;
1012
use crate::sys;
@@ -22,7 +24,15 @@ pub type RawSocket = raw::SOCKET;
2224
/// Extracts raw handles.
2325
#[stable(feature = "rust1", since = "1.0.0")]
2426
pub trait AsRawHandle {
25-
/// Extracts the raw handle, without taking any ownership.
27+
/// Extracts the raw handle.
28+
///
29+
/// This function is typically used to **borrow** an owned handle.
30+
/// When used in this way, this method does **not** pass ownership of the
31+
/// raw handle to the caller, and the handle is only guaranteed
32+
/// to be valid while the original object has not yet been destroyed.
33+
///
34+
/// However, borrowing is not strictly required. See [`AsHandle::as_handle`]
35+
/// for an API which strictly borrows a handle.
2636
#[stable(feature = "rust1", since = "1.0.0")]
2737
fn as_raw_handle(&self) -> RawHandle;
2838
}
@@ -32,15 +42,30 @@ pub trait AsRawHandle {
3242
pub trait FromRawHandle {
3343
/// Constructs a new I/O object from the specified raw handle.
3444
///
35-
/// This function will **consume ownership** of the handle given,
36-
/// passing responsibility for closing the handle to the returned
37-
/// object.
45+
/// This function is typically used to **consume ownership** of the handle
46+
/// given, passing responsibility for closing the handle to the returned
47+
/// object. When used in this way, the returned object
48+
/// will take responsibility for closing it when the object goes out of
49+
/// scope.
50+
///
51+
/// However, consuming ownership is not strictly required. Use a
52+
/// `From<OwnedHandle>::from` implementation for an API which strictly
53+
/// consumes ownership.
54+
///
55+
/// # Safety
3856
///
39-
/// This function is also unsafe as the primitives currently returned
40-
/// have the contract that they are the sole owner of the file
41-
/// descriptor they are wrapping. Usage of this function could
42-
/// accidentally allow violating this contract which can cause memory
43-
/// unsafety in code that relies on it being true.
57+
/// The `handle` passed in must:
58+
/// - be a valid an open handle,
59+
/// - be a handle opened for synchronous I/O, *without* the
60+
/// `FILE_FLAG_OVERLAPPED` flag, and
61+
/// - be a handle for a resource that may be freed via [`CloseHandle`]
62+
/// (as opposed to `RegCloseKey` or other close functions).
63+
///
64+
/// Note that the handle *may* have the value `INVALID_HANDLE_VALUE` (-1),
65+
/// which is sometimes a valid handle value. See [here] for the full story.
66+
///
67+
/// [`CloseHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle
68+
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
4469
#[stable(feature = "from_raw_os", since = "1.1.0")]
4570
unsafe fn from_raw_handle(handle: RawHandle) -> Self;
4671
}
@@ -51,9 +76,13 @@ pub trait FromRawHandle {
5176
pub trait IntoRawHandle {
5277
/// Consumes this object, returning the raw underlying handle.
5378
///
54-
/// This function **transfers ownership** of the underlying handle to the
55-
/// caller. Callers are then the unique owners of the handle and must close
56-
/// it once it's no longer needed.
79+
/// This function is typically used to **transfer ownership** of the underlying
80+
/// handle to the caller. When used in this way, callers are then the unique
81+
/// owners of the handle and must close it once it's no longer needed.
82+
///
83+
/// However, transferring ownership is not strictly required. Use a
84+
/// `Into<OwnedHandle>::into` implementation for an API which strictly
85+
/// transfers ownership.
5786
#[stable(feature = "into_raw_os", since = "1.4.0")]
5887
fn into_raw_handle(self) -> RawHandle;
5988
}
@@ -130,24 +159,41 @@ impl IntoRawHandle for fs::File {
130159
/// Extracts raw sockets.
131160
#[stable(feature = "rust1", since = "1.0.0")]
132161
pub trait AsRawSocket {
133-
/// Extracts the underlying raw socket from this object.
162+
/// Extracts the raw socket.
163+
///
164+
/// This function is typically used to **borrow** an owned socket.
165+
/// When used in this way, this method does **not** pass ownership of the
166+
/// raw socket to the caller, and the socket is only guaranteed
167+
/// to be valid while the original object has not yet been destroyed.
168+
///
169+
/// However, borrowing is not strictly required. See [`AsSocket::as_socket`]
170+
/// for an API which strictly borrows a socket.
134171
#[stable(feature = "rust1", since = "1.0.0")]
135172
fn as_raw_socket(&self) -> RawSocket;
136173
}
137174

138175
/// Creates I/O objects from raw sockets.
139176
#[stable(feature = "from_raw_os", since = "1.1.0")]
140177
pub trait FromRawSocket {
141-
/// Creates a new I/O object from the given raw socket.
178+
/// Constructs a new I/O object from the specified raw socket.
179+
///
180+
/// This function is typically used to **consume ownership** of the socket
181+
/// given, passing responsibility for closing the socket to the returned
182+
/// object. When used in this way, the returned object
183+
/// will take responsibility for closing it when the object goes out of
184+
/// scope.
142185
///
143-
/// This function will **consume ownership** of the socket provided and
144-
/// it will be closed when the returned object goes out of scope.
186+
/// However, consuming ownership is not strictly required. Use a
187+
/// `From<OwnedSocket>::from` implementation for an API which strictly
188+
/// consumes ownership.
145189
///
146-
/// This function is also unsafe as the primitives currently returned
147-
/// have the contract that they are the sole owner of the file
148-
/// descriptor they are wrapping. Usage of this function could
149-
/// accidentally allow violating this contract which can cause memory
150-
/// unsafety in code that relies on it being true.
190+
/// # Safety
191+
///
192+
/// The `socket` passed in must:
193+
/// - be a valid an open socket,
194+
/// - be a socket that may be freed via [`closesocket`].
195+
///
196+
/// [`closesocket`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-closesocket
151197
#[stable(feature = "from_raw_os", since = "1.1.0")]
152198
unsafe fn from_raw_socket(sock: RawSocket) -> Self;
153199
}
@@ -158,9 +204,13 @@ pub trait FromRawSocket {
158204
pub trait IntoRawSocket {
159205
/// Consumes this object, returning the raw underlying socket.
160206
///
161-
/// This function **transfers ownership** of the underlying socket to the
162-
/// caller. Callers are then the unique owners of the socket and must close
163-
/// it once it's no longer needed.
207+
/// This function is typically used to **transfer ownership** of the underlying
208+
/// socket to the caller. When used in this way, callers are then the unique
209+
/// owners of the socket and must close it once it's no longer needed.
210+
///
211+
/// However, transferring ownership is not strictly required. Use a
212+
/// `Into<OwnedSocket>::into` implementation for an API which strictly
213+
/// transfers ownership.
164214
#[stable(feature = "into_raw_os", since = "1.4.0")]
165215
fn into_raw_socket(self) -> RawSocket;
166216
}

library/std/src/os/windows/io/socket.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,6 @@ impl IntoRawSocket for OwnedSocket {
172172
}
173173

174174
impl FromRawSocket for OwnedSocket {
175-
/// Constructs a new instance of `Self` from the given raw socket.
176-
///
177-
/// # Safety
178-
///
179-
/// The resource pointed to by `socket` must be open and suitable for
180-
/// assuming ownership. The resource must not require cleanup other than
181-
/// `closesocket`.
182175
#[inline]
183176
unsafe fn from_raw_socket(socket: RawSocket) -> Self {
184177
debug_assert_ne!(socket, c::INVALID_SOCKET as RawSocket);

0 commit comments

Comments
 (0)