diff options
| author | Ryan Liptak <squeek502@hotmail.com> | 2021-08-13 17:03:27 -0700 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2021-08-20 10:02:54 +0300 |
| commit | 2f6dbaa0ea7307dd6806082b07266a43db5da950 (patch) | |
| tree | c1e7c13d8d304a65e1b37d9d013ed135a2d77eb4 /lib | |
| parent | 6a5094872f10acc629543cc7f10533b438d0283a (diff) | |
| download | zig-2f6dbaa0ea7307dd6806082b07266a43db5da950.tar.gz zig-2f6dbaa0ea7307dd6806082b07266a43db5da950.zip | |
fs.Dir.walk: Do not close the initial dir during/after walking it
Closing the initial directory was unexpected to me, and does not mesh very well with how the rest of the Dir API works.
Fixes #9556
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/std/build.zig | 3 | ||||
| -rw-r--r-- | lib/std/fs.zig | 13 | ||||
| -rw-r--r-- | lib/std/fs/test.zig | 11 |
3 files changed, 15 insertions, 12 deletions
diff --git a/lib/std/build.zig b/lib/std/build.zig index efb305d4a3..b06ef55db4 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -3026,7 +3026,8 @@ pub const InstallDirStep = struct { const self = @fieldParentPtr(InstallDirStep, "step", step); const dest_prefix = self.builder.getInstallPath(self.options.install_dir, self.options.install_subdir); const full_src_dir = self.builder.pathFromRoot(self.options.source_dir); - const src_dir = try std.fs.cwd().openDir(full_src_dir, .{ .iterate = true }); + var src_dir = try std.fs.cwd().openDir(full_src_dir, .{ .iterate = true }); + defer src_dir.close(); var it = try src_dir.walk(self.builder.allocator); next_entry: while (try it.next()) |entry| { for (self.options.exclude_extensions) |ext| { diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 0d5db65011..494d871974 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -795,22 +795,31 @@ pub const Dir = struct { .kind = base.kind, }; } else { - self.stack.pop().iter.dir.close(); + var item = self.stack.pop(); + if (self.stack.items.len != 0) { + item.iter.dir.close(); + } } } return null; } pub fn deinit(self: *Walker) void { - while (self.stack.popOrNull()) |*item| item.iter.dir.close(); + while (self.stack.popOrNull()) |*item| { + if (self.stack.items.len != 0) { + item.iter.dir.close(); + } + } self.stack.deinit(); self.name_buffer.deinit(); } }; /// Recursively iterates over a directory. + /// `self` must have been opened with `OpenDirOptions{.iterate = true}`. /// Must call `Walker.deinit` when done. /// The order of returned file system entries is undefined. + /// `self` will not be closed after walking it. pub fn walk(self: Dir, allocator: *Allocator) !Walker { var name_buffer = std.ArrayList(u8).init(allocator); errdefer name_buffer.deinit(); diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 7cc43bbb36..26abbe5158 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -909,11 +909,7 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" { test "walker" { if (builtin.os.tag == .wasi) return error.SkipZigTest; - var arena = ArenaAllocator.init(testing.allocator); - defer arena.deinit(); - var allocator = &arena.allocator; - - var tmp = tmpDir(.{}); + var tmp = tmpDir(.{ .iterate = true }); defer tmp.cleanup(); // iteration order of walker is undefined, so need lookup maps to check against @@ -942,10 +938,7 @@ test "walker" { try tmp.dir.makePath(kv.key); } - const tmp_path = try fs.path.join(allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..] }); - const tmp_dir = try fs.cwd().openDir(tmp_path, .{ .iterate = true }); - - var walker = try tmp_dir.walk(testing.allocator); + var walker = try tmp.dir.walk(testing.allocator); defer walker.deinit(); var num_walked: usize = 0; |
