diff options
| author | Ryan Liptak <squeek502@hotmail.com> | 2022-07-23 20:14:34 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-07-24 12:00:14 -0700 |
| commit | 4624c818991f161fc6a7021119e4d071b6e40e6c (patch) | |
| tree | 692add57db315f0c43ab4dd1d8ebc1b7bc19dae9 /lib | |
| parent | 934573fc5db1307caf559cc485e0e557a7c655e2 (diff) | |
| download | zig-4624c818991f161fc6a7021119e4d071b6e40e6c.tar.gz zig-4624c818991f161fc6a7021119e4d071b6e40e6c.zip | |
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
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/std/fs.zig | 7 | ||||
| -rw-r--r-- | lib/std/fs/test.zig | 24 |
2 files changed, 29 insertions, 2 deletions
diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 61f79beaf6..1cf1d4533f 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -889,8 +889,11 @@ pub const IterableDir = struct { } pub fn deinit(self: *Walker) void { - for (self.stack.items) |*item| { - item.iter.dir.close(); + // Close any remaining directories except the initial one (which is always at index 0) + if (self.stack.items.len > 1) { + for (self.stack.items[1..]) |*item| { + item.iter.dir.close(); + } } self.stack.deinit(); self.name_buffer.deinit(); diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 40a004a9b1..4e2e791c9d 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -1034,6 +1034,30 @@ test "walker" { try testing.expectEqual(expected_paths.kvs.len, num_walked); } +test "walker without fully iterating" { + if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest; + if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/"); + + var tmp = tmpIterableDir(.{}); + defer tmp.cleanup(); + + var walker = try tmp.iterable_dir.walk(testing.allocator); + defer walker.deinit(); + + // Create 2 directories inside the tmp directory, but then only iterate once before breaking. + // This ensures that walker doesn't try to close the initial directory when not fully iterating. + + try tmp.iterable_dir.dir.makePath("a"); + try tmp.iterable_dir.dir.makePath("b"); + + var num_walked: usize = 0; + while (try walker.next()) |_| { + num_walked += 1; + break; + } + try testing.expectEqual(@as(usize, 1), num_walked); +} + test ". and .. in fs.Dir functions" { if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest; if (builtin.os.tag == .wasi and !builtin.link_libc) try os.initPreopensWasi(std.heap.page_allocator, "/"); |
