Commit 6d6f6a4ac6
Changed files (1)
lib
std
lib/std/os/windows.zig
@@ -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),
+ }
}
}