about summary refs log tree commit diff
path: root/library/std
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-03-22 05:48:49 +0000
committerbors <bors@rust-lang.org>2022-03-22 05:48:49 +0000
commitb9c406741780945de12aa0e3b2c8ccd99a5e6316 (patch)
treefae0a9a614795162cf68b0b687a683999d62f6d9 /library/std
parent2d15732f6eec3d50ed1ad4a79c36b07d8b896474 (diff)
parent6c407d0592288d3890d45590466b80a364f42982 (diff)
downloadrust-b9c406741780945de12aa0e3b2c8ccd99a5e6316.tar.gz
rust-b9c406741780945de12aa0e3b2c8ccd99a5e6316.zip
Auto merge of #95158 - sunfishcode:sunfishcode/windows-8, r=joshtriplett
Preserve the Windows `GetLastError` error in `HandleOrInvalid`.

In the `TryFrom<HandleOrInvalid> for OwnedHandle` and
`TryFrom<HandleOrNull> for OwnedHandle` implemenations, `forget` the
owned handle on the error path, to avoid calling `CloseHandle` on an
invalid handle. It's harmless, except that it may overwrite the
thread's `GetLastError` error.

r? `@joshtriplett`
Diffstat (limited to 'library/std')
-rw-r--r--library/std/src/fs/tests.rs6
-rw-r--r--library/std/src/os/windows/io/handle.rs20
2 files changed, 24 insertions, 2 deletions
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 6d67c396c62..3fa731c9529 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1360,6 +1360,12 @@ fn read_dir_not_found() {
 }
 
 #[test]
+fn file_open_not_found() {
+    let res = File::open("/path/that/does/not/exist");
+    assert_eq!(res.err().unwrap().kind(), ErrorKind::NotFound);
+}
+
+#[test]
 fn create_dir_all_with_junctions() {
     let tmpdir = tmpdir();
     let target = tmpdir.join("target");
diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index be2ccbd98e9..120af9f99dd 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -147,7 +147,15 @@ impl TryFrom<HandleOrNull> for OwnedHandle {
     #[inline]
     fn try_from(handle_or_null: HandleOrNull) -> Result<Self, ()> {
         let owned_handle = handle_or_null.0;
-        if owned_handle.handle.is_null() { Err(()) } else { Ok(owned_handle) }
+        if owned_handle.handle.is_null() {
+            // Don't call `CloseHandle`; it'd be harmless, except that it could
+            // overwrite the `GetLastError` error.
+            forget(owned_handle);
+
+            Err(())
+        } else {
+            Ok(owned_handle)
+        }
     }
 }
 
@@ -197,7 +205,15 @@ impl TryFrom<HandleOrInvalid> for OwnedHandle {
     #[inline]
     fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, ()> {
         let owned_handle = handle_or_invalid.0;
-        if owned_handle.handle == c::INVALID_HANDLE_VALUE { Err(()) } else { Ok(owned_handle) }
+        if owned_handle.handle == c::INVALID_HANDLE_VALUE {
+            // Don't call `CloseHandle`; it'd be harmless, except that it could
+            // overwrite the `GetLastError` error.
+            forget(owned_handle);
+
+            Err(())
+        } else {
+            Ok(owned_handle)
+        }
     }
 }