about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorDan Gohman <dev@sunfishcode.online>2022-01-21 12:43:07 -0800
committerDan Gohman <dev@sunfishcode.online>2022-03-04 05:09:38 -0800
commitee02f01ea6caa0dd56393012aa84ca4d09549702 (patch)
tree6c582901d275881e11a935855fe6f6ea0df6fc4a /library/std/src/sys
parent62ff2bcf9485f52050093d1780f409d50953549b (diff)
downloadrust-ee02f01ea6caa0dd56393012aa84ca4d09549702.tar.gz
rust-ee02f01ea6caa0dd56393012aa84ca4d09549702.zip
Consistently present absent stdio handles on Windows as NULL handles.
This addresses #90964 by making the std API consistent about presenting
absent stdio handles on Windows as NULL handles. Stdio handles may be
absent due to `#![windows_subsystem = "windows"]`, due to the console
being detached, or due to a child process having been launched from a
parent where stdio handles are absent.

Specifically, this fixes the case of child processes of parents with absent
stdio, which previously ended up with `stdin().as_raw_handle()` returning
`INVALID_HANDLE_VALUE`, which was surprising, and which overlapped with an
unrelated valid handle value. With this patch, `stdin().as_raw_handle()`
now returns null in these situation, which is consistent with what it
does in the parent process.

And, document this in the "Windows Portability Considerations" sections of
the relevant documentation.
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/windows/process.rs13
1 files changed, 13 insertions, 0 deletions
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index fafd1412d4c..ec53c46cd7b 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -309,6 +309,19 @@ impl Command {
         si.hStdOutput = stdout.as_raw_handle();
         si.hStdError = stderr.as_raw_handle();
 
+        // `CreateProcessW` fails with `ERROR_FILE_NOT_FOUND` if any of the
+        // stdio handles are null, so if we have null handles, set them to
+        // `INVALID_HANDLE_VALUE`.
+        if si.hStdInput.is_null() {
+            si.hStdInput = c::INVALID_HANDLE_VALUE;
+        }
+        if si.hStdOutput.is_null() {
+            si.hStdOutput = c::INVALID_HANDLE_VALUE;
+        }
+        if si.hStdError.is_null() {
+            si.hStdError = c::INVALID_HANDLE_VALUE;
+        }
+
         let program = to_u16s(&program)?;
         unsafe {
             cvt(c::CreateProcessW(