Skip to content

Commit

Permalink
#12474: Code improvement and add a new test case
Browse files Browse the repository at this point in the history
  • Loading branch information
QusaiHroub committed Mar 17, 2023
1 parent d26f53f commit 00acf66
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
24 changes: 18 additions & 6 deletions lib/std/fs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1465,6 +1465,11 @@ pub const Dir = struct {
}
}

/// Calls openDirWithAccessAndCreationW recursively to make an entire path
/// (i.e. falling back if the parent directory does not exist). Opens the dir if the path
/// already exists and is a directory.
/// This function is not atomic, and if it returns an error, the file system may
/// have been modified regardless.
fn openDirAccessMaskW(self: Dir, sub_path: []const u8, access_mask: u32, no_follow: bool) OpenError!Dir {
const w = os.windows;
var end_index: usize = sub_path.len;
Expand Down Expand Up @@ -1499,6 +1504,7 @@ pub const Dir = struct {
/// This function performs `makePath`, followed by `openDir`.
/// If supported by the OS, this operation is atomic. It is not atomic on
/// all operating systems.
/// On Windows, this function preforms `openDirAccessMaskW`.
pub fn makeOpenPath(self: Dir, sub_path: []const u8, open_dir_options: OpenDirOptions) !Dir {
return switch (builtin.os.tag) {
.windows => {
Expand All @@ -1509,9 +1515,12 @@ pub const Dir = struct {
return self.openDirAccessMaskW(sub_path, base_flags, open_dir_options.no_follow);
},
else => {
return self.openDir(sub_path, open_dir_options) catch {
try self.makePath(sub_path);
return self.openDir(sub_path, open_dir_options);
return self.openDir(sub_path, open_dir_options) catch |err| switch (err) {
error.FileNotFound => {
try self.makePath(sub_path);
return self.openDir(sub_path, open_dir_options);
},
else => |e| return e,
};
},
};
Expand All @@ -1532,9 +1541,12 @@ pub const Dir = struct {
};
},
else => {
return self.openIterableDir(sub_path, open_dir_options) catch {
try self.makePath(sub_path);
return self.openIterableDir(sub_path, open_dir_options);
return self.openIterableDir(sub_path, open_dir_options) catch |err| switch (err) {
error.FileNotFound => {
try self.makePath(sub_path);
return self.openIterableDir(sub_path, open_dir_options);
},
else => |e| return e,
};
},
};
Expand Down
7 changes: 7 additions & 0 deletions lib/std/fs/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,13 @@ test "file operations on directories" {
dir.close();
}

test "makeOpenPath parent dirs do not exist" {
if (builtin.os.tag == .wasi) return error.SkipZigTest;

var dir = try fs.cwd().makeOpenPath("root_dir/parent_dir/some_dir", .{});
defer dir.close();
}

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

0 comments on commit 00acf66

Please sign in to comment.