Commit 7594d2c097
Changed files (2)
lib
std
fs
lib/std/fs/test.zig
@@ -1416,23 +1416,42 @@ test "File.PermissionsUnix" {
try testing.expect(!permissions_unix.unixHas(.other, .execute));
}
-test "delete a read-only file on windows" {
- if (builtin.os.tag != .windows) return error.SkipZigTest;
+test "delete a read-only file on windows with file pending semantics" {
+ if (builtin.os.tag != .windows or builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs1))
+ return error.SkipZigTest;
+
+ var tmp = tmpDir(.{});
+ defer tmp.cleanup();
+ {
+ const file = try tmp.dir.createFile("test_file", .{ .read = true });
+ defer file.close();
+ // Create a file and make it read-only
+ const metadata = try file.metadata();
+ var permissions = metadata.permissions();
+ permissions.setReadOnly(true);
+ try file.setPermissions(permissions);
+ try testing.expectError(error.AccessDenied, tmp.dir.deleteFile("test_file"));
+ // Now make the file not read-only
+ permissions.setReadOnly(false);
+ try file.setPermissions(permissions);
+ }
+ try tmp.dir.deleteFile("test_file");
+}
+
+test "delete a read-only file on windows with posix semantis" {
+ if (builtin.os.tag != .windows or !builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs1))
+ return error.SkipZigTest;
var tmp = tmpDir(.{});
defer tmp.cleanup();
const file = try tmp.dir.createFile("test_file", .{ .read = true });
+ defer file.close();
// Create a file and make it read-only
const metadata = try file.metadata();
var permissions = metadata.permissions();
permissions.setReadOnly(true);
try file.setPermissions(permissions);
- try testing.expectError(error.AccessDenied, tmp.dir.deleteFile("test_file"));
- // Now make the file not read-only
- permissions.setReadOnly(false);
- try file.setPermissions(permissions);
- file.close();
- try tmp.dir.deleteFile("test_file");
+ try tmp.dir.deleteFile("test_file"); // file is unmapped and deleted once last handle closed
}
test "delete a setAsCwd directory on Windows" {
lib/std/os/windows.zig
@@ -938,6 +938,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
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{
@@ -953,17 +954,13 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
@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,
@@ -971,15 +968,15 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
@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),
- }
+ }
+ 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),
}
}