Skip to content

Commit b60aae4

Browse files
authoredMar 19, 2025
fix(windows): don't automatically delete files on open (#344)
We tried doing this to match the behavior on Unix platforms but this appears to trigger some form of Windows kernel bug at scale. Given that it's not necessary, we're reverting it. I'm leaving the feature flag in the `Cargo.toml` for now but will remove it in the near future. fixes #339
1 parent 167f544 commit b60aae4

File tree

3 files changed

+11
-30
lines changed

3 files changed

+11
-30
lines changed
 

‎CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 3.19.1 [unreleased]
4+
5+
- Don't unlink temporary files immediately on Windows (fixes #339). Unfortunately, this seemed to corrupt the file object (possibly a Windows kernel bug) in rare cases and isn't strictly speaking necessary.
6+
37
## 3.19.0
48

59
- Remove direct dependency on `cfg-if`. It's still in the tree, but we didn't really need to use it in this crate.

‎Cargo.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,5 @@ doc-comment = "0.3"
4040
[features]
4141
default = ["getrandom"]
4242
nightly = []
43-
# Disables immediate deletion of newly opened tempfiles on windows, instead relying on the old
44-
# "delete on close" behavior. This will hopefully fix #339.
43+
# DEPRECATED unstable feature, will be removed in the near future.
4544
unstable-windows-keep-open-tempfile = []

‎src/file/imp/windows.rs

+6-28
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@ use std::{io, iter};
88

99
use windows_sys::Win32::Foundation::{HANDLE, INVALID_HANDLE_VALUE};
1010
use windows_sys::Win32::Storage::FileSystem::{
11-
FileDispositionInfoEx, MoveFileExW, ReOpenFile, SetFileAttributesW, SetFileInformationByHandle,
12-
FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_TEMPORARY, FILE_DISPOSITION_FLAG_DELETE,
13-
FILE_DISPOSITION_FLAG_POSIX_SEMANTICS, FILE_DISPOSITION_INFO_EX, FILE_FLAG_DELETE_ON_CLOSE,
14-
FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE,
15-
MOVEFILE_REPLACE_EXISTING,
11+
MoveFileExW, ReOpenFile, SetFileAttributesW, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_TEMPORARY,
12+
FILE_FLAG_DELETE_ON_CLOSE, FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_SHARE_DELETE,
13+
FILE_SHARE_READ, FILE_SHARE_WRITE, MOVEFILE_REPLACE_EXISTING,
1614
};
1715

1816
use crate::util;
@@ -25,25 +23,6 @@ fn not_supported<T>(msg: &str) -> io::Result<T> {
2523
Err(io::Error::new(io::ErrorKind::Other, msg))
2624
}
2725

28-
fn delete_open_file(f: &File) -> io::Result<()> {
29-
unsafe {
30-
let info = FILE_DISPOSITION_INFO_EX {
31-
Flags: FILE_DISPOSITION_FLAG_DELETE | FILE_DISPOSITION_FLAG_POSIX_SEMANTICS,
32-
};
33-
if SetFileInformationByHandle(
34-
f.as_raw_handle() as HANDLE,
35-
FileDispositionInfoEx,
36-
&info as *const _ as *const _,
37-
std::mem::size_of::<FILE_DISPOSITION_INFO_EX>() as u32,
38-
) == 0
39-
{
40-
Err(io::Error::last_os_error())
41-
} else {
42-
Ok(())
43-
}
44-
}
45-
}
46-
4726
pub fn create_named(
4827
path: &Path,
4928
open_options: &mut OpenOptions,
@@ -74,10 +53,9 @@ pub fn create(dir: &Path) -> io::Result<File> {
7453
.share_mode(0)
7554
.custom_flags(FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE)
7655
.open(path)?;
77-
// Attempt to delete the file by-handle. If this fails, do nothing; the file will be
78-
// deleted on close anyways.
79-
#[cfg(not(feature = "unstable-windows-keep-open-tempfile"))]
80-
let _ = delete_open_file(&f);
56+
// NOTE: in theory, we could delete the file immediately (we open the file in "unix
57+
// semantics" mode) but this seemed to corrupt something in Windows at scale (see #339).
58+
// So we just rely on `FILE_FLAG_DELETE_ON_CLOSE`.
8159
Ok(f)
8260
},
8361
)

0 commit comments

Comments
 (0)