diff options
| author | Chris Denton <chris@chrisdenton.dev> | 2024-12-24 11:04:12 +0000 |
|---|---|---|
| committer | Chris Denton <chris@chrisdenton.dev> | 2024-12-24 11:04:12 +0000 |
| commit | ca56dc853714cc6f939a4c735bfc119842896d83 (patch) | |
| tree | de25fc1f27b66026ae9ff7ce42f76be3039ead48 /library | |
| parent | 32c8a9f49d5b753ccb0aee2fd1f7a232a9c5baf3 (diff) | |
| download | rust-ca56dc853714cc6f939a4c735bfc119842896d83.tar.gz rust-ca56dc853714cc6f939a4c735bfc119842896d83.zip | |
Windows: Use FILE_ALLOCATION_INFO for truncation
But fallback to FILE_END_OF_FILE_INFO for WINE
Diffstat (limited to 'library')
| -rw-r--r-- | library/std/src/sys/pal/windows/fs.rs | 28 |
1 files 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 642be872dce..dda4259919b 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::<c_void>(), - mem::size_of::<c::FILE_END_OF_FILE_INFO>() as u32, + (&raw const alloc).cast::<c_void>(), + mem::size_of::<c::FILE_ALLOCATION_INFO>() 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::<c_void>(), + mem::size_of::<c::FILE_END_OF_FILE_INFO>() as u32, + ); + if result == 0 { + return Err(io::Error::last_os_error()); + } } } } |
