Skip to content

Commit

Permalink
feat: delete unnamed temporary files on windows immediately
Browse files Browse the repository at this point in the history
  • Loading branch information
Stebalien committed Feb 16, 2025
1 parent 78d30a2 commit 3eee527
Showing 1 changed file with 26 additions and 3 deletions.
29 changes: 26 additions & 3 deletions src/file/imp/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use std::{io, iter};

use windows_sys::Win32::Foundation::{HANDLE, INVALID_HANDLE_VALUE};
use windows_sys::Win32::Storage::FileSystem::{
MoveFileExW, ReOpenFile, SetFileAttributesW, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_TEMPORARY,
FileDispositionInfoExClass, MoveFileExW, ReOpenFile, SetFileAttributesW,
SetFileInformationByHandle, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_TEMPORARY,
FILE_DISPOSITION_FLAG_DELETE, FILE_DISPOSITION_FLAG_POSIX_SEMANTICS, FILE_DISPOSITION_INFO_EX,
FILE_FLAG_DELETE_ON_CLOSE, FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_SHARE_DELETE,
FILE_SHARE_READ, FILE_SHARE_WRITE, MOVEFILE_REPLACE_EXISTING,
};
Expand All @@ -23,6 +25,23 @@ fn not_supported<T>(msg: &str) -> io::Result<T> {
Err(io::Error::new(io::ErrorKind::Other, msg))
}

fn delete_open_file(f: &File) -> io::Result<()> {
unsafe {
let info = FILE_DISPOSITION_INFO_EX {
Flags: FILE_DISPOSITION_FLAG_DELETE | FILE_DISPOSITION_FLAG_POSIX_SEMANTICS,
};
match SetFileInformationByHandle(
f.as_raw_handle() as isize,
FileDispositionInfoExClass,
&info as *const _,
std::mem::size_of::<FILE_DISPOSITION_INFO_EX>() as u32,
) {
0 => Ok(()),
_ => Err(io::Error::last_os_error()),
}
}
}

pub fn create_named(
path: &Path,
open_options: &mut OpenOptions,
Expand All @@ -46,13 +65,17 @@ pub fn create(dir: &Path) -> io::Result<File> {
OsStr::new(""),
crate::NUM_RAND_CHARS,
|path| {
OpenOptions::new()
let f = OpenOptions::new()
.create_new(true)
.read(true)
.write(true)
.share_mode(0)
.custom_flags(FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE)
.open(path)
.open(path)?;
// Attempt to delete the file by-handle. If this fails, do nothing; the file will be
// deleted on close anyways.
let _ = delete_open_file(f);
Ok(f)
},
)
}
Expand Down

0 comments on commit 3eee527

Please sign in to comment.