aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRyan Liptak <squeek502@hotmail.com>2021-08-13 17:03:27 -0700
committerVeikka Tuominen <git@vexu.eu>2021-08-20 10:02:54 +0300
commit2f6dbaa0ea7307dd6806082b07266a43db5da950 (patch)
treec1e7c13d8d304a65e1b37d9d013ed135a2d77eb4 /lib
parent6a5094872f10acc629543cc7f10533b438d0283a (diff)
downloadzig-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.zig3
-rw-r--r--lib/std/fs.zig13
-rw-r--r--lib/std/fs/test.zig11
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;