authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-09-27 21:59:29+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-09-27 21:59:29+02:00
loge60939bfaafc9e6b3ccdc172009b950fc7a3eab1
tree8b3306daa258e9adf303d1c9be2c3fbab5af0977
parent8794ce6f79886e5ebbf0476d56917e219b52c561
parent43cd9eb110f6803f4e19d92347ebf263e6e644af
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #6397 from suirad/fix-5537

Fix for Windows: std.os.windows.DeleteFile()

2 files changed, 40 insertions(+), 1 deletions(-)

lib/std/fs/test.zig+23
...@@ -813,3 +813,26 @@ fn run_lock_file_test(contexts: []FileLockTestContext) !void {...@@ -813,3 +813,26 @@ fn run_lock_file_test(contexts: []FileLockTestContext) !void {
813 try threads.append(try std.Thread.spawn(ctx, FileLockTestContext.run));813 try threads.append(try std.Thread.spawn(ctx, FileLockTestContext.run));
814 }814 }
815}815}
816
817test "deleteDir" {
818 var tmp_dir = tmpDir(.{});
819 defer tmp_dir.cleanup();
820
821 // deleting a non-existent directory
822 testing.expectError(error.FileNotFound, tmp_dir.dir.deleteDir("test_dir"));
823
824 var dir = try tmp_dir.dir.makeOpenPath("test_dir", .{});
825 var file = try dir.createFile("test_file", .{});
826 file.close();
827 dir.close();
828
829 // deleting a non-empty directory
830 testing.expectError(error.DirNotEmpty, tmp_dir.dir.deleteDir("test_dir"));
831
832 dir = try tmp_dir.dir.openDir("test_dir", .{});
833 try dir.deleteFile("test_file");
834 dir.close();
835
836 // deleting an empty directory
837 try tmp_dir.dir.deleteDir("test_dir");
838}
lib/std/os/windows.zig+17-1
...@@ -764,6 +764,7 @@ pub const DeleteFileError = error{...@@ -764,6 +764,7 @@ pub const DeleteFileError = error{
764 Unexpected,764 Unexpected,
765 NotDir,765 NotDir,
766 IsDir,766 IsDir,
767 DirNotEmpty,
767};768};
768769
769pub const DeleteFileOptions = struct {770pub const DeleteFileOptions = struct {
...@@ -818,7 +819,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil...@@ -818,7 +819,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
818 0,819 0,
819 );820 );
820 switch (rc) {821 switch (rc) {
821 .SUCCESS => return CloseHandle(tmp_handle),822 .SUCCESS => CloseHandle(tmp_handle),
822 .OBJECT_NAME_INVALID => unreachable,823 .OBJECT_NAME_INVALID => unreachable,
823 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,824 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
824 .INVALID_PARAMETER => unreachable,825 .INVALID_PARAMETER => unreachable,
...@@ -826,6 +827,21 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil...@@ -826,6 +827,21 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
826 .NOT_A_DIRECTORY => return error.NotDir,827 .NOT_A_DIRECTORY => return error.NotDir,
827 else => return unexpectedStatus(rc),828 else => return unexpectedStatus(rc),
828 }829 }
830
831 // If a directory fails to be deleted, CloseHandle will still report success
832 // Check if the directory still exists and return error.DirNotEmpty if true
833 if (options.remove_dir) {
834 var basic_info: FILE_BASIC_INFORMATION = undefined;
835 switch (ntdll.NtQueryAttributesFile(&attr, &basic_info)) {
836 .SUCCESS => return error.DirNotEmpty,
837 .OBJECT_NAME_NOT_FOUND => return,
838 .OBJECT_PATH_NOT_FOUND => return,
839 .INVALID_PARAMETER => unreachable,
840 .ACCESS_DENIED => return error.AccessDenied,
841 .OBJECT_PATH_SYNTAX_BAD => unreachable,
842 else => |urc| return unexpectedStatus(urc),
843 }
844 }
829}845}
830846
831pub const MoveFileError = error{ FileNotFound, Unexpected };847pub const MoveFileError = error{ FileNotFound, Unexpected };