Skip to content

Commit ca42a1b

Browse files
committed
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 needed 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
1 parent ad88831 commit ca42a1b

File tree

3 files changed

+101
-63
lines changed

3 files changed

+101
-63
lines changed

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

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,14 @@ pub type RawFd = raw::c_int;
2424
pub trait AsRawFd {
2525
/// Extracts the raw file descriptor.
2626
///
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.
27+
/// This function is typically used to **borrow** an owned file descriptor.
28+
/// When used in this way, this method does **not** pass ownership of the
29+
/// raw file descriptor to the caller, and the file descriptor is only
30+
/// guaranteed to be valid while the original object has not yet been
31+
/// destroyed.
32+
///
33+
/// However, borrowing is not strictly required. See [`AsFd::as_fd`]
34+
/// for an API which strictly borrows a handle.
3035
///
3136
/// # Example
3237
///
@@ -55,15 +60,17 @@ pub trait FromRawFd {
5560
/// Constructs a new instance of `Self` from the given raw file
5661
/// descriptor.
5762
///
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.
63+
/// This function is typically used to **consume ownership** of the
64+
/// specified file descriptor. When used in this way, the returned object
65+
/// will take responsibility for closing it when the object goes out of
66+
/// scope.
67+
///
68+
/// However, consuming ownership is not strictly required. See
69+
/// [`FromFd::from_fd`] for an API which strictly consumes ownership.
6170
///
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.
71+
/// # Safety
72+
///
73+
/// The `fd` passed in must be a valid an open file descriptor.
6774
///
6875
/// # Example
6976
///
@@ -94,9 +101,12 @@ pub trait FromRawFd {
94101
pub trait IntoRawFd {
95102
/// Consumes this object, returning the raw underlying file descriptor.
96103
///
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.
104+
/// This function is typically used to **transfer ownership** of the underlying
105+
/// file descriptor to the caller. When used in this way, callers are then the unique
106+
/// owners of the file descriptor and must close it once it's no longer needed.
107+
///
108+
/// However, transferring ownership is not strictly required. See
109+
/// [`IntoFd::into_fd`] for an API which strictly transfers ownership.
100110
///
101111
/// # Example
102112
///

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

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -210,29 +210,13 @@ impl IntoRawHandle for OwnedHandle {
210210
}
211211

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

235-
impl FromRawHandle for HandleOrNull {
219+
impl HandleOrNull {
236220
/// Constructs a new instance of `Self` from the given `RawHandle` returned
237221
/// from a Windows API that uses null to indicate failure, such as
238222
/// `CreateThread`.
@@ -242,9 +226,9 @@ impl FromRawHandle for HandleOrNull {
242226
///
243227
/// # Safety
244228
///
245-
/// The resource pointed to by `handle` must be either open and otherwise
246-
/// unowned, or null. Note that not all Windows APIs use null for errors;
247-
/// see [here] for the full story.
229+
/// The passed `handle` value must either satisfy the safety requirements
230+
/// of [`FromRawHandle::from_raw_handle`], or be null. Note that not all
231+
/// Windows APIs use null for errors; see [here] for the full story.
248232
///
249233
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
250234
#[inline]
@@ -253,7 +237,7 @@ impl FromRawHandle for HandleOrNull {
253237
}
254238
}
255239

256-
impl FromRawHandle for HandleOrInvalid {
240+
impl HandleOrInvalid {
257241
/// Constructs a new instance of `Self` from the given `RawHandle` returned
258242
/// from a Windows API that uses `INVALID_HANDLE_VALUE` to indicate
259243
/// failure, such as `CreateFileW`.
@@ -263,10 +247,10 @@ impl FromRawHandle for HandleOrInvalid {
263247
///
264248
/// # Safety
265249
///
266-
/// The resource pointed to by `handle` must be either open and otherwise
267-
/// unowned, null, or equal to `INVALID_HANDLE_VALUE` (-1). Note that not
268-
/// all Windows APIs use `INVALID_HANDLE_VALUE` for errors; see [here] for
269-
/// the full story.
250+
/// The passed `handle` value must either satisfy the safety requirements
251+
/// of [`FromRawHandle::from_raw_handle`], or be
252+
/// `INVALID_HANDLE_VALUE` (-1). Note that not all Windows APIs use
253+
/// `INVALID_HANDLE_VALUE` for errors; see [here] for the full story.
270254
///
271255
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
272256
#[inline]

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

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@ pub type RawSocket = raw::SOCKET;
2222
/// Extracts raw handles.
2323
#[stable(feature = "rust1", since = "1.0.0")]
2424
pub trait AsRawHandle {
25-
/// Extracts the raw handle, without taking any ownership.
25+
/// Extracts the raw handle.
26+
///
27+
/// This function is typically used to **borrow** an owned handle.
28+
/// When used in this way, this method does **not** pass ownership of the
29+
/// raw handle to the caller, and the handle is only guaranteed
30+
/// to be valid while the original object has not yet been destroyed.
31+
///
32+
/// However, borrowing is not strictly required. See [`AsHandle::as_handle`]
33+
/// for an API which strictly borrows a handle.
2634
#[stable(feature = "rust1", since = "1.0.0")]
2735
fn as_raw_handle(&self) -> RawHandle;
2836
}
@@ -32,15 +40,29 @@ pub trait AsRawHandle {
3240
pub trait FromRawHandle {
3341
/// Constructs a new I/O object from the specified raw handle.
3442
///
35-
/// This function will **consume ownership** of the handle given,
36-
/// passing responsibility for closing the handle to the returned
37-
/// object.
43+
/// This function is typically used to **consume ownership** of the handle
44+
/// given, passing responsibility for closing the handle to the returned
45+
/// object. When used in this way, the returned object
46+
/// will take responsibility for closing it when the object goes out of
47+
/// scope.
48+
///
49+
/// However, consuming ownership is not strictly required. See
50+
/// [`FromHandle::from_handle`] for an API which strictly consumes ownership.
51+
///
52+
/// # Safety
3853
///
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.
54+
/// The `handle` passed in must:
55+
/// - be a valid an open handle,
56+
/// - be a handle opened for synchronous I/O, *without* the
57+
/// `FILE_FLAG_OVERLAPPED` flag, and
58+
/// - be a handle for a resource that may be freed via [`CloseHandle`]
59+
/// (as opposed to `RegCloseKey` or other close functions).
60+
///
61+
/// Note that the handle *may* have the value `INVALID_HANDLE_VALUE` (-1),
62+
/// which is sometimes a valid handle value. See [here] for the full story.
63+
///
64+
/// [`CloseHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle
65+
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
4466
#[stable(feature = "from_raw_os", since = "1.1.0")]
4567
unsafe fn from_raw_handle(handle: RawHandle) -> Self;
4668
}
@@ -51,9 +73,12 @@ pub trait FromRawHandle {
5173
pub trait IntoRawHandle {
5274
/// Consumes this object, returning the raw underlying handle.
5375
///
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.
76+
/// This function is typically used to **transfer ownership** of the underlying
77+
/// handle to the caller. When used in this way, callers are then the unique
78+
/// owners of the handle and must close it once it's no longer needed.
79+
///
80+
/// However, transferring ownership is not strictly required. See
81+
/// [`IntoHandle::into_handle`] for an API which strictly transfers ownership.
5782
#[stable(feature = "into_raw_os", since = "1.4.0")]
5883
fn into_raw_handle(self) -> RawHandle;
5984
}
@@ -130,24 +155,40 @@ impl IntoRawHandle for fs::File {
130155
/// Extracts raw sockets.
131156
#[stable(feature = "rust1", since = "1.0.0")]
132157
pub trait AsRawSocket {
133-
/// Extracts the underlying raw socket from this object.
158+
/// Extracts the raw socket.
159+
///
160+
/// This function is typically used to **borrow** an owned socket.
161+
/// When used in this way, this method does **not** pass ownership of the
162+
/// raw socket to the caller, and the socket is only guaranteed
163+
/// to be valid while the original object has not yet been destroyed.
164+
///
165+
/// However, borrowing is not strictly required. See [`AsSocket::as_socket`]
166+
/// for an API which strictly borrows a socket.
134167
#[stable(feature = "rust1", since = "1.0.0")]
135168
fn as_raw_socket(&self) -> RawSocket;
136169
}
137170

138171
/// Creates I/O objects from raw sockets.
139172
#[stable(feature = "from_raw_os", since = "1.1.0")]
140173
pub trait FromRawSocket {
141-
/// Creates a new I/O object from the given raw socket.
174+
/// Constructs a new I/O object from the specified raw socket.
175+
///
176+
/// This function is typically used to **consume ownership** of the socket
177+
/// given, passing responsibility for closing the socket to the returned
178+
/// object. When used in this way, the returned object
179+
/// will take responsibility for closing it when the object goes out of
180+
/// scope.
142181
///
143-
/// This function will **consume ownership** of the socket provided and
144-
/// it will be closed when the returned object goes out of scope.
182+
/// However, consuming ownership is not strictly required. See
183+
/// [`FromSocket::from_socket`] for an API which strictly consumes ownership.
145184
///
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.
185+
/// # Safety
186+
///
187+
/// The `socket` passed in must:
188+
/// - be a valid an open socket,
189+
/// - be a handle for a resource that may be freed via [`closesocket`].
190+
///
191+
/// [`closesocket`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-closesocket
151192
#[stable(feature = "from_raw_os", since = "1.1.0")]
152193
unsafe fn from_raw_socket(sock: RawSocket) -> Self;
153194
}
@@ -158,9 +199,12 @@ pub trait FromRawSocket {
158199
pub trait IntoRawSocket {
159200
/// Consumes this object, returning the raw underlying socket.
160201
///
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.
202+
/// This function is typically used to **transfer ownership** of the underlying
203+
/// socket to the caller. When used in this way, callers are then the unique
204+
/// owners of the socket and must close it once it's no longer needed.
205+
///
206+
/// However, transferring ownership is not strictly required. See
207+
/// [`IntoSocket::into_socket`] for an API which strictly transfers ownership.
164208
#[stable(feature = "into_raw_os", since = "1.4.0")]
165209
fn into_raw_socket(self) -> RawSocket;
166210
}

0 commit comments

Comments
 (0)