diff options
Diffstat (limited to 'library/std/src/sys/pal/windows/fs.rs')
| -rw-r--r-- | library/std/src/sys/pal/windows/fs.rs | 64 |
1 files changed, 24 insertions, 40 deletions
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index bdb55643bb1..dce5a429cb0 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -1,4 +1,4 @@ -use super::api::{self, WinError}; +use super::api::{self, WinError, set_file_information_by_handle}; use super::{IoResult, to_u16s}; use crate::alloc::{alloc, handle_alloc_error}; use crate::borrow::Cow; @@ -44,7 +44,7 @@ pub struct FileType { } pub struct ReadDir { - handle: FindNextFileHandle, + handle: Option<FindNextFileHandle>, root: Arc<PathBuf>, first: Option<c::WIN32_FIND_DATAW>, } @@ -113,13 +113,13 @@ impl fmt::Debug for ReadDir { impl Iterator for ReadDir { type Item = io::Result<DirEntry>; fn next(&mut self) -> Option<io::Result<DirEntry>> { - if self.handle.0 == c::INVALID_HANDLE_VALUE { + let Some(handle) = self.handle.as_ref() else { // This iterator was initialized with an `INVALID_HANDLE_VALUE` as its handle. // Simply return `None` because this is only the case when `FindFirstFileExW` in // the construction of this iterator returns `ERROR_FILE_NOT_FOUND` which means // no matchhing files can be found. return None; - } + }; if let Some(first) = self.first.take() { if let Some(e) = DirEntry::new(&self.root, &first) { return Some(Ok(e)); @@ -128,7 +128,7 @@ impl Iterator for ReadDir { unsafe { let mut wfd = mem::zeroed(); loop { - if c::FindNextFileW(self.handle.0, &mut wfd) == 0 { + if c::FindNextFileW(handle.0, &mut wfd) == 0 { match api::get_last_error() { WinError::NO_MORE_FILES => return None, WinError { code } => { @@ -319,31 +319,17 @@ impl File { && creation == c::OPEN_ALWAYS && api::get_last_error() == WinError::ALREADY_EXISTS { - unsafe { - // This first tries `FileAllocationInfo` but falls back to - // `FileEndOfFileInfo` in order to support WINE. - // If WINE gains support for FileAllocationInfo, we should - // remove the fallback. - let alloc = c::FILE_ALLOCATION_INFO { AllocationSize: 0 }; - let result = c::SetFileInformationByHandle( - handle.as_raw_handle(), - c::FileAllocationInfo, - (&raw const alloc).cast::<c_void>(), - mem::size_of::<c::FILE_ALLOCATION_INFO>() as u32, - ); - if result == 0 { + // This first tries `FileAllocationInfo` but falls back to + // `FileEndOfFileInfo` in order to support WINE. + // If WINE gains support for FileAllocationInfo, we should + // remove the fallback. + let alloc = c::FILE_ALLOCATION_INFO { AllocationSize: 0 }; + set_file_information_by_handle(handle.as_raw_handle(), &alloc) + .or_else(|_| { let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 0 }; - let result = c::SetFileInformationByHandle( - handle.as_raw_handle(), - c::FileEndOfFileInfo, - (&raw const eof).cast::<c_void>(), - mem::size_of::<c::FILE_END_OF_FILE_INFO>() as u32, - ); - if result == 0 { - return Err(io::Error::last_os_error()); - } - } - } + set_file_information_by_handle(handle.as_raw_handle(), &eof) + }) + .io_result()?; } Ok(File { handle: Handle::from_inner(handle) }) } else { @@ -631,6 +617,10 @@ impl File { Ok(newpos as u64) } + pub fn tell(&self) -> io::Result<u64> { + self.seek(SeekFrom::Current(0)) + } + pub fn duplicate(&self) -> io::Result<File> { Ok(Self { handle: self.handle.try_clone()? }) } @@ -812,7 +802,7 @@ impl File { /// will prevent anyone from opening a new handle to the file. #[allow(unused)] fn win32_delete(&self) -> Result<(), WinError> { - let info = c::FILE_DISPOSITION_INFO { DeleteFile: c::TRUE as _ }; + let info = c::FILE_DISPOSITION_INFO { DeleteFile: true }; api::set_file_information_by_handle(self.handle.as_raw_handle(), &info) } @@ -1194,7 +1184,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> { if find_handle != c::INVALID_HANDLE_VALUE { Ok(ReadDir { - handle: FindNextFileHandle(find_handle), + handle: Some(FindNextFileHandle(find_handle)), root: Arc::new(root), first: Some(wfd), }) @@ -1212,11 +1202,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> { // See issue #120040: https://github.com/rust-lang/rust/issues/120040. let last_error = api::get_last_error(); if last_error == WinError::FILE_NOT_FOUND { - return Ok(ReadDir { - handle: FindNextFileHandle(find_handle), - root: Arc::new(root), - first: None, - }); + return Ok(ReadDir { handle: None, root: Arc::new(root), first: None }); } // Just return the error constructed from the raw OS error if the above is not the case. @@ -1376,7 +1362,7 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> { if let Err(err) = result { if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as _) { // FileRenameInfoEx and FILE_RENAME_FLAG_POSIX_SEMANTICS were added in Windows 10 1607; retry with FileRenameInfo. - file_rename_info.Anonymous.ReplaceIfExists = 1; + file_rename_info.Anonymous.ReplaceIfExists = true; cvt(unsafe { c::SetFileInformationByHandle( @@ -1472,9 +1458,7 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> { #[cfg(target_vendor = "uwp")] pub fn link(_original: &Path, _link: &Path) -> io::Result<()> { - return Err( - io::const_error!(io::ErrorKind::Unsupported, "hard link are not supported on UWP",), - ); + return Err(io::const_error!(io::ErrorKind::Unsupported, "hard link are not supported on UWP")); } pub fn stat(path: &Path) -> io::Result<FileAttr> { |
