Skip to content

Commit 308efaf

Browse files
authored
Rollup merge of #94572 - sunfishcode:sunfishcode/handle-or, r=joshtriplett
Use `HandleOrNull` and `HandleOrInvalid` in the Windows FFI bindings. Use the new `HandleOrNull` and `HandleOrInvalid` types that were introduced as part of [I/O safety] in a few functions in the Windows FFI bindings. This factors out an `unsafe` block and two `unsafe` function calls in the Windows implementation code. And, it helps test `HandleOrNull` and `HandleOrInvalid`, and indeed, it turned up a bug: `OwnedHandle` also needs to be `#[repr(transparent)]`, as it's used inside of `HandleOrNull` and `HandleOrInvalid` which are also `#[repr(transparent)]`. r? ```@joshtriplett``` [I/O safety]: #87074
2 parents 958bd02 + 3560649 commit 308efaf

File tree

5 files changed

+22
-17
lines changed

5 files changed

+22
-17
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ pub struct BorrowedHandle<'handle> {
5959
/// [`RegCloseKey`]: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regclosekey
6060
///
6161
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
62+
#[repr(transparent)]
6263
#[unstable(feature = "io_safety", issue = "87074")]
6364
pub struct OwnedHandle {
6465
handle: RawHandle,

library/std/src/sys/windows/c.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use crate::mem;
88
use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort};
9+
use crate::os::windows::io::{BorrowedHandle, HandleOrInvalid, HandleOrNull};
910
use crate::ptr;
1011
use core::ffi::NonZero_c_ulong;
1112

@@ -886,7 +887,7 @@ extern "system" {
886887
lpParameter: LPVOID,
887888
dwCreationFlags: DWORD,
888889
lpThreadId: LPDWORD,
889-
) -> HANDLE;
890+
) -> HandleOrNull;
890891
pub fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
891892
pub fn SwitchToThread() -> BOOL;
892893
pub fn Sleep(dwMilliseconds: DWORD);
@@ -950,14 +951,14 @@ extern "system" {
950951
dwOptions: DWORD,
951952
) -> BOOL;
952953
pub fn ReadFile(
953-
hFile: HANDLE,
954+
hFile: BorrowedHandle<'_>,
954955
lpBuffer: LPVOID,
955956
nNumberOfBytesToRead: DWORD,
956957
lpNumberOfBytesRead: LPDWORD,
957958
lpOverlapped: LPOVERLAPPED,
958959
) -> BOOL;
959960
pub fn WriteFile(
960-
hFile: HANDLE,
961+
hFile: BorrowedHandle<'_>,
961962
lpBuffer: LPVOID,
962963
nNumberOfBytesToWrite: DWORD,
963964
lpNumberOfBytesWritten: LPDWORD,
@@ -981,7 +982,7 @@ extern "system" {
981982
dwCreationDisposition: DWORD,
982983
dwFlagsAndAttributes: DWORD,
983984
hTemplateFile: HANDLE,
984-
) -> HANDLE;
985+
) -> HandleOrInvalid;
985986

986987
pub fn FindFirstFileW(fileName: LPCWSTR, findFileData: LPWIN32_FIND_DATAW) -> HANDLE;
987988
pub fn FindNextFileW(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW) -> BOOL;

library/std/src/sys/windows/fs.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::os::windows::prelude::*;
22

3+
use crate::convert::TryInto;
34
use crate::ffi::OsString;
45
use crate::fmt;
56
use crate::io::{self, Error, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
@@ -294,10 +295,10 @@ impl File {
294295
ptr::null_mut(),
295296
)
296297
};
297-
if handle == c::INVALID_HANDLE_VALUE {
298-
Err(Error::last_os_error())
298+
if let Ok(handle) = handle.try_into() {
299+
Ok(File { handle: Handle::from_inner(handle) })
299300
} else {
300-
unsafe { Ok(File { handle: Handle::from_raw_handle(handle) }) }
301+
Err(Error::last_os_error())
301302
}
302303
}
303304

library/std/src/sys/windows/handle.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl Handle {
7878
let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
7979
let res = cvt(unsafe {
8080
c::ReadFile(
81-
self.as_raw_handle(),
81+
self.as_handle(),
8282
buf.as_mut_ptr() as c::LPVOID,
8383
len,
8484
&mut read,
@@ -116,7 +116,7 @@ impl Handle {
116116
overlapped.Offset = offset as u32;
117117
overlapped.OffsetHigh = (offset >> 32) as u32;
118118
cvt(c::ReadFile(
119-
self.as_raw_handle(),
119+
self.as_handle(),
120120
buf.as_mut_ptr() as c::LPVOID,
121121
len,
122122
&mut read,
@@ -135,7 +135,7 @@ impl Handle {
135135
let len = cmp::min(buf.remaining(), <c::DWORD>::MAX as usize) as c::DWORD;
136136
let res = cvt(unsafe {
137137
c::ReadFile(
138-
self.as_raw_handle(),
138+
self.as_handle(),
139139
buf.unfilled_mut().as_mut_ptr() as c::LPVOID,
140140
len,
141141
&mut read,
@@ -171,7 +171,7 @@ impl Handle {
171171
let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
172172
let mut amt = 0;
173173
let res = cvt(c::ReadFile(
174-
self.as_raw_handle(),
174+
self.as_handle(),
175175
buf.as_ptr() as c::LPVOID,
176176
len,
177177
&mut amt,
@@ -225,7 +225,7 @@ impl Handle {
225225
let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
226226
cvt(unsafe {
227227
c::WriteFile(
228-
self.as_raw_handle(),
228+
self.as_handle(),
229229
buf.as_ptr() as c::LPVOID,
230230
len,
231231
&mut amt,
@@ -252,7 +252,7 @@ impl Handle {
252252
overlapped.Offset = offset as u32;
253253
overlapped.OffsetHigh = (offset >> 32) as u32;
254254
cvt(c::WriteFile(
255-
self.as_raw_handle(),
255+
self.as_handle(),
256256
buf.as_ptr() as c::LPVOID,
257257
len,
258258
&mut written,

library/std/src/sys/windows/thread.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
use crate::convert::TryInto;
12
use crate::ffi::CStr;
23
use crate::io;
34
use crate::num::NonZeroUsize;
4-
use crate::os::windows::io::{AsRawHandle, FromRawHandle};
5+
use crate::os::windows::io::AsRawHandle;
56
use crate::ptr;
67
use crate::sys::c;
78
use crate::sys::handle::Handle;
89
use crate::sys::stack_overflow;
10+
use crate::sys_common::FromInner;
911
use crate::time::Duration;
1012

1113
use libc::c_void;
@@ -40,13 +42,13 @@ impl Thread {
4042
ptr::null_mut(),
4143
);
4244

43-
return if ret as usize == 0 {
45+
return if let Ok(handle) = ret.try_into() {
46+
Ok(Thread { handle: Handle::from_inner(handle) })
47+
} else {
4448
// The thread failed to start and as a result p was not consumed. Therefore, it is
4549
// safe to reconstruct the box so that it gets deallocated.
4650
drop(Box::from_raw(p));
4751
Err(io::Error::last_os_error())
48-
} else {
49-
Ok(Thread { handle: Handle::from_raw_handle(ret) })
5052
};
5153

5254
extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {

0 commit comments

Comments
 (0)