authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2023-07-27 12:59:30-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2023-10-20 23:25:43-07:00
log63b504219d119a13731811065d18a2b10b4214b3
tree00eb29867b28f3369f7437aaf29de26009c1d772
parentc139b9d4ad68d1cb5e2c489891493232a11db76c

Dir.makeOpenPathAccessMaskW: Use path.ComponentIterator

See 49053cb1b4af7ee2973cf606def398c7eef6578b for details Also, fix leaking the intermediate directory handles.

1 files changed, 18 insertions(+), 20 deletions(-)

lib/std/fs.zig+18-20
...@@ -1490,33 +1490,31 @@ pub const Dir = struct {...@@ -1490,33 +1490,31 @@ pub const Dir = struct {
1490 /// have been modified regardless.1490 /// have been modified regardless.
1491 fn makeOpenPathAccessMaskW(self: Dir, sub_path: []const u8, access_mask: u32, no_follow: bool) OpenError!Dir {1491 fn makeOpenPathAccessMaskW(self: Dir, sub_path: []const u8, access_mask: u32, no_follow: bool) OpenError!Dir {
1492 const w = os.windows;1492 const w = os.windows;
1493 var end_index: usize = sub_path.len;1493 var it = try path.componentIterator(sub_path);
1494 // If there are no components in the path, then create a dummy component with the full path.
1495 var component = it.last() orelse path.NativeUtf8ComponentIterator.Component{
1496 .name = "",
1497 .path = sub_path,
1498 };
14941499
1495 return while (true) {1500 while (true) {
1496 const sub_path_w = try w.sliceToPrefixedFileW(sub_path[0..end_index]);1501 const sub_path_w = try w.sliceToPrefixedFileW(self.fd, component.path);
1497 const result = self.makeOpenDirAccessMaskW(sub_path_w.span().ptr, access_mask, .{1502 const is_last = it.peekNext() == null;
1503 var result = self.makeOpenDirAccessMaskW(sub_path_w.span().ptr, access_mask, .{
1498 .no_follow = no_follow,1504 .no_follow = no_follow,
1499 .create_disposition = if (end_index == sub_path.len) w.FILE_OPEN_IF else w.FILE_CREATE,1505 .create_disposition = if (is_last) w.FILE_OPEN_IF else w.FILE_CREATE,
1500 }) catch |err| switch (err) {1506 }) catch |err| switch (err) {
1501 error.FileNotFound => {1507 error.FileNotFound => |e| {
1502 // march end_index backward until next path component1508 component = it.previous() orelse return e;
1503 while (true) {
1504 if (end_index == 0) return err;
1505 end_index -= 1;
1506 if (path.isSep(sub_path[end_index])) break;
1507 }
1508 continue;1509 continue;
1509 },1510 },
1510 else => return err,1511 else => |e| return e,
1511 };1512 };
15121513
1513 if (end_index == sub_path.len) return result;1514 component = it.next() orelse return result;
1514 // march end_index forward until next path component1515 // Don't leak the intermediate file handles
1515 while (true) {1516 result.close();
1516 end_index += 1;1517 }
1517 if (end_index == sub_path.len or path.isSep(sub_path[end_index])) break;
1518 }
1519 };
1520 }1518 }
15211519
1522 /// This function performs `makePath`, followed by `openDir`.1520 /// This function performs `makePath`, followed by `openDir`.