From ca56dc853714cc6f939a4c735bfc119842896d83 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 24 Dec 2024 11:04:12 +0000 Subject: [PATCH] Windows: Use FILE_ALLOCATION_INFO for truncation But fallback to FILE_END_OF_FILE_INFO for WINE --- library/std/src/sys/pal/windows/fs.rs | 28 +++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index 642be872dceb2..dda4259919b6d 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -316,19 +316,31 @@ impl File { && api::get_last_error() == WinError::ALREADY_EXISTS { unsafe { - // This originally used `FileAllocationInfo` instead of - // `FileEndOfFileInfo` but that wasn't supported by WINE. - // It's arguable which fits the semantics of `OpenOptions` - // better so let's just use the more widely supported method. - let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 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 }; let result = c::SetFileInformationByHandle( handle.as_raw_handle(), c::FileEndOfFileInfo, - (&raw const eof).cast::(), - mem::size_of::() as u32, + (&raw const alloc).cast::(), + mem::size_of::() as u32, ); if result == 0 { - return Err(io::Error::last_os_error()); + if api::get_last_error().code != 0 { + panic!("FILE_ALLOCATION_INFO failed!!!"); + } + let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 0 }; + let result = c::SetFileInformationByHandle( + handle.as_raw_handle(), + c::FileEndOfFileInfo, + (&raw const eof).cast::(), + mem::size_of::() as u32, + ); + if result == 0 { + return Err(io::Error::last_os_error()); + } } } }