authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2022-07-23 20:14:34-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-24 12:00:14-07:00
log4624c818991f161fc6a7021119e4d071b6e40e6c
tree692add57db315f0c43ab4dd1d8ebc1b7bc19dae9
parent934573fc5db1307caf559cc485e0e557a7c655e2

std.fs: Fix Walker closing the initial directory when not fully iterated

This is a fix for a regression caused by https://github.com/ziglang/zig/commit/61c5d8f8f19d4321a492cb8a1adc4d221024f7d9 Closes #12209

2 files changed, 29 insertions(+), 2 deletions(-)

lib/std/fs.zig+5-2
...@@ -889,8 +889,11 @@ pub const IterableDir = struct {...@@ -889,8 +889,11 @@ pub const IterableDir = struct {
889 }889 }
890890
891 pub fn deinit(self: *Walker) void {891 pub fn deinit(self: *Walker) void {
892 for (self.stack.items) |*item| {892 // Close any remaining directories except the initial one (which is always at index 0)
893 item.iter.dir.close();893 if (self.stack.items.len > 1) {
894 for (self.stack.items[1..]) |*item| {
895 item.iter.dir.close();
896 }
894 }897 }
895 self.stack.deinit();898 self.stack.deinit();
896 self.name_buffer.deinit();899 self.name_buffer.deinit();
lib/std/fs/test.zig+24
...@@ -1034,6 +1034,30 @@ test "walker" {...@@ -1034,6 +1034,30 @@ test "walker" {
1034 try testing.expectEqual(expected_paths.kvs.len, num_walked);1034 try testing.expectEqual(expected_paths.kvs.len, num_walked);
1035}1035}
10361036
1037test "walker without fully iterating" {
1038 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
1039 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");
1040
1041 var tmp = tmpIterableDir(.{});
1042 defer tmp.cleanup();
1043
1044 var walker = try tmp.iterable_dir.walk(testing.allocator);
1045 defer walker.deinit();
1046
1047 // Create 2 directories inside the tmp directory, but then only iterate once before breaking.
1048 // This ensures that walker doesn't try to close the initial directory when not fully iterating.
1049
1050 try tmp.iterable_dir.dir.makePath("a");
1051 try tmp.iterable_dir.dir.makePath("b");
1052
1053 var num_walked: usize = 0;
1054 while (try walker.next()) |_| {
1055 num_walked += 1;
1056 break;
1057 }
1058 try testing.expectEqual(@as(usize, 1), num_walked);
1059}
1060
1037test ". and .. in fs.Dir functions" {1061test ". and .. in fs.Dir functions" {
1038 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;1062 if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
1039 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");1063 if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/");