Skip to content

Commit f38b7ff

Browse files
authored
Rollup merge of #96932 - sunfishcode:sunfishcode/document-borrowed-handle, r=joshtriplett
Clarify what values `BorrowedHandle`, `OwnedHandle` etc. can hold. Reword the documentation to clarify that when `BorrowedHandle`, `OwnedHandle`, or `HandleOrNull` hold the value `-1`, it always means the current process handle, and not `INVALID_HANDLE_VALUE`. `-1` should only mean `INVALID_HANDLE_VALUE` after a call to a function documented to return that to report errors, which should lead I/O functions to produce errors rather than succeeding and producing `OwnedHandle` or `BorrowedHandle` values. So if a consumer of an `OwnedHandle` or `BorrowedHandle` ever sees them holding a `-1`, it should always mean the current process handle.
2 parents ebb80ec + 275812a commit f38b7ff

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

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

+19-12
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
2222
/// so it can be used in FFI in places where a handle is passed as an argument,
2323
/// it is not captured or consumed.
2424
///
25-
/// Note that it *may* have the value `INVALID_HANDLE_VALUE` (-1), which is
26-
/// sometimes a valid handle value. See [here] for the full story.
25+
/// Note that it *may* have the value `-1`, which in `BorrowedHandle` always
26+
/// represents a valid handle value, such as [the current process handle], and
27+
/// not `INVALID_HANDLE_VALUE`, despite the two having the same value. See
28+
/// [here] for the full story.
2729
///
2830
/// And, it *may* have the value `NULL` (0), which can occur when consoles are
2931
/// detached from processes, or when `windows_subsystem` is used.
@@ -33,6 +35,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
3335
/// handle, which is then borrowed under the same lifetime.
3436
///
3537
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
38+
/// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
3639
#[derive(Copy, Clone)]
3740
#[repr(transparent)]
3841
#[unstable(feature = "io_safety", issue = "87074")]
@@ -45,8 +48,10 @@ pub struct BorrowedHandle<'handle> {
4548
///
4649
/// This closes the handle on drop.
4750
///
48-
/// Note that it *may* have the value `INVALID_HANDLE_VALUE` (-1), which is
49-
/// sometimes a valid handle value. See [here] for the full story.
51+
/// Note that it *may* have the value `-1`, which in `OwnedHandle` always
52+
/// represents a valid handle value, such as [the current process handle], and
53+
/// not `INVALID_HANDLE_VALUE`, despite the two having the same value. See
54+
/// [here] for the full story.
5055
///
5156
/// And, it *may* have the value `NULL` (0), which can occur when consoles are
5257
/// detached from processes, or when `windows_subsystem` is used.
@@ -59,6 +64,7 @@ pub struct BorrowedHandle<'handle> {
5964
/// [`RegCloseKey`]: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regclosekey
6065
///
6166
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
67+
/// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
6268
#[repr(transparent)]
6369
#[unstable(feature = "io_safety", issue = "87074")]
6470
pub struct OwnedHandle {
@@ -75,11 +81,13 @@ pub struct OwnedHandle {
7581
/// `NULL`. This ensures that such FFI calls cannot start using the handle without
7682
/// checking for `NULL` first.
7783
///
78-
/// This type considers any value other than `NULL` to be valid, including `INVALID_HANDLE_VALUE`.
79-
/// This is because APIs that use `NULL` as their sentry value don't treat `INVALID_HANDLE_VALUE`
80-
/// as special.
84+
/// This type may hold any handle value that [`OwnedHandle`] may hold. As with `OwnedHandle`, when
85+
/// it holds `-1`, that value is interpreted as a valid handle value, such as
86+
/// [the current process handle], and not `INVALID_HANDLE_VALUE`.
8187
///
82-
/// If this holds a valid handle, it will close the handle on drop.
88+
/// If this holds a non-null handle, it will close the handle on drop.
89+
///
90+
/// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
8391
#[repr(transparent)]
8492
#[unstable(feature = "io_safety", issue = "87074")]
8593
#[derive(Debug)]
@@ -95,11 +103,10 @@ pub struct HandleOrNull(OwnedHandle);
95103
/// `INVALID_HANDLE_VALUE`. This ensures that such FFI calls cannot start using the handle without
96104
/// checking for `INVALID_HANDLE_VALUE` first.
97105
///
98-
/// This type considers any value other than `INVALID_HANDLE_VALUE` to be valid, including `NULL`.
99-
/// This is because APIs that use `INVALID_HANDLE_VALUE` as their sentry value may return `NULL`
100-
/// under `windows_subsystem = "windows"` or other situations where I/O devices are detached.
106+
/// This type may hold any handle value that [`OwnedHandle`] may hold, except that when it holds
107+
/// `-1`, that value is interpreted to mean `INVALID_HANDLE_VALUE`.
101108
///
102-
/// If this holds a valid handle, it will close the handle on drop.
109+
/// If holds a handle other than `INVALID_HANDLE_VALUE`, it will close the handle on drop.
103110
#[repr(transparent)]
104111
#[unstable(feature = "io_safety", issue = "87074")]
105112
#[derive(Debug)]

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

+7
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,15 @@ pub trait AsRawHandle {
3232
/// raw handle to the caller, and the handle is only guaranteed
3333
/// to be valid while the original object has not yet been destroyed.
3434
///
35+
/// This function may return null, such as when called on [`Stdin`],
36+
/// [`Stdout`], or [`Stderr`] when the console is detached.
37+
///
3538
/// However, borrowing is not strictly required. See [`AsHandle::as_handle`]
3639
/// for an API which strictly borrows a handle.
40+
///
41+
/// [`Stdin`]: io::Stdin
42+
/// [`Stdout`]: io::Stdout
43+
/// [`Stderr`]: io::Stderr
3744
#[stable(feature = "rust1", since = "1.0.0")]
3845
fn as_raw_handle(&self) -> RawHandle;
3946
}

0 commit comments

Comments
 (0)