Skip to content

Commit f471ce3

Browse files
Rollup merge of #136552 - ChrisDenton:option-find-handle, r=Mark-Simulacrum
Use an `Option` for `FindNextFileHandle` in `ReadDir` instead of `INVALID_FILE_HANDLE` sentinel value Sometimes we store an invalid handle when we don't want to return an error. We then check the handle before use in order to avoid actually using the invalid handle. However, using an `Option` for this is better and avoids us forgetting to check the handle is valid. This was noticed due to us closing the handle without checking for validity: https://github.com/rust-lang/rust/blob/bd6a6777f5cbbec549f123995026cef76d1e6b84/library/std/src/sys/pal/windows/fs.rs#L148-L151
2 parents e1bd25e + bd6a677 commit f471ce3

File tree

1 file changed

+6
-10
lines changed
  • library/std/src/sys/pal/windows

1 file changed

+6
-10
lines changed

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

+6-10
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub struct FileType {
4444
}
4545

4646
pub struct ReadDir {
47-
handle: FindNextFileHandle,
47+
handle: Option<FindNextFileHandle>,
4848
root: Arc<PathBuf>,
4949
first: Option<c::WIN32_FIND_DATAW>,
5050
}
@@ -113,13 +113,13 @@ impl fmt::Debug for ReadDir {
113113
impl Iterator for ReadDir {
114114
type Item = io::Result<DirEntry>;
115115
fn next(&mut self) -> Option<io::Result<DirEntry>> {
116-
if self.handle.0 == c::INVALID_HANDLE_VALUE {
116+
let Some(handle) = self.handle.as_ref() else {
117117
// This iterator was initialized with an `INVALID_HANDLE_VALUE` as its handle.
118118
// Simply return `None` because this is only the case when `FindFirstFileExW` in
119119
// the construction of this iterator returns `ERROR_FILE_NOT_FOUND` which means
120120
// no matchhing files can be found.
121121
return None;
122-
}
122+
};
123123
if let Some(first) = self.first.take() {
124124
if let Some(e) = DirEntry::new(&self.root, &first) {
125125
return Some(Ok(e));
@@ -128,7 +128,7 @@ impl Iterator for ReadDir {
128128
unsafe {
129129
let mut wfd = mem::zeroed();
130130
loop {
131-
if c::FindNextFileW(self.handle.0, &mut wfd) == 0 {
131+
if c::FindNextFileW(handle.0, &mut wfd) == 0 {
132132
match api::get_last_error() {
133133
WinError::NO_MORE_FILES => return None,
134134
WinError { code } => {
@@ -1194,7 +1194,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
11941194

11951195
if find_handle != c::INVALID_HANDLE_VALUE {
11961196
Ok(ReadDir {
1197-
handle: FindNextFileHandle(find_handle),
1197+
handle: Some(FindNextFileHandle(find_handle)),
11981198
root: Arc::new(root),
11991199
first: Some(wfd),
12001200
})
@@ -1212,11 +1212,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
12121212
// See issue #120040: https://github.com/rust-lang/rust/issues/120040.
12131213
let last_error = api::get_last_error();
12141214
if last_error == WinError::FILE_NOT_FOUND {
1215-
return Ok(ReadDir {
1216-
handle: FindNextFileHandle(find_handle),
1217-
root: Arc::new(root),
1218-
first: None,
1219-
});
1215+
return Ok(ReadDir { handle: None, root: Arc::new(root), first: None });
12201216
}
12211217

12221218
// Just return the error constructed from the raw OS error if the above is not the case.

0 commit comments

Comments
 (0)