Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 27, 2020
Merged

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

merged 2 commits into from
Sep 27, 2020

Conversation

suirad
Copy link
Contributor

@suirad suirad commented Sep 23, 2020

This commit addresses #5537 using the following test:

const builtin = @import("builtin");
const std = @import("std");
const fs = std.fs;
const assert = std.debug.assert;
const print = std.debug.print;
const testing = std.testing;

test "#5537" {
    if (builtin.os.tag != .windows) return;
    const cwd = fs.cwd();

    cwd.makeDir("tmp") catch |e| {
        switch (e) {
            error.PathAlreadyExists => {},
            else => return e,
        }
    };
    defer cwd.deleteDir("tmp") catch unreachable;

    var file = try cwd.createFile("tmp/tmpfile", .{ .read = true });
    defer {
        file.close();
        cwd.deleteFile("tmp/tmpfile") catch unreachable;
    }

   // Actual test for proper behavior
    testing.expectError(error.DirNotEmpty, cwd.deleteDir("tmp"));
}

I considered adding this test to the std to catch regressions but I wasn't sure if it was wanted to be added and I also wasn't sure exactly where in the repo to add it.

@squeek502
Copy link
Collaborator

squeek502 commented Sep 23, 2020

Nice. Here's a possible test case that can be added to std/fs/test.zig:

test "deleteDir" {
    var tmp_dir = tmpDir(.{});
    defer tmp_dir.cleanup();

    // deleting a non-existent directory
    testing.expectError(error.FileNotFound, tmp_dir.dir.deleteDir("test_dir"));

    var dir = try tmp_dir.dir.makeOpenPath("test_dir", .{});
    var file = try dir.createFile("test_file", .{});
    file.close();
    dir.close();

    // deleting a non-empty directory
    testing.expectError(error.DirNotEmpty, tmp_dir.dir.deleteDir("test_dir"));

    dir = try tmp_dir.dir.openDir("test_dir", .{});
    try dir.deleteFile("test_file");
    dir.close();

    // deleting an empty directory
    try tmp_dir.dir.deleteDir("test_dir");
}

@kubkon
Copy link
Member

kubkon commented Sep 23, 2020

Nice. Here's a possible test case that can be added to std/fs/test.zig:

test "deleteDir" {
    var tmp_dir = tmpDir(.{});
    defer tmp_dir.cleanup();

    // deleting a non-existent directory
    testing.expectError(error.FileNotFound, tmp_dir.dir.deleteDir("test_dir"));

    var dir = try tmp_dir.dir.makeOpenPath("test_dir", .{});
    var file = try dir.createFile("test_file", .{});
    file.close();
    dir.close();

    // deleting a non-empty directory
    testing.expectError(error.DirNotEmpty, tmp_dir.dir.deleteDir("test_dir"));

    dir = try tmp_dir.dir.openDir("test_dir", .{});
    try dir.deleteFile("test_file");
    dir.close();

    // deleting an empty directory
    try tmp_dir.dir.deleteDir("test_dir");
}

We definitely need a test case added for this, thanks for suggesting this @squeek502!

@kubkon
Copy link
Member

kubkon commented Sep 23, 2020

@suirad, have you perhaps experimented with ReactOS approach where instead of setting FILE_DELETE_ON_CLOSE in NtCreateFile, we open the file/dir with DELETE and then mark it for deletion with NtSetInformationFile. I'm curious to see whether this will have different behaviour when trying to remove a non-empty directory, i.e., ideally yield an error of some kind rather than succeed and ignore the op altoghether.

@kubkon kubkon added os-windows standard library This issue involves writing Zig code for the standard library. labels Sep 24, 2020
@suirad
Copy link
Contributor Author

suirad commented Sep 24, 2020

I've updated the code adding @squeek502 's test and moving the non empty directory detection into std.os.windows.DeleteFile per @kubkon 's notes.

@suirad suirad changed the title Fix for Windows: std.fs.Dir.deleteDir() Fix for Windows: std.os.windows.DeleteFile() Sep 24, 2020
Copy link
Member

@kubkon kubkon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Just one more nitpick which doesn't tweak the behaviour of this PR, and we're good to go.

a proper error when attempting to delete a directory that isnt empty
@kubkon kubkon merged commit e60939b into ziglang:master Sep 27, 2020
@suirad suirad deleted the fix-5537 branch September 28, 2020 03:33
squeek502 added a commit to squeek502/zig that referenced this pull request Sep 30, 2020
Re-adds the test that was added and then reverted in ziglang#6397, but with the test for ziglang#5537 skipped for now since that issue is no longer fixed.
andrewrk pushed a commit that referenced this pull request Sep 30, 2020
Re-adds the test that was added and then reverted in #6397, but with the test for #5537 skipped for now since that issue is no longer fixed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
os-windows standard library This issue involves writing Zig code for the standard library.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants