mirror of
https://github.com/ziglang/zig.git
synced 2024-11-16 09:03:12 +00:00
std.windows: use posix semantics to delete files, if available
Justification: When a file is deleted on Windows, it may not be immediately removed from the directory. This can cause problems with future scans of that directory, which will see the partially deleted file. Under some workloads and system configurations, Windows files may appear to be deleted immediately. This is the PR with requested fixup. Thanks to @SpexGuy for the original PR.
This commit is contained in:
parent
e963793e37
commit
0f0f005e92
@ -937,25 +937,50 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
|
||||
.DELETE_PENDING => return,
|
||||
else => return unexpectedStatus(rc),
|
||||
}
|
||||
var file_dispo = FILE_DISPOSITION_INFORMATION{
|
||||
.DeleteFile = TRUE,
|
||||
};
|
||||
rc = ntdll.NtSetInformationFile(
|
||||
tmp_handle,
|
||||
&io,
|
||||
&file_dispo,
|
||||
@sizeOf(FILE_DISPOSITION_INFORMATION),
|
||||
.FileDispositionInformation,
|
||||
);
|
||||
CloseHandle(tmp_handle);
|
||||
switch (rc) {
|
||||
.SUCCESS => return,
|
||||
.DIRECTORY_NOT_EMPTY => return error.DirNotEmpty,
|
||||
.INVALID_PARAMETER => unreachable,
|
||||
.CANNOT_DELETE => return error.AccessDenied,
|
||||
.MEDIA_WRITE_PROTECTED => return error.AccessDenied,
|
||||
.ACCESS_DENIED => return error.AccessDenied,
|
||||
else => return unexpectedStatus(rc),
|
||||
defer CloseHandle(tmp_handle);
|
||||
if (comptime builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs1)) {
|
||||
// Deletion with posix semantics.
|
||||
var info = FILE_DISPOSITION_INFORMATION_EX{
|
||||
.Flags = FILE_DISPOSITION_DELETE |
|
||||
FILE_DISPOSITION_POSIX_SEMANTICS |
|
||||
FILE_DISPOSITION_ON_CLOSE |
|
||||
FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE,
|
||||
};
|
||||
|
||||
rc = ntdll.NtSetInformationFile(
|
||||
tmp_handle,
|
||||
&io,
|
||||
&info,
|
||||
@sizeOf(FILE_DISPOSITION_INFORMATION_EX),
|
||||
.FileDispositionInformationEx,
|
||||
);
|
||||
switch (rc) {
|
||||
.SUCCESS => {},
|
||||
.CANNOT_DELETE => return error.FileBusy, // file is currently mapped
|
||||
else => return unexpectedStatus(rc),
|
||||
}
|
||||
} else {
|
||||
// Deletion with file pending semantics, which requires waiting or moving
|
||||
// files to get them removed (from here).
|
||||
var file_dispo = FILE_DISPOSITION_INFORMATION{
|
||||
.DeleteFile = TRUE,
|
||||
};
|
||||
rc = ntdll.NtSetInformationFile(
|
||||
tmp_handle,
|
||||
&io,
|
||||
&file_dispo,
|
||||
@sizeOf(FILE_DISPOSITION_INFORMATION),
|
||||
.FileDispositionInformation,
|
||||
);
|
||||
switch (rc) {
|
||||
.SUCCESS => {},
|
||||
.DIRECTORY_NOT_EMPTY => return error.DirNotEmpty,
|
||||
.INVALID_PARAMETER => unreachable,
|
||||
.CANNOT_DELETE => return error.AccessDenied,
|
||||
.MEDIA_WRITE_PROTECTED => return error.AccessDenied,
|
||||
.ACCESS_DENIED => return error.AccessDenied,
|
||||
else => return unexpectedStatus(rc),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2397,6 +2422,18 @@ pub const FILE_NAME_INFORMATION = extern struct {
|
||||
FileName: [1]WCHAR,
|
||||
};
|
||||
|
||||
pub const FILE_DISPOSITION_INFORMATION_EX = extern struct {
|
||||
/// combination of FILE_DISPOSITION_* flags
|
||||
Flags: ULONG,
|
||||
};
|
||||
|
||||
const FILE_DISPOSITION_DO_NOT_DELETE: ULONG = 0x00000000;
|
||||
const FILE_DISPOSITION_DELETE: ULONG = 0x00000001;
|
||||
const FILE_DISPOSITION_POSIX_SEMANTICS: ULONG = 0x00000002;
|
||||
const FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK: ULONG = 0x00000004;
|
||||
const FILE_DISPOSITION_ON_CLOSE: ULONG = 0x00000008;
|
||||
const FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE: ULONG = 0x00000010;
|
||||
|
||||
pub const FILE_RENAME_INFORMATION = extern struct {
|
||||
ReplaceIfExists: BOOLEAN,
|
||||
RootDirectory: ?HANDLE,
|
||||
|
Loading…
Reference in New Issue
Block a user