aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRyan Liptak <squeek502@hotmail.com>2022-07-23 20:14:34 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-07-24 12:00:14 -0700
commit4624c818991f161fc6a7021119e4d071b6e40e6c (patch)
tree692add57db315f0c43ab4dd1d8ebc1b7bc19dae9 /lib
parent934573fc5db1307caf559cc485e0e557a7c655e2 (diff)
downloadzig-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.zig7
-rw-r--r--lib/std/fs/test.zig24
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, "/");