Skip to content

Commit

Permalink
Dir.makeOpenPathAccessMaskW: Use path.ComponentIterator
Browse files Browse the repository at this point in the history
See 49053cb for details

Also, fix leaking the intermediate directory handles.
  • Loading branch information
squeek502 authored and andrewrk committed Oct 19, 2023
1 parent c139b9d commit 4484f28
Showing 1 changed file with 18 additions and 20 deletions.
38 changes: 18 additions & 20 deletions lib/std/fs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1490,33 +1490,31 @@ pub const Dir = struct {
/// have been modified regardless.
fn makeOpenPathAccessMaskW(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;
var it = try path.componentIterator(sub_path);
// If there are no components in the path, then create a dummy component with the full path.
var component = it.last() orelse path.NativeUtf8ComponentIterator.Component{
.name = "",
.path = sub_path,
};

return while (true) {
const sub_path_w = try w.sliceToPrefixedFileW(sub_path[0..end_index]);
const result = self.makeOpenDirAccessMaskW(sub_path_w.span().ptr, access_mask, .{
while (true) {
const sub_path_w = try w.sliceToPrefixedFileW(component.path);
const is_last = it.peekNext() == null;
var result = self.makeOpenDirAccessMaskW(sub_path_w.span().ptr, access_mask, .{
.no_follow = no_follow,
.create_disposition = if (end_index == sub_path.len) w.FILE_OPEN_IF else w.FILE_CREATE,
.create_disposition = if (is_last) w.FILE_OPEN_IF else w.FILE_CREATE,
}) catch |err| switch (err) {
error.FileNotFound => {
// march end_index backward until next path component
while (true) {
if (end_index == 0) return err;
end_index -= 1;
if (path.isSep(sub_path[end_index])) break;
}
error.FileNotFound => |e| {
component = it.previous() orelse return e;
continue;
},
else => return err,
else => |e| return e,
};

if (end_index == sub_path.len) return result;
// march end_index forward until next path component
while (true) {
end_index += 1;
if (end_index == sub_path.len or path.isSep(sub_path[end_index])) break;
}
};
component = it.next() orelse return result;
// Don't leak the intermediate file handles
result.close();
}
}

/// This function performs `makePath`, followed by `openDir`.
Expand Down

0 comments on commit 4484f28

Please sign in to comment.