Skip to content

Commit a3f31d7

Browse files
ChrisDentongitbot
authored and
gitbot
committed
Windows: Use FILE_ALLOCATION_INFO for truncation
But fallback to FILE_END_OF_FILE_INFO for WINE
1 parent b79852f commit a3f31d7

File tree

1 file changed

+20
-8
lines changed
  • std/src/sys/pal/windows

1 file changed

+20
-8
lines changed

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

+20-8
Original file line numberDiff line numberDiff line change
@@ -316,19 +316,31 @@ impl File {
316316
&& api::get_last_error() == WinError::ALREADY_EXISTS
317317
{
318318
unsafe {
319-
// This originally used `FileAllocationInfo` instead of
320-
// `FileEndOfFileInfo` but that wasn't supported by WINE.
321-
// It's arguable which fits the semantics of `OpenOptions`
322-
// better so let's just use the more widely supported method.
323-
let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 0 };
319+
// This first tries `FileAllocationInfo` but falls back to
320+
// `FileEndOfFileInfo` in order to support WINE.
321+
// If WINE gains support for FileAllocationInfo, we should
322+
// remove the fallback.
323+
let alloc = c::FILE_ALLOCATION_INFO { AllocationSize: 0 };
324324
let result = c::SetFileInformationByHandle(
325325
handle.as_raw_handle(),
326326
c::FileEndOfFileInfo,
327-
(&raw const eof).cast::<c_void>(),
328-
mem::size_of::<c::FILE_END_OF_FILE_INFO>() as u32,
327+
(&raw const alloc).cast::<c_void>(),
328+
mem::size_of::<c::FILE_ALLOCATION_INFO>() as u32,
329329
);
330330
if result == 0 {
331-
return Err(io::Error::last_os_error());
331+
if api::get_last_error().code != 0 {
332+
panic!("FILE_ALLOCATION_INFO failed!!!");
333+
}
334+
let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 0 };
335+
let result = c::SetFileInformationByHandle(
336+
handle.as_raw_handle(),
337+
c::FileEndOfFileInfo,
338+
(&raw const eof).cast::<c_void>(),
339+
mem::size_of::<c::FILE_END_OF_FILE_INFO>() as u32,
340+
);
341+
if result == 0 {
342+
return Err(io::Error::last_os_error());
343+
}
332344
}
333345
}
334346
}

0 commit comments

Comments
 (0)