mirror of
https://github.com/ziglang/zig.git
synced 2024-11-16 09:03:12 +00:00
std.os.windows.OpenFile: handle DELETE_PENDING
This error means that there *was* a file in this location on the file system, but it was deleted. However, the OS is not finished with the deletion operation, and so this CreateFile call has failed. There is not really a sane way to handle this other than retrying the creation after the OS finishes the deletion.
This commit is contained in:
parent
717e2c8718
commit
6d6f6a4ac6
@ -105,41 +105,53 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
|
||||
// If we're not following symlinks, we need to ensure we don't pass in any synchronization flags such as FILE_SYNCHRONOUS_IO_NONALERT.
|
||||
const flags: ULONG = if (options.follow_symlinks) file_or_dir_flag | blocking_flag else file_or_dir_flag | FILE_OPEN_REPARSE_POINT;
|
||||
|
||||
const rc = ntdll.NtCreateFile(
|
||||
&result,
|
||||
options.access_mask,
|
||||
&attr,
|
||||
&io,
|
||||
null,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
options.share_access,
|
||||
options.creation,
|
||||
flags,
|
||||
null,
|
||||
0,
|
||||
);
|
||||
switch (rc) {
|
||||
.SUCCESS => {
|
||||
if (std.io.is_async and options.io_mode == .evented) {
|
||||
_ = CreateIoCompletionPort(result, std.event.Loop.instance.?.os_data.io_port, undefined, undefined) catch undefined;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
.OBJECT_NAME_INVALID => unreachable,
|
||||
.OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
|
||||
.OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
|
||||
.NO_MEDIA_IN_DEVICE => return error.NoDevice,
|
||||
.INVALID_PARAMETER => unreachable,
|
||||
.SHARING_VIOLATION => return error.AccessDenied,
|
||||
.ACCESS_DENIED => return error.AccessDenied,
|
||||
.PIPE_BUSY => return error.PipeBusy,
|
||||
.OBJECT_PATH_SYNTAX_BAD => unreachable,
|
||||
.OBJECT_NAME_COLLISION => return error.PathAlreadyExists,
|
||||
.FILE_IS_A_DIRECTORY => return error.IsDir,
|
||||
.NOT_A_DIRECTORY => return error.NotDir,
|
||||
.USER_MAPPED_FILE => return error.AccessDenied,
|
||||
.INVALID_HANDLE => unreachable,
|
||||
else => return unexpectedStatus(rc),
|
||||
while (true) {
|
||||
const rc = ntdll.NtCreateFile(
|
||||
&result,
|
||||
options.access_mask,
|
||||
&attr,
|
||||
&io,
|
||||
null,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
options.share_access,
|
||||
options.creation,
|
||||
flags,
|
||||
null,
|
||||
0,
|
||||
);
|
||||
switch (rc) {
|
||||
.SUCCESS => {
|
||||
if (std.io.is_async and options.io_mode == .evented) {
|
||||
_ = CreateIoCompletionPort(result, std.event.Loop.instance.?.os_data.io_port, undefined, undefined) catch undefined;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
.OBJECT_NAME_INVALID => unreachable,
|
||||
.OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
|
||||
.OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
|
||||
.NO_MEDIA_IN_DEVICE => return error.NoDevice,
|
||||
.INVALID_PARAMETER => unreachable,
|
||||
.SHARING_VIOLATION => return error.AccessDenied,
|
||||
.ACCESS_DENIED => return error.AccessDenied,
|
||||
.PIPE_BUSY => return error.PipeBusy,
|
||||
.OBJECT_PATH_SYNTAX_BAD => unreachable,
|
||||
.OBJECT_NAME_COLLISION => return error.PathAlreadyExists,
|
||||
.FILE_IS_A_DIRECTORY => return error.IsDir,
|
||||
.NOT_A_DIRECTORY => return error.NotDir,
|
||||
.USER_MAPPED_FILE => return error.AccessDenied,
|
||||
.INVALID_HANDLE => unreachable,
|
||||
.DELETE_PENDING => {
|
||||
// This error means that there *was* a file in this location on
|
||||
// the file system, but it was deleted. However, the OS is not
|
||||
// finished with the deletion operation, and so this CreateFile
|
||||
// call has failed. There is not really a sane way to handle
|
||||
// this other than retrying the creation after the OS finishes
|
||||
// the deletion.
|
||||
std.time.sleep(std.time.ns_per_ms);
|
||||
continue;
|
||||
},
|
||||
else => return unexpectedStatus(rc),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user