Commit 7594d2c097

Jan Philipp Hafer <jan.hafer@rwth-aachen.de>
2023-05-01 18:22:28
address review by user @squeek502
1 parent be50dbf
Changed files (2)
lib
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),
     }
 }