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

This is a fix for a regression caused by 61c5d8f8f1

Closes #12209
This commit is contained in:
Ryan Liptak 2022-07-23 20:14:34 -07:00 committed by Andrew Kelley
parent 934573fc5d
commit 4624c81899
2 changed files with 29 additions and 2 deletions

View File

@ -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();

View File

@ -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, "/");