aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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, "/");