authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-08 13:46:29-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-23 22:15:08-08:00
log264d714321d3e5f1f189af393e1fb24d101a7e91
treecb637a9c8c8565790db5b8cbcd1e960f88523da1
parentf53248a40936ebc9aaf75ddbd16e67ebec05ab84

update all openDir() sites to accept io instance


21 files changed, 107 insertions(+), 92 deletions(-)

lib/compiler/aro/aro/Driver/Filesystem.zig+2-2
...@@ -223,9 +223,9 @@ pub const Filesystem = union(enum) {...@@ -223,9 +223,9 @@ pub const Filesystem = union(enum) {
223 };223 };
224 }224 }
225225
226 pub fn openDir(fs: Filesystem, dir_name: []const u8) std.Io.Dir.OpenError!Dir {226 pub fn openDir(fs: Filesystem, io: Io, dir_name: []const u8) std.Io.Dir.OpenError!Dir {
227 return switch (fs) {227 return switch (fs) {
228 .real => |cwd| .{ .dir = try cwd.openDir(dir_name, .{ .access_sub_paths = false, .iterate = true }) },228 .real => |cwd| .{ .dir = try cwd.openDir(io, dir_name, .{ .access_sub_paths = false, .iterate = true }) },
229 .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } },229 .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } },
230 };230 };
231 }231 }
lib/compiler/aro/aro/Toolchain.zig+1-1
...@@ -509,7 +509,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void {...@@ -509,7 +509,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void {
509 }509 }
510 var search_path = d.aro_name;510 var search_path = d.aro_name;
511 while (std.fs.path.dirname(search_path)) |dirname| : (search_path = dirname) {511 while (std.fs.path.dirname(search_path)) |dirname| : (search_path = dirname) {
512 var base_dir = d.comp.cwd.openDir(dirname, .{}) catch continue;512 var base_dir = d.comp.cwd.openDir(io, dirname, .{}) catch continue;
513 defer base_dir.close(io);513 defer base_dir.close(io);
514514
515 base_dir.access("include/stddef.h", .{}) catch continue;515 base_dir.access("include/stddef.h", .{}) catch continue;
lib/compiler/resinator/compile.zig+7-7
...@@ -106,13 +106,13 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io...@@ -106,13 +106,13 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io
106 // If dirname returns null, then the root path will be the same as106 // If dirname returns null, then the root path will be the same as
107 // the cwd so we don't need to add it as a distinct search path.107 // the cwd so we don't need to add it as a distinct search path.
108 if (std.fs.path.dirname(root_path)) |root_dir_path| {108 if (std.fs.path.dirname(root_path)) |root_dir_path| {
109 var root_dir = try options.cwd.openDir(root_dir_path, .{});109 var root_dir = try options.cwd.openDir(io, root_dir_path, .{});
110 errdefer root_dir.close(io);110 errdefer root_dir.close(io);
111 try search_dirs.append(allocator, .{ .dir = root_dir, .path = try allocator.dupe(u8, root_dir_path) });111 try search_dirs.append(allocator, .{ .dir = root_dir, .path = try allocator.dupe(u8, root_dir_path) });
112 }112 }
113 }113 }
114 // Re-open the passed in cwd since we want to be able to close it (Io.Dir.cwd() shouldn't be closed)114 // Re-open the passed in cwd since we want to be able to close it (Io.Dir.cwd() shouldn't be closed)
115 const cwd_dir = options.cwd.openDir(".", .{}) catch |err| {115 const cwd_dir = options.cwd.openDir(io, ".", .{}) catch |err| {
116 try options.diagnostics.append(.{116 try options.diagnostics.append(.{
117 .err = .failed_to_open_cwd,117 .err = .failed_to_open_cwd,
118 .token = .{118 .token = .{
...@@ -132,7 +132,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io...@@ -132,7 +132,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io
132 };132 };
133 try search_dirs.append(allocator, .{ .dir = cwd_dir, .path = null });133 try search_dirs.append(allocator, .{ .dir = cwd_dir, .path = null });
134 for (options.extra_include_paths) |extra_include_path| {134 for (options.extra_include_paths) |extra_include_path| {
135 var dir = openSearchPathDir(options.cwd, extra_include_path) catch {135 var dir = openSearchPathDir(options.cwd, io, extra_include_path) catch {
136 // TODO: maybe a warning that the search path is skipped?136 // TODO: maybe a warning that the search path is skipped?
137 continue;137 continue;
138 };138 };
...@@ -140,7 +140,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io...@@ -140,7 +140,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io
140 try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, extra_include_path) });140 try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, extra_include_path) });
141 }141 }
142 for (options.system_include_paths) |system_include_path| {142 for (options.system_include_paths) |system_include_path| {
143 var dir = openSearchPathDir(options.cwd, system_include_path) catch {143 var dir = openSearchPathDir(options.cwd, io, system_include_path) catch {
144 // TODO: maybe a warning that the search path is skipped?144 // TODO: maybe a warning that the search path is skipped?
145 continue;145 continue;
146 };146 };
...@@ -159,7 +159,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io...@@ -159,7 +159,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io
159 };159 };
160 var it = std.mem.tokenizeScalar(u8, INCLUDE, delimiter);160 var it = std.mem.tokenizeScalar(u8, INCLUDE, delimiter);
161 while (it.next()) |search_path| {161 while (it.next()) |search_path| {
162 var dir = openSearchPathDir(options.cwd, search_path) catch continue;162 var dir = openSearchPathDir(options.cwd, io, search_path) catch continue;
163 errdefer dir.close(io);163 errdefer dir.close(io);
164 try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, search_path) });164 try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, search_path) });
165 }165 }
...@@ -2896,11 +2896,11 @@ pub const Compiler = struct {...@@ -2896,11 +2896,11 @@ pub const Compiler = struct {
28962896
2897pub const OpenSearchPathError = std.Io.Dir.OpenError;2897pub const OpenSearchPathError = std.Io.Dir.OpenError;
28982898
2899fn openSearchPathDir(dir: std.Io.Dir, path: []const u8) OpenSearchPathError!std.Io.Dir {2899fn openSearchPathDir(dir: std.Io.Dir, io: Io, path: []const u8) OpenSearchPathError!std.Io.Dir {
2900 // Validate the search path to avoid possible unreachable on invalid paths,2900 // Validate the search path to avoid possible unreachable on invalid paths,
2901 // see https://github.com/ziglang/zig/issues/15607 for why this is currently necessary.2901 // see https://github.com/ziglang/zig/issues/15607 for why this is currently necessary.
2902 try validateSearchPath(path);2902 try validateSearchPath(path);
2903 return dir.openDir(path, .{});2903 return dir.openDir(io, path, .{});
2904}2904}
29052905
2906/// Very crude attempt at validating a path. This is imperfect2906/// Very crude attempt at validating a path. This is imperfect
lib/compiler/std-docs.zig+2-2
...@@ -40,7 +40,7 @@ pub fn main() !void {...@@ -40,7 +40,7 @@ pub fn main() !void {
40 const zig_exe_path = argv.next().?;40 const zig_exe_path = argv.next().?;
41 const global_cache_path = argv.next().?;41 const global_cache_path = argv.next().?;
4242
43 var lib_dir = try Io.Dir.cwd().openDir(zig_lib_directory, .{});43 var lib_dir = try Io.Dir.cwd().openDir(io, zig_lib_directory, .{});
44 defer lib_dir.close(io);44 defer lib_dir.close(io);
4545
46 var listen_port: u16 = 0;46 var listen_port: u16 = 0;
...@@ -206,7 +206,7 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void {...@@ -206,7 +206,7 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void {
206 },206 },
207 });207 });
208208
209 var std_dir = try context.lib_dir.openDir("std", .{ .iterate = true });209 var std_dir = try context.lib_dir.openDir(io, "std", .{ .iterate = true });
210 defer std_dir.close(io);210 defer std_dir.close(io);
211211
212 var walker = try std_dir.walk(gpa);212 var walker = try std_dir.walk(gpa);
lib/std/Build.zig+2-1
...@@ -2184,6 +2184,7 @@ fn dependencyInner(...@@ -2184,6 +2184,7 @@ fn dependencyInner(
2184 pkg_deps: AvailableDeps,2184 pkg_deps: AvailableDeps,
2185 args: anytype,2185 args: anytype,
2186) *Dependency {2186) *Dependency {
2187 const io = b.graph.io;
2187 const user_input_options = userInputOptionsFromArgs(b.allocator, args);2188 const user_input_options = userInputOptionsFromArgs(b.allocator, args);
2188 if (b.graph.dependency_cache.getContext(.{2189 if (b.graph.dependency_cache.getContext(.{
2189 .build_root_string = build_root_string,2190 .build_root_string = build_root_string,
...@@ -2193,7 +2194,7 @@ fn dependencyInner(...@@ -2193,7 +2194,7 @@ fn dependencyInner(
21932194
2194 const build_root: std.Build.Cache.Directory = .{2195 const build_root: std.Build.Cache.Directory = .{
2195 .path = build_root_string,2196 .path = build_root_string,
2196 .handle = Io.Dir.cwd().openDir(build_root_string, .{}) catch |err| {2197 .handle = Io.Dir.cwd().openDir(io, build_root_string, .{}) catch |err| {
2197 std.debug.print("unable to open '{s}': {s}\n", .{2198 std.debug.print("unable to open '{s}': {s}\n", .{
2198 build_root_string, @errorName(err),2199 build_root_string, @errorName(err),
2199 });2200 });
lib/std/Build/Cache/Path.zig+2-1
...@@ -71,6 +71,7 @@ pub fn openFile(p: Path, io: Io, sub_path: []const u8, flags: Io.File.OpenFlags)...@@ -71,6 +71,7 @@ pub fn openFile(p: Path, io: Io, sub_path: []const u8, flags: Io.File.OpenFlags)
7171
72pub fn openDir(72pub fn openDir(
73 p: Path,73 p: Path,
74 io: Io,
74 sub_path: []const u8,75 sub_path: []const u8,
75 args: Io.Dir.OpenOptions,76 args: Io.Dir.OpenOptions,
76) Io.Dir.OpenError!Io.Dir {77) Io.Dir.OpenError!Io.Dir {
...@@ -80,7 +81,7 @@ pub fn openDir(...@@ -80,7 +81,7 @@ pub fn openDir(
80 p.sub_path, sub_path,81 p.sub_path, sub_path,
81 }) catch return error.NameTooLong;82 }) catch return error.NameTooLong;
82 };83 };
83 return p.root_dir.handle.openDir(joined_path, args);84 return p.root_dir.handle.openDir(io, joined_path, args);
84}85}
8586
86pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: Io.Dir.OpenOptions) !Io.Dir {87pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: Io.Dir.OpenOptions) !Io.Dir {
lib/std/Build/Step/InstallArtifact.zig+1-1
...@@ -164,7 +164,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {...@@ -164,7 +164,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
164 const src_dir_path = dir.source.getPath3(b, step);164 const src_dir_path = dir.source.getPath3(b, step);
165 const full_h_prefix = b.getInstallPath(h_dir, dir.dest_rel_path);165 const full_h_prefix = b.getInstallPath(h_dir, dir.dest_rel_path);
166166
167 var src_dir = src_dir_path.root_dir.handle.openDir(src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| {167 var src_dir = src_dir_path.root_dir.handle.openDir(io, src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| {
168 return step.fail("unable to open source directory '{f}': {s}", .{168 return step.fail("unable to open source directory '{f}': {s}", .{
169 src_dir_path, @errorName(err),169 src_dir_path, @errorName(err),
170 });170 });
lib/std/Build/Step/WriteFile.zig+1-1
...@@ -218,7 +218,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {...@@ -218,7 +218,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
218 const need_derived_inputs = try step.addDirectoryWatchInput(dir.source);218 const need_derived_inputs = try step.addDirectoryWatchInput(dir.source);
219 const src_dir_path = dir.source.getPath3(b, step);219 const src_dir_path = dir.source.getPath3(b, step);
220220
221 var src_dir = src_dir_path.root_dir.handle.openDir(src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| {221 var src_dir = src_dir_path.root_dir.handle.openDir(io, src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| {
222 return step.fail("unable to open source directory '{f}': {s}", .{222 return step.fail("unable to open source directory '{f}': {s}", .{
223 src_dir_path, @errorName(err),223 src_dir_path, @errorName(err),
224 });224 });
lib/std/Io/Dir.zig+5-5
...@@ -234,7 +234,7 @@ pub const SelectiveWalker = struct {...@@ -234,7 +234,7 @@ pub const SelectiveWalker = struct {
234 return;234 return;
235 }235 }
236236
237 var new_dir = entry.dir.openDir(entry.basename, .{ .iterate = true }) catch |err| {237 var new_dir = entry.dir.openDir(io, entry.basename, .{ .iterate = true }) catch |err| {
238 switch (err) {238 switch (err) {
239 error.NameTooLong => unreachable,239 error.NameTooLong => unreachable,
240 else => |e| return e,240 else => |e| return e,
...@@ -1326,7 +1326,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void {...@@ -1326,7 +1326,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void {
1326 var treat_as_dir = true;1326 var treat_as_dir = true;
1327 handle_entry: while (true) {1327 handle_entry: while (true) {
1328 if (treat_as_dir) {1328 if (treat_as_dir) {
1329 break :iterable_dir parent_dir.openDir(name, .{1329 break :iterable_dir parent_dir.openDir(io, name, .{
1330 .follow_symlinks = false,1330 .follow_symlinks = false,
1331 .iterate = true,1331 .iterate = true,
1332 }) catch |err| switch (err) {1332 }) catch |err| switch (err) {
...@@ -1430,7 +1430,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8,...@@ -1430,7 +1430,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8,
1430 var treat_as_dir = entry.kind == .directory;1430 var treat_as_dir = entry.kind == .directory;
1431 handle_entry: while (true) {1431 handle_entry: while (true) {
1432 if (treat_as_dir) {1432 if (treat_as_dir) {
1433 const new_dir = dir.openDir(entry.name, .{1433 const new_dir = dir.openDir(io, entry.name, .{
1434 .follow_symlinks = false,1434 .follow_symlinks = false,
1435 .iterate = true,1435 .iterate = true,
1436 }) catch |err| switch (err) {1436 }) catch |err| switch (err) {
...@@ -1520,14 +1520,14 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8,...@@ -1520,14 +1520,14 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8,
1520}1520}
15211521
1522/// On successful delete, returns null.1522/// On successful delete, returns null.
1523fn deleteTreeOpenInitialSubpath(dir: Dir, sub_path: []const u8, kind_hint: File.Kind) !?Dir {1523fn deleteTreeOpenInitialSubpath(dir: Dir, io: Io, sub_path: []const u8, kind_hint: File.Kind) !?Dir {
1524 return iterable_dir: {1524 return iterable_dir: {
1525 // Treat as a file by default1525 // Treat as a file by default
1526 var treat_as_dir = kind_hint == .directory;1526 var treat_as_dir = kind_hint == .directory;
15271527
1528 handle_entry: while (true) {1528 handle_entry: while (true) {
1529 if (treat_as_dir) {1529 if (treat_as_dir) {
1530 break :iterable_dir dir.openDir(sub_path, .{1530 break :iterable_dir dir.openDir(io, sub_path, .{
1531 .follow_symlinks = false,1531 .follow_symlinks = false,
1532 .iterate = true,1532 .iterate = true,
1533 }) catch |err| switch (err) {1533 }) catch |err| switch (err) {
lib/std/crypto/Certificate/Bundle.zig+1-1
...@@ -180,7 +180,7 @@ pub fn addCertsFromDirPath(...@@ -180,7 +180,7 @@ pub fn addCertsFromDirPath(
180 dir: Io.Dir,180 dir: Io.Dir,
181 sub_dir_path: []const u8,181 sub_dir_path: []const u8,
182) AddCertsFromDirPathError!void {182) AddCertsFromDirPathError!void {
183 var iterable_dir = try dir.openDir(sub_dir_path, .{ .iterate = true });183 var iterable_dir = try dir.openDir(io, sub_dir_path, .{ .iterate = true });
184 defer iterable_dir.close(io);184 defer iterable_dir.close(io);
185 return addCertsFromDir(cb, gpa, io, iterable_dir);185 return addCertsFromDir(cb, gpa, io, iterable_dir);
186}186}
lib/std/crypto/codecs/asn1/test.zig+1-1
...@@ -73,7 +73,7 @@ test AllTypes {...@@ -73,7 +73,7 @@ test AllTypes {
73 try std.testing.expectEqualSlices(u8, encoded, buf);73 try std.testing.expectEqualSlices(u8, encoded, buf);
7474
75 // Use this to update test file.75 // Use this to update test file.
76 // const dir = try Io.Dir.cwd().openDir("lib/std/crypto/asn1", .{});76 // const dir = try Io.Dir.cwd().openDir(io, "lib/std/crypto/asn1", .{});
77 // var file = try dir.createFile(io, path, .{});77 // var file = try dir.createFile(io, path, .{});
78 // defer file.close(io);78 // defer file.close(io);
79 // try file.writeAll(buf);79 // try file.writeAll(buf);
lib/std/dynamic_library.zig+3-3
...@@ -160,9 +160,9 @@ pub const ElfDynLib = struct {...@@ -160,9 +160,9 @@ pub const ElfDynLib = struct {
160 fn openPath(path: []const u8, io: Io) !Io.Dir {160 fn openPath(path: []const u8, io: Io) !Io.Dir {
161 if (path.len == 0) return error.NotDir;161 if (path.len == 0) return error.NotDir;
162 var parts = std.mem.tokenizeScalar(u8, path, '/');162 var parts = std.mem.tokenizeScalar(u8, path, '/');
163 var parent = if (path[0] == '/') try Io.Dir.cwd().openDir("/", .{}) else Io.Dir.cwd();163 var parent = if (path[0] == '/') try Io.Dir.cwd().openDir(io, "/", .{}) else Io.Dir.cwd();
164 while (parts.next()) |part| {164 while (parts.next()) |part| {
165 const child = try parent.openDir(part, .{});165 const child = try parent.openDir(io, part, .{});
166 parent.close(io);166 parent.close(io);
167 parent = child;167 parent = child;
168 }168 }
...@@ -184,7 +184,7 @@ pub const ElfDynLib = struct {...@@ -184,7 +184,7 @@ pub const ElfDynLib = struct {
184 }184 }
185185
186 fn resolveFromParent(io: Io, dir_path: []const u8, file_name: []const u8) ?posix.fd_t {186 fn resolveFromParent(io: Io, dir_path: []const u8, file_name: []const u8) ?posix.fd_t {
187 var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch return null;187 var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch return null;
188 defer dir.close(io);188 defer dir.close(io);
189 return posix.openat(dir.handle, file_name, .{189 return posix.openat(dir.handle, file_name, .{
190 .ACCMODE = .RDONLY,190 .ACCMODE = .RDONLY,
lib/std/fs/test.zig+28-26
...@@ -367,7 +367,7 @@ test "openDir" {...@@ -367,7 +367,7 @@ test "openDir" {
367367
368 for ([_][]const u8{ "", ".", ".." }) |sub_path| {368 for ([_][]const u8{ "", ".", ".." }) |sub_path| {
369 const dir_path = try fs.path.join(allocator, &.{ subdir_path, sub_path });369 const dir_path = try fs.path.join(allocator, &.{ subdir_path, sub_path });
370 var dir = try ctx.dir.openDir(dir_path, .{});370 var dir = try ctx.dir.openDir(io, dir_path, .{});
371 defer dir.close(io);371 defer dir.close(io);
372 }372 }
373 }373 }
...@@ -448,7 +448,7 @@ test "openDirAbsolute" {...@@ -448,7 +448,7 @@ test "openDirAbsolute" {
448test "openDir cwd parent '..'" {448test "openDir cwd parent '..'" {
449 const io = testing.io;449 const io = testing.io;
450450
451 var dir = Io.Dir.cwd().openDir("..", .{}) catch |err| {451 var dir = Io.Dir.cwd().openDir(io, "..", .{}) catch |err| {
452 if (native_os == .wasi and err == error.PermissionDenied) {452 if (native_os == .wasi and err == error.PermissionDenied) {
453 return; // This is okay. WASI disallows escaping from the fs sandbox453 return; // This is okay. WASI disallows escaping from the fs sandbox
454 }454 }
...@@ -471,7 +471,7 @@ test "openDir non-cwd parent '..'" {...@@ -471,7 +471,7 @@ test "openDir non-cwd parent '..'" {
471 var subdir = try tmp.dir.makeOpenPath("subdir", .{});471 var subdir = try tmp.dir.makeOpenPath("subdir", .{});
472 defer subdir.close(io);472 defer subdir.close(io);
473473
474 var dir = try subdir.openDir("..", .{});474 var dir = try subdir.openDir(io, "..", .{});
475 defer dir.close(io);475 defer dir.close(io);
476476
477 const expected_path = try tmp.dir.realpathAlloc(testing.allocator, ".");477 const expected_path = try tmp.dir.realpathAlloc(testing.allocator, ".");
...@@ -839,7 +839,7 @@ test "directory operations on files" {...@@ -839,7 +839,7 @@ test "directory operations on files" {
839 file.close(io);839 file.close(io);
840840
841 try testing.expectError(error.PathAlreadyExists, ctx.dir.makeDir(test_file_name));841 try testing.expectError(error.PathAlreadyExists, ctx.dir.makeDir(test_file_name));
842 try testing.expectError(error.NotDir, ctx.dir.openDir(test_file_name, .{}));842 try testing.expectError(error.NotDir, ctx.dir.openDir(io, test_file_name, .{}));
843 try testing.expectError(error.NotDir, ctx.dir.deleteDir(test_file_name));843 try testing.expectError(error.NotDir, ctx.dir.deleteDir(test_file_name));
844844
845 if (ctx.path_type == .absolute and comptime PathType.absolute.isSupported(builtin.os)) {845 if (ctx.path_type == .absolute and comptime PathType.absolute.isSupported(builtin.os)) {
...@@ -902,7 +902,7 @@ test "file operations on directories" {...@@ -902,7 +902,7 @@ test "file operations on directories" {
902 }902 }
903903
904 // ensure the directory still exists as a sanity check904 // ensure the directory still exists as a sanity check
905 var dir = try ctx.dir.openDir(test_dir_name, .{});905 var dir = try ctx.dir.openDir(io, test_dir_name, .{});
906 dir.close(io);906 dir.close(io);
907 }907 }
908 }.impl);908 }.impl);
...@@ -918,7 +918,7 @@ test "makeOpenPath parent dirs do not exist" {...@@ -918,7 +918,7 @@ test "makeOpenPath parent dirs do not exist" {
918 dir.close(io);918 dir.close(io);
919919
920 // double check that the full directory structure was created920 // double check that the full directory structure was created
921 var dir_verification = try tmp_dir.dir.openDir("root_dir/parent_dir/some_dir", .{});921 var dir_verification = try tmp_dir.dir.openDir(io, "root_dir/parent_dir/some_dir", .{});
922 dir_verification.close(io);922 dir_verification.close(io);
923}923}
924924
...@@ -1005,8 +1005,8 @@ test "Dir.rename directories" {...@@ -1005,8 +1005,8 @@ test "Dir.rename directories" {
1005 try ctx.dir.rename(test_dir_path, test_dir_renamed_path);1005 try ctx.dir.rename(test_dir_path, test_dir_renamed_path);
10061006
1007 // Ensure the directory was renamed1007 // Ensure the directory was renamed
1008 try testing.expectError(error.FileNotFound, ctx.dir.openDir(test_dir_path, .{}));1008 try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, test_dir_path, .{}));
1009 var dir = try ctx.dir.openDir(test_dir_renamed_path, .{});1009 var dir = try ctx.dir.openDir(io, test_dir_renamed_path, .{});
10101010
1011 // Put a file in the directory1011 // Put a file in the directory
1012 var file = try dir.createFile(io, "test_file", .{ .read = true });1012 var file = try dir.createFile(io, "test_file", .{ .read = true });
...@@ -1017,8 +1017,8 @@ test "Dir.rename directories" {...@@ -1017,8 +1017,8 @@ test "Dir.rename directories" {
1017 try ctx.dir.rename(test_dir_renamed_path, test_dir_renamed_again_path);1017 try ctx.dir.rename(test_dir_renamed_path, test_dir_renamed_again_path);
10181018
1019 // Ensure the directory was renamed and the file still exists in it1019 // Ensure the directory was renamed and the file still exists in it
1020 try testing.expectError(error.FileNotFound, ctx.dir.openDir(test_dir_renamed_path, .{}));1020 try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, test_dir_renamed_path, .{}));
1021 dir = try ctx.dir.openDir(test_dir_renamed_again_path, .{});1021 dir = try ctx.dir.openDir(io, test_dir_renamed_again_path, .{});
1022 file = try dir.openFile(io, "test_file", .{});1022 file = try dir.openFile(io, "test_file", .{});
1023 file.close(io);1023 file.close(io);
1024 dir.close(io);1024 dir.close(io);
...@@ -1042,8 +1042,8 @@ test "Dir.rename directory onto empty dir" {...@@ -1042,8 +1042,8 @@ test "Dir.rename directory onto empty dir" {
1042 try ctx.dir.rename(test_dir_path, target_dir_path);1042 try ctx.dir.rename(test_dir_path, target_dir_path);
10431043
1044 // Ensure the directory was renamed1044 // Ensure the directory was renamed
1045 try testing.expectError(error.FileNotFound, ctx.dir.openDir(test_dir_path, .{}));1045 try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, test_dir_path, .{}));
1046 var dir = try ctx.dir.openDir(target_dir_path, .{});1046 var dir = try ctx.dir.openDir(io, target_dir_path, .{});
1047 dir.close(io);1047 dir.close(io);
1048 }1048 }
1049 }.impl);1049 }.impl);
...@@ -1070,7 +1070,7 @@ test "Dir.rename directory onto non-empty dir" {...@@ -1070,7 +1070,7 @@ test "Dir.rename directory onto non-empty dir" {
1070 try testing.expectError(error.PathAlreadyExists, ctx.dir.rename(test_dir_path, target_dir_path));1070 try testing.expectError(error.PathAlreadyExists, ctx.dir.rename(test_dir_path, target_dir_path));
10711071
1072 // Ensure the directory was not renamed1072 // Ensure the directory was not renamed
1073 var dir = try ctx.dir.openDir(test_dir_path, .{});1073 var dir = try ctx.dir.openDir(io, test_dir_path, .{});
1074 dir.close(io);1074 dir.close(io);
1075 }1075 }
1076 }.impl);1076 }.impl);
...@@ -1165,8 +1165,8 @@ test "renameAbsolute" {...@@ -1165,8 +1165,8 @@ test "renameAbsolute" {
1165 );1165 );
11661166
1167 // ensure the directory was renamed1167 // ensure the directory was renamed
1168 try testing.expectError(error.FileNotFound, tmp_dir.dir.openDir(test_dir_name, .{}));1168 try testing.expectError(error.FileNotFound, tmp_dir.dir.openDir(io, test_dir_name, .{}));
1169 var dir = try tmp_dir.dir.openDir(renamed_test_dir_name, .{});1169 var dir = try tmp_dir.dir.openDir(io, renamed_test_dir_name, .{});
1170 dir.close(io);1170 dir.close(io);
1171}1171}
11721172
...@@ -1234,6 +1234,7 @@ test "deleteTree on a symlink" {...@@ -1234,6 +1234,7 @@ test "deleteTree on a symlink" {
1234test "makePath, put some files in it, deleteTree" {1234test "makePath, put some files in it, deleteTree" {
1235 try testWithAllSupportedPathTypes(struct {1235 try testWithAllSupportedPathTypes(struct {
1236 fn impl(ctx: *TestContext) !void {1236 fn impl(ctx: *TestContext) !void {
1237 const io = ctx.io;
1237 const allocator = ctx.arena.allocator();1238 const allocator = ctx.arena.allocator();
1238 const dir_path = try ctx.transformPath("os_test_tmp");1239 const dir_path = try ctx.transformPath("os_test_tmp");
12391240
...@@ -1248,7 +1249,7 @@ test "makePath, put some files in it, deleteTree" {...@@ -1248,7 +1249,7 @@ test "makePath, put some files in it, deleteTree" {
1248 });1249 });
12491250
1250 try ctx.dir.deleteTree(dir_path);1251 try ctx.dir.deleteTree(dir_path);
1251 try testing.expectError(error.FileNotFound, ctx.dir.openDir(dir_path, .{}));1252 try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, dir_path, .{}));
1252 }1253 }
1253 }.impl);1254 }.impl);
1254}1255}
...@@ -1256,6 +1257,7 @@ test "makePath, put some files in it, deleteTree" {...@@ -1256,6 +1257,7 @@ test "makePath, put some files in it, deleteTree" {
1256test "makePath, put some files in it, deleteTreeMinStackSize" {1257test "makePath, put some files in it, deleteTreeMinStackSize" {
1257 try testWithAllSupportedPathTypes(struct {1258 try testWithAllSupportedPathTypes(struct {
1258 fn impl(ctx: *TestContext) !void {1259 fn impl(ctx: *TestContext) !void {
1260 const io = ctx.io;
1259 const allocator = ctx.arena.allocator();1261 const allocator = ctx.arena.allocator();
1260 const dir_path = try ctx.transformPath("os_test_tmp");1262 const dir_path = try ctx.transformPath("os_test_tmp");
12611263
...@@ -1270,7 +1272,7 @@ test "makePath, put some files in it, deleteTreeMinStackSize" {...@@ -1270,7 +1272,7 @@ test "makePath, put some files in it, deleteTreeMinStackSize" {
1270 });1272 });
12711273
1272 try ctx.dir.deleteTreeMinStackSize(dir_path);1274 try ctx.dir.deleteTreeMinStackSize(dir_path);
1273 try testing.expectError(error.FileNotFound, ctx.dir.openDir(dir_path, .{}));1275 try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, dir_path, .{}));
1274 }1276 }
1275 }.impl);1277 }.impl);
1276}1278}
...@@ -1296,7 +1298,7 @@ test "makePath but sub_path contains pre-existing file" {...@@ -1296,7 +1298,7 @@ test "makePath but sub_path contains pre-existing file" {
1296}1298}
12971299
1298fn expectDir(io: Io, dir: Dir, path: []const u8) !void {1300fn expectDir(io: Io, dir: Dir, path: []const u8) !void {
1299 var d = try dir.openDir(path, .{});1301 var d = try dir.openDir(io, path, .{});
1300 d.close(io);1302 d.close(io);
1301}1303}
13021304
...@@ -1307,7 +1309,7 @@ test "makepath existing directories" {...@@ -1307,7 +1309,7 @@ test "makepath existing directories" {
1307 defer tmp.cleanup();1309 defer tmp.cleanup();
13081310
1309 try tmp.dir.makeDir("A");1311 try tmp.dir.makeDir("A");
1310 var tmpA = try tmp.dir.openDir("A", .{});1312 var tmpA = try tmp.dir.openDir(io, "A", .{});
1311 defer tmpA.close(io);1313 defer tmpA.close(io);
1312 try tmpA.makeDir("B");1314 try tmpA.makeDir("B");
13131315
...@@ -1569,7 +1571,7 @@ test "sendfile" {...@@ -1569,7 +1571,7 @@ test "sendfile" {
15691571
1570 try tmp.dir.makePath("os_test_tmp");1572 try tmp.dir.makePath("os_test_tmp");
15711573
1572 var dir = try tmp.dir.openDir("os_test_tmp", .{});1574 var dir = try tmp.dir.openDir(io, "os_test_tmp", .{});
1573 defer dir.close(io);1575 defer dir.close(io);
15741576
1575 const line1 = "line1\n";1577 const line1 = "line1\n";
...@@ -1616,7 +1618,7 @@ test "sendfile with buffered data" {...@@ -1616,7 +1618,7 @@ test "sendfile with buffered data" {
16161618
1617 try tmp.dir.makePath("os_test_tmp");1619 try tmp.dir.makePath("os_test_tmp");
16181620
1619 var dir = try tmp.dir.openDir("os_test_tmp", .{});1621 var dir = try tmp.dir.openDir(io, "os_test_tmp", .{});
1620 defer dir.close(io);1622 defer dir.close(io);
16211623
1622 var src_file = try dir.createFile(io, "sendfile1.txt", .{ .read = true });1624 var src_file = try dir.createFile(io, "sendfile1.txt", .{ .read = true });
...@@ -1913,7 +1915,7 @@ test "walker" {...@@ -1913,7 +1915,7 @@ test "walker" {
1913 return err;1915 return err;
1914 };1916 };
1915 // make sure that the entry.dir is the containing dir1917 // make sure that the entry.dir is the containing dir
1916 var entry_dir = try entry.dir.openDir(entry.basename, .{});1918 var entry_dir = try entry.dir.openDir(io, entry.basename, .{});
1917 defer entry_dir.close(io);1919 defer entry_dir.close(io);
1918 num_walked += 1;1920 num_walked += 1;
1919 }1921 }
...@@ -1981,7 +1983,7 @@ test "selective walker, skip entries that start with ." {...@@ -1981,7 +1983,7 @@ test "selective walker, skip entries that start with ." {
1981 };1983 };
19821984
1983 // make sure that the entry.dir is the containing dir1985 // make sure that the entry.dir is the containing dir
1984 var entry_dir = try entry.dir.openDir(entry.basename, .{});1986 var entry_dir = try entry.dir.openDir(io, entry.basename, .{});
1985 defer entry_dir.close(io);1987 defer entry_dir.close(io);
1986 num_walked += 1;1988 num_walked += 1;
1987 }1989 }
...@@ -2026,7 +2028,7 @@ test "'.' and '..' in Io.Dir functions" {...@@ -2026,7 +2028,7 @@ test "'.' and '..' in Io.Dir functions" {
20262028
2027 try ctx.dir.makeDir(subdir_path);2029 try ctx.dir.makeDir(subdir_path);
2028 try ctx.dir.access(subdir_path, .{});2030 try ctx.dir.access(subdir_path, .{});
2029 var created_subdir = try ctx.dir.openDir(subdir_path, .{});2031 var created_subdir = try ctx.dir.openDir(io, subdir_path, .{});
2030 created_subdir.close(io);2032 created_subdir.close(io);
20312033
2032 const created_file = try ctx.dir.createFile(io, file_path, .{});2034 const created_file = try ctx.dir.createFile(io, file_path, .{});
...@@ -2103,7 +2105,7 @@ test "chmod" {...@@ -2103,7 +2105,7 @@ test "chmod" {
2103 try testing.expectEqual(@as(File.Mode, 0o644), (try file.stat()).mode & 0o7777);2105 try testing.expectEqual(@as(File.Mode, 0o644), (try file.stat()).mode & 0o7777);
21042106
2105 try tmp.dir.makeDir("test_dir");2107 try tmp.dir.makeDir("test_dir");
2106 var dir = try tmp.dir.openDir("test_dir", .{ .iterate = true });2108 var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true });
2107 defer dir.close(io);2109 defer dir.close(io);
21082110
2109 try dir.chmod(0o700);2111 try dir.chmod(0o700);
...@@ -2125,7 +2127,7 @@ test "chown" {...@@ -2125,7 +2127,7 @@ test "chown" {
21252127
2126 try tmp.dir.makeDir("test_dir");2128 try tmp.dir.makeDir("test_dir");
21272129
2128 var dir = try tmp.dir.openDir("test_dir", .{ .iterate = true });2130 var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true });
2129 defer dir.close(io);2131 defer dir.close(io);
2130 try dir.chown(null, null);2132 try dir.chown(null, null);
2131}2133}
lib/std/os/linux/IoUring.zig+3-1
...@@ -3066,6 +3066,8 @@ test "unlinkat" {...@@ -3066,6 +3066,8 @@ test "unlinkat" {
3066test "mkdirat" {3066test "mkdirat" {
3067 if (!is_linux) return error.SkipZigTest;3067 if (!is_linux) return error.SkipZigTest;
30683068
3069 const io = testing.io;
3070
3069 var ring = IoUring.init(1, 0) catch |err| switch (err) {3071 var ring = IoUring.init(1, 0) catch |err| switch (err) {
3070 error.SystemOutdated => return error.SkipZigTest,3072 error.SystemOutdated => return error.SkipZigTest,
3071 error.PermissionDenied => return error.SkipZigTest,3073 error.PermissionDenied => return error.SkipZigTest,
...@@ -3104,7 +3106,7 @@ test "mkdirat" {...@@ -3104,7 +3106,7 @@ test "mkdirat" {
3104 }, cqe);3106 }, cqe);
31053107
3106 // Validate that the directory exist3108 // Validate that the directory exist
3107 _ = try tmp.dir.openDir(path, .{});3109 _ = try tmp.dir.openDir(io, path, .{});
3108}3110}
31093111
3110test "symlinkat" {3112test "symlinkat" {
lib/std/zig/LibCInstallation.zig+5-5
...@@ -337,7 +337,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F...@@ -337,7 +337,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
337 // search in reverse order337 // search in reverse order
338 const search_path_untrimmed = search_paths.items[search_paths.items.len - path_i - 1];338 const search_path_untrimmed = search_paths.items[search_paths.items.len - path_i - 1];
339 const search_path = std.mem.trimStart(u8, search_path_untrimmed, " ");339 const search_path = std.mem.trimStart(u8, search_path_untrimmed, " ");
340 var search_dir = Io.Dir.cwd().openDir(search_path, .{}) catch |err| switch (err) {340 var search_dir = Io.Dir.cwd().openDir(io, search_path, .{}) catch |err| switch (err) {
341 error.FileNotFound,341 error.FileNotFound,
342 error.NotDir,342 error.NotDir,
343 error.NoDevice,343 error.NoDevice,
...@@ -392,7 +392,7 @@ fn findNativeIncludeDirWindows(...@@ -392,7 +392,7 @@ fn findNativeIncludeDirWindows(
392 result_buf.shrinkAndFree(0);392 result_buf.shrinkAndFree(0);
393 try result_buf.print("{s}\\Include\\{s}\\ucrt", .{ install.path, install.version });393 try result_buf.print("{s}\\Include\\{s}\\ucrt", .{ install.path, install.version });
394394
395 var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) {395 var dir = Io.Dir.cwd().openDir(io, result_buf.items, .{}) catch |err| switch (err) {
396 error.FileNotFound,396 error.FileNotFound,
397 error.NotDir,397 error.NotDir,
398 error.NoDevice,398 error.NoDevice,
...@@ -440,7 +440,7 @@ fn findNativeCrtDirWindows(...@@ -440,7 +440,7 @@ fn findNativeCrtDirWindows(
440 result_buf.shrinkAndFree(0);440 result_buf.shrinkAndFree(0);
441 try result_buf.print("{s}\\Lib\\{s}\\ucrt\\{s}", .{ install.path, install.version, arch_sub_dir });441 try result_buf.print("{s}\\Lib\\{s}\\ucrt\\{s}", .{ install.path, install.version, arch_sub_dir });
442442
443 var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) {443 var dir = Io.Dir.cwd().openDir(io, result_buf.items, .{}) catch |err| switch (err) {
444 error.FileNotFound,444 error.FileNotFound,
445 error.NotDir,445 error.NotDir,
446 error.NoDevice,446 error.NoDevice,
...@@ -508,7 +508,7 @@ fn findNativeKernel32LibDir(...@@ -508,7 +508,7 @@ fn findNativeKernel32LibDir(
508 result_buf.shrinkAndFree(0);508 result_buf.shrinkAndFree(0);
509 try result_buf.print("{s}\\Lib\\{s}\\um\\{s}", .{ install.path, install.version, arch_sub_dir });509 try result_buf.print("{s}\\Lib\\{s}\\um\\{s}", .{ install.path, install.version, arch_sub_dir });
510510
511 var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) {511 var dir = Io.Dir.cwd().openDir(io, result_buf.items, .{}) catch |err| switch (err) {
512 error.FileNotFound,512 error.FileNotFound,
513 error.NotDir,513 error.NotDir,
514 error.NoDevice,514 error.NoDevice,
...@@ -544,7 +544,7 @@ fn findNativeMsvcIncludeDir(...@@ -544,7 +544,7 @@ fn findNativeMsvcIncludeDir(
544 const dir_path = try fs.path.join(allocator, &[_][]const u8{ up2, "include" });544 const dir_path = try fs.path.join(allocator, &[_][]const u8{ up2, "include" });
545 errdefer allocator.free(dir_path);545 errdefer allocator.free(dir_path);
546546
547 var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| switch (err) {547 var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch |err| switch (err) {
548 error.FileNotFound,548 error.FileNotFound,
549 error.NotDir,549 error.NotDir,
550 error.NoDevice,550 error.NoDevice,
src/Compilation.zig+15-8
...@@ -745,6 +745,7 @@ pub const Directories = struct {...@@ -745,6 +745,7 @@ pub const Directories = struct {
745 /// Uses `std.process.fatal` on error conditions.745 /// Uses `std.process.fatal` on error conditions.
746 pub fn init(746 pub fn init(
747 arena: Allocator,747 arena: Allocator,
748 io: Io,
748 override_zig_lib: ?[]const u8,749 override_zig_lib: ?[]const u8,
749 override_global_cache: ?[]const u8,750 override_global_cache: ?[]const u8,
750 local_cache_strat: union(enum) {751 local_cache_strat: union(enum) {
...@@ -768,7 +769,7 @@ pub const Directories = struct {...@@ -768,7 +769,7 @@ pub const Directories = struct {
768 };769 };
769770
770 const zig_lib: Cache.Directory = d: {771 const zig_lib: Cache.Directory = d: {
771 if (override_zig_lib) |path| break :d openUnresolved(arena, cwd, path, .@"zig lib");772 if (override_zig_lib) |path| break :d openUnresolved(arena, io, cwd, path, .@"zig lib");
772 if (wasi) break :d openWasiPreopen(wasi_preopens, "/lib");773 if (wasi) break :d openWasiPreopen(wasi_preopens, "/lib");
773 break :d introspect.findZigLibDirFromSelfExe(arena, cwd, self_exe_path) catch |err| {774 break :d introspect.findZigLibDirFromSelfExe(arena, cwd, self_exe_path) catch |err| {
774 fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) });775 fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) });
...@@ -776,22 +777,22 @@ pub const Directories = struct {...@@ -776,22 +777,22 @@ pub const Directories = struct {
776 };777 };
777778
778 const global_cache: Cache.Directory = d: {779 const global_cache: Cache.Directory = d: {
779 if (override_global_cache) |path| break :d openUnresolved(arena, cwd, path, .@"global cache");780 if (override_global_cache) |path| break :d openUnresolved(arena, io, cwd, path, .@"global cache");
780 if (wasi) break :d openWasiPreopen(wasi_preopens, "/cache");781 if (wasi) break :d openWasiPreopen(wasi_preopens, "/cache");
781 const path = introspect.resolveGlobalCacheDir(arena) catch |err| {782 const path = introspect.resolveGlobalCacheDir(arena) catch |err| {
782 fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)});783 fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)});
783 };784 };
784 break :d openUnresolved(arena, cwd, path, .@"global cache");785 break :d openUnresolved(arena, io, cwd, path, .@"global cache");
785 };786 };
786787
787 const local_cache: Cache.Directory = switch (local_cache_strat) {788 const local_cache: Cache.Directory = switch (local_cache_strat) {
788 .override => |path| openUnresolved(arena, cwd, path, .@"local cache"),789 .override => |path| openUnresolved(arena, io, cwd, path, .@"local cache"),
789 .search => d: {790 .search => d: {
790 const maybe_path = introspect.resolveSuitableLocalCacheDir(arena, cwd) catch |err| {791 const maybe_path = introspect.resolveSuitableLocalCacheDir(arena, cwd) catch |err| {
791 fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)});792 fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)});
792 };793 };
793 const path = maybe_path orelse break :d global_cache;794 const path = maybe_path orelse break :d global_cache;
794 break :d openUnresolved(arena, cwd, path, .@"local cache");795 break :d openUnresolved(arena, io, cwd, path, .@"local cache");
795 },796 },
796 .global => global_cache,797 .global => global_cache,
797 };798 };
...@@ -818,13 +819,19 @@ pub const Directories = struct {...@@ -818,13 +819,19 @@ pub const Directories = struct {
818 },819 },
819 };820 };
820 }821 }
821 fn openUnresolved(arena: Allocator, cwd: []const u8, unresolved_path: []const u8, thing: enum { @"zig lib", @"global cache", @"local cache" }) Cache.Directory {822 fn openUnresolved(
823 arena: Allocator,
824 io: Io,
825 cwd: []const u8,
826 unresolved_path: []const u8,
827 thing: enum { @"zig lib", @"global cache", @"local cache" },
828 ) Cache.Directory {
822 const path = introspect.resolvePath(arena, cwd, &.{unresolved_path}) catch |err| {829 const path = introspect.resolvePath(arena, cwd, &.{unresolved_path}) catch |err| {
823 fatal("unable to resolve {s} directory: {s}", .{ @tagName(thing), @errorName(err) });830 fatal("unable to resolve {s} directory: {s}", .{ @tagName(thing), @errorName(err) });
824 };831 };
825 const nonempty_path = if (path.len == 0) "." else path;832 const nonempty_path = if (path.len == 0) "." else path;
826 const handle_or_err = switch (thing) {833 const handle_or_err = switch (thing) {
827 .@"zig lib" => Io.Dir.cwd().openDir(nonempty_path, .{}),834 .@"zig lib" => Io.Dir.cwd().openDir(io, nonempty_path, .{}),
828 .@"global cache", .@"local cache" => Io.Dir.cwd().makeOpenPath(nonempty_path, .{}),835 .@"global cache", .@"local cache" => Io.Dir.cwd().makeOpenPath(nonempty_path, .{}),
829 };836 };
830 return .{837 return .{
...@@ -5331,7 +5338,7 @@ fn docsCopyModule(...@@ -5331,7 +5338,7 @@ fn docsCopyModule(
5331 const root = module.root;5338 const root = module.root;
5332 var mod_dir = d: {5339 var mod_dir = d: {
5333 const root_dir, const sub_path = root.openInfo(comp.dirs);5340 const root_dir, const sub_path = root.openInfo(comp.dirs);
5334 break :d root_dir.openDir(sub_path, .{ .iterate = true });5341 break :d root_dir.openDir(io, sub_path, .{ .iterate = true });
5335 } catch |err| {5342 } catch |err| {
5336 return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{f}': {t}", .{ root.fmt(comp), err });5343 return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{f}': {t}", .{ root.fmt(comp), err });
5337 };5344 };
src/Package/Fetch.zig+3-2
...@@ -383,7 +383,7 @@ pub fn run(f: *Fetch) RunError!void {...@@ -383,7 +383,7 @@ pub fn run(f: *Fetch) RunError!void {
383 },383 },
384 .remote => |remote| remote,384 .remote => |remote| remote,
385 .path_or_url => |path_or_url| {385 .path_or_url => |path_or_url| {
386 if (Io.Dir.cwd().openDir(path_or_url, .{ .iterate = true })) |dir| {386 if (Io.Dir.cwd().openDir(io, path_or_url, .{ .iterate = true })) |dir| {
387 var resource: Resource = .{ .dir = dir };387 var resource: Resource = .{ .dir = dir };
388 return f.runResource(path_or_url, &resource, null);388 return f.runResource(path_or_url, &resource, null);
389 } else |dir_err| {389 } else |dir_err| {
...@@ -2311,8 +2311,9 @@ const TestFetchBuilder = struct {...@@ -2311,8 +2311,9 @@ const TestFetchBuilder = struct {
2311 }2311 }
23122312
2313 fn packageDir(self: *TestFetchBuilder) !Io.Dir {2313 fn packageDir(self: *TestFetchBuilder) !Io.Dir {
2314 const io = self.job_queue.io;
2314 const root = self.fetch.package_root;2315 const root = self.fetch.package_root;
2315 return try root.root_dir.handle.openDir(root.sub_path, .{ .iterate = true });2316 return try root.root_dir.handle.openDir(io, root.sub_path, .{ .iterate = true });
2316 }2317 }
23172318
2318 // Test helper, asserts thet package dir constains expected_files.2319 // Test helper, asserts thet package dir constains expected_files.
src/Package/Fetch/git.zig+1-1
...@@ -254,7 +254,7 @@ pub const Repository = struct {...@@ -254,7 +254,7 @@ pub const Repository = struct {
254 switch (entry.type) {254 switch (entry.type) {
255 .directory => {255 .directory => {
256 try dir.makeDir(entry.name);256 try dir.makeDir(entry.name);
257 var subdir = try dir.openDir(entry.name, .{});257 var subdir = try dir.openDir(io, entry.name, .{});
258 defer subdir.close(io);258 defer subdir.close(io);
259 const sub_path = try std.fs.path.join(repository.odb.allocator, &.{ current_path, entry.name });259 const sub_path = try std.fs.path.join(repository.odb.allocator, &.{ current_path, entry.name });
260 defer repository.odb.allocator.free(sub_path);260 defer repository.odb.allocator.free(sub_path);
src/fmt.zig+2-2
...@@ -186,7 +186,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !...@@ -186,7 +186,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !
186 error.FileNotFound => continue,186 error.FileNotFound => continue,
187 // On Windows, statFile does not work for directories187 // On Windows, statFile does not work for directories
188 error.IsDir => dir: {188 error.IsDir => dir: {
189 var dir = try Io.Dir.cwd().openDir(file_path, .{});189 var dir = try Io.Dir.cwd().openDir(io, file_path, .{});
190 defer dir.close(io);190 defer dir.close(io);
191 break :dir try dir.stat();191 break :dir try dir.stat();
192 },192 },
...@@ -224,7 +224,7 @@ fn fmtPathDir(...@@ -224,7 +224,7 @@ fn fmtPathDir(
224) !void {224) !void {
225 const io = fmt.io;225 const io = fmt.io;
226226
227 var dir = try parent_dir.openDir(parent_sub_path, .{ .iterate = true });227 var dir = try parent_dir.openDir(io, parent_sub_path, .{ .iterate = true });
228 defer dir.close(io);228 defer dir.close(io);
229229
230 const stat = try dir.stat();230 const stat = try dir.stat();
src/introspect.zig+3-3
...@@ -21,7 +21,7 @@ fn testZigInstallPrefix(io: Io, base_dir: Io.Dir) ?Cache.Directory {...@@ -21,7 +21,7 @@ fn testZigInstallPrefix(io: Io, base_dir: Io.Dir) ?Cache.Directory {
21 zig_dir: {21 zig_dir: {
22 // Try lib/zig/std/std.zig22 // Try lib/zig/std/std.zig
23 const lib_zig = "lib" ++ fs.path.sep_str ++ "zig";23 const lib_zig = "lib" ++ fs.path.sep_str ++ "zig";
24 var test_zig_dir = base_dir.openDir(lib_zig, .{}) catch break :zig_dir;24 var test_zig_dir = base_dir.openDir(io, lib_zig, .{}) catch break :zig_dir;
25 const file = test_zig_dir.openFile(io, test_index_file, .{}) catch {25 const file = test_zig_dir.openFile(io, test_index_file, .{}) catch {
26 test_zig_dir.close(io);26 test_zig_dir.close(io);
27 break :zig_dir;27 break :zig_dir;
...@@ -31,7 +31,7 @@ fn testZigInstallPrefix(io: Io, base_dir: Io.Dir) ?Cache.Directory {...@@ -31,7 +31,7 @@ fn testZigInstallPrefix(io: Io, base_dir: Io.Dir) ?Cache.Directory {
31 }31 }
3232
33 // Try lib/std/std.zig33 // Try lib/std/std.zig
34 var test_zig_dir = base_dir.openDir("lib", .{}) catch return null;34 var test_zig_dir = base_dir.openDir(io, "lib", .{}) catch return null;
35 const file = test_zig_dir.openFile(io, test_index_file, .{}) catch {35 const file = test_zig_dir.openFile(io, test_index_file, .{}) catch {
36 test_zig_dir.close(io);36 test_zig_dir.close(io);
37 return null;37 return null;
...@@ -85,7 +85,7 @@ pub fn findZigLibDirFromSelfExe(...@@ -85,7 +85,7 @@ pub fn findZigLibDirFromSelfExe(
85 const cwd = Io.Dir.cwd();85 const cwd = Io.Dir.cwd();
86 var cur_path: []const u8 = self_exe_path;86 var cur_path: []const u8 = self_exe_path;
87 while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) {87 while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) {
88 var base_dir = cwd.openDir(dirname, .{}) catch continue;88 var base_dir = cwd.openDir(io, dirname, .{}) catch continue;
89 defer base_dir.close(io);89 defer base_dir.close(io);
9090
91 const sub_directory = testZigInstallPrefix(io, base_dir) orelse continue;91 const sub_directory = testZigInstallPrefix(io, base_dir) orelse continue;
src/main.zig+19-18
...@@ -713,7 +713,7 @@ const Emit = union(enum) {...@@ -713,7 +713,7 @@ const Emit = union(enum) {
713 } else e: {713 } else e: {
714 // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would.714 // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would.
715 if (fs.path.dirname(path)) |dir_path| {715 if (fs.path.dirname(path)) |dir_path| {
716 var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| {716 var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch |err| {
717 fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) });717 fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) });
718 };718 };
719 dir.close(io);719 dir.close(io);
...@@ -3304,7 +3304,7 @@ fn buildOutputType(...@@ -3304,7 +3304,7 @@ fn buildOutputType(
3304 } else emit: {3304 } else emit: {
3305 // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would.3305 // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would.
3306 if (fs.path.dirname(path)) |dir_path| {3306 if (fs.path.dirname(path)) |dir_path| {
3307 var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| {3307 var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch |err| {
3308 fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) });3308 fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) });
3309 };3309 };
3310 dir.close(io);3310 dir.close(io);
...@@ -3959,14 +3959,14 @@ fn createModule(...@@ -3959,14 +3959,14 @@ fn createModule(
3959 if (fs.path.isAbsolute(lib_dir_arg)) {3959 if (fs.path.isAbsolute(lib_dir_arg)) {
3960 const stripped_dir = lib_dir_arg[fs.path.parsePath(lib_dir_arg).root.len..];3960 const stripped_dir = lib_dir_arg[fs.path.parsePath(lib_dir_arg).root.len..];
3961 const full_path = try fs.path.join(arena, &[_][]const u8{ root, stripped_dir });3961 const full_path = try fs.path.join(arena, &[_][]const u8{ root, stripped_dir });
3962 addLibDirectoryWarn(&create_module.lib_directories, full_path);3962 addLibDirectoryWarn(io, &create_module.lib_directories, full_path);
3963 } else {3963 } else {
3964 addLibDirectoryWarn(&create_module.lib_directories, lib_dir_arg);3964 addLibDirectoryWarn(io, &create_module.lib_directories, lib_dir_arg);
3965 }3965 }
3966 }3966 }
3967 } else {3967 } else {
3968 for (create_module.lib_dir_args.items) |lib_dir_arg| {3968 for (create_module.lib_dir_args.items) |lib_dir_arg| {
3969 addLibDirectoryWarn(&create_module.lib_directories, lib_dir_arg);3969 addLibDirectoryWarn(io, &create_module.lib_directories, lib_dir_arg);
3970 }3970 }
3971 }3971 }
3972 create_module.lib_dir_args = undefined; // From here we use lib_directories instead.3972 create_module.lib_dir_args = undefined; // From here we use lib_directories instead.
...@@ -4002,7 +4002,7 @@ fn createModule(...@@ -4002,7 +4002,7 @@ fn createModule(
4002 try create_module.rpath_list.appendSlice(arena, paths.rpaths.items);4002 try create_module.rpath_list.appendSlice(arena, paths.rpaths.items);
40034003
4004 try create_module.lib_directories.ensureUnusedCapacity(arena, paths.lib_dirs.items.len);4004 try create_module.lib_directories.ensureUnusedCapacity(arena, paths.lib_dirs.items.len);
4005 for (paths.lib_dirs.items) |path| addLibDirectoryWarn2(&create_module.lib_directories, path, true);4005 for (paths.lib_dirs.items) |path| addLibDirectoryWarn2(io, &create_module.lib_directories, path, true);
4006 }4006 }
40074007
4008 if (create_module.libc_paths_file) |paths_file| {4008 if (create_module.libc_paths_file) |paths_file| {
...@@ -4026,8 +4026,8 @@ fn createModule(...@@ -4026,8 +4026,8 @@ fn createModule(
4026 };4026 };
4027 }4027 }
4028 try create_module.lib_directories.ensureUnusedCapacity(arena, 2);4028 try create_module.lib_directories.ensureUnusedCapacity(arena, 2);
4029 addLibDirectoryWarn(&create_module.lib_directories, create_module.libc_installation.?.msvc_lib_dir.?);4029 addLibDirectoryWarn(io, &create_module.lib_directories, create_module.libc_installation.?.msvc_lib_dir.?);
4030 addLibDirectoryWarn(&create_module.lib_directories, create_module.libc_installation.?.kernel32_lib_dir.?);4030 addLibDirectoryWarn(io, &create_module.lib_directories, create_module.libc_installation.?.kernel32_lib_dir.?);
4031 }4031 }
40324032
4033 // Destructively mutates but does not transfer ownership of `unresolved_link_inputs`.4033 // Destructively mutates but does not transfer ownership of `unresolved_link_inputs`.
...@@ -5118,7 +5118,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)...@@ -5118,7 +5118,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
5118 process.raiseFileDescriptorLimit();5118 process.raiseFileDescriptorLimit();
51195119
5120 const cwd_path = try introspect.getResolvedCwd(arena);5120 const cwd_path = try introspect.getResolvedCwd(arena);
5121 const build_root = try findBuildRoot(arena, .{5121 const build_root = try findBuildRoot(arena, io, .{
5122 .cwd_path = cwd_path,5122 .cwd_path = cwd_path,
5123 .build_file = build_file,5123 .build_file = build_file,
5124 });5124 });
...@@ -5227,7 +5227,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)...@@ -5227,7 +5227,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
5227 if (system_pkg_dir_path) |p| {5227 if (system_pkg_dir_path) |p| {
5228 job_queue.global_cache = .{5228 job_queue.global_cache = .{
5229 .path = p,5229 .path = p,
5230 .handle = Io.Dir.cwd().openDir(p, .{}) catch |err| {5230 .handle = Io.Dir.cwd().openDir(io, p, .{}) catch |err| {
5231 fatal("unable to open system package directory '{s}': {s}", .{5231 fatal("unable to open system package directory '{s}': {s}", .{
5232 p, @errorName(err),5232 p, @errorName(err),
5233 });5233 });
...@@ -7039,7 +7039,7 @@ fn cmdFetch(...@@ -7039,7 +7039,7 @@ fn cmdFetch(
70397039
7040 const cwd_path = try introspect.getResolvedCwd(arena);7040 const cwd_path = try introspect.getResolvedCwd(arena);
70417041
7042 var build_root = try findBuildRoot(arena, .{7042 var build_root = try findBuildRoot(arena, io, .{
7043 .cwd_path = cwd_path,7043 .cwd_path = cwd_path,
7044 });7044 });
7045 defer build_root.deinit();7045 defer build_root.deinit();
...@@ -7251,7 +7251,7 @@ const FindBuildRootOptions = struct {...@@ -7251,7 +7251,7 @@ const FindBuildRootOptions = struct {
7251 cwd_path: ?[]const u8 = null,7251 cwd_path: ?[]const u8 = null,
7252};7252};
72537253
7254fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot {7254fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) !BuildRoot {
7255 const cwd_path = options.cwd_path orelse try introspect.getResolvedCwd(arena);7255 const cwd_path = options.cwd_path orelse try introspect.getResolvedCwd(arena);
7256 const build_zig_basename = if (options.build_file) |bf|7256 const build_zig_basename = if (options.build_file) |bf|
7257 fs.path.basename(bf)7257 fs.path.basename(bf)
...@@ -7260,7 +7260,7 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot {...@@ -7260,7 +7260,7 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot {
72607260
7261 if (options.build_file) |bf| {7261 if (options.build_file) |bf| {
7262 if (fs.path.dirname(bf)) |dirname| {7262 if (fs.path.dirname(bf)) |dirname| {
7263 const dir = Io.Dir.cwd().openDir(dirname, .{}) catch |err| {7263 const dir = Io.Dir.cwd().openDir(io, dirname, .{}) catch |err| {
7264 fatal("unable to open directory to build file from argument 'build-file', '{s}': {s}", .{ dirname, @errorName(err) });7264 fatal("unable to open directory to build file from argument 'build-file', '{s}': {s}", .{ dirname, @errorName(err) });
7265 };7265 };
7266 return .{7266 return .{
...@@ -7281,7 +7281,7 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot {...@@ -7281,7 +7281,7 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot {
7281 while (true) {7281 while (true) {
7282 const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename });7282 const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename });
7283 if (Io.Dir.cwd().access(joined_path, .{})) |_| {7283 if (Io.Dir.cwd().access(joined_path, .{})) |_| {
7284 const dir = Io.Dir.cwd().openDir(dirname, .{}) catch |err| {7284 const dir = Io.Dir.cwd().openDir(io, dirname, .{}) catch |err| {
7285 fatal("unable to open directory while searching for build.zig file, '{s}': {s}", .{ dirname, @errorName(err) });7285 fatal("unable to open directory while searching for build.zig file, '{s}': {s}", .{ dirname, @errorName(err) });
7286 };7286 };
7287 return .{7287 return .{
...@@ -7464,7 +7464,7 @@ fn findTemplates(gpa: Allocator, arena: Allocator, io: Io) Templates {...@@ -7464,7 +7464,7 @@ fn findTemplates(gpa: Allocator, arena: Allocator, io: Io) Templates {
74647464
7465 const s = fs.path.sep_str;7465 const s = fs.path.sep_str;
7466 const template_sub_path = "init";7466 const template_sub_path = "init";
7467 const template_dir = zig_lib_directory.handle.openDir(template_sub_path, .{}) catch |err| {7467 const template_dir = zig_lib_directory.handle.openDir(io, template_sub_path, .{}) catch |err| {
7468 const path = zig_lib_directory.path orelse ".";7468 const path = zig_lib_directory.path orelse ".";
7469 fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{7469 fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{
7470 path, s, template_sub_path, @errorName(err),7470 path, s, template_sub_path, @errorName(err),
...@@ -7581,17 +7581,18 @@ fn anyObjectLinkInputs(link_inputs: []const link.UnresolvedInput) bool {...@@ -7581,17 +7581,18 @@ fn anyObjectLinkInputs(link_inputs: []const link.UnresolvedInput) bool {
7581 return false;7581 return false;
7582}7582}
75837583
7584fn addLibDirectoryWarn(lib_directories: *std.ArrayList(Directory), path: []const u8) void {7584fn addLibDirectoryWarn(io: Io, lib_directories: *std.ArrayList(Directory), path: []const u8) void {
7585 return addLibDirectoryWarn2(lib_directories, path, false);7585 return addLibDirectoryWarn2(io, lib_directories, path, false);
7586}7586}
75877587
7588fn addLibDirectoryWarn2(7588fn addLibDirectoryWarn2(
7589 io: Io,
7589 lib_directories: *std.ArrayList(Directory),7590 lib_directories: *std.ArrayList(Directory),
7590 path: []const u8,7591 path: []const u8,
7591 ignore_not_found: bool,7592 ignore_not_found: bool,
7592) void {7593) void {
7593 lib_directories.appendAssumeCapacity(.{7594 lib_directories.appendAssumeCapacity(.{
7594 .handle = Io.Dir.cwd().openDir(path, .{}) catch |err| {7595 .handle = Io.Dir.cwd().openDir(io, path, .{}) catch |err| {
7595 if (err == error.FileNotFound and ignore_not_found) return;7596 if (err == error.FileNotFound and ignore_not_found) return;
7596 warn("unable to open library directory '{s}': {s}", .{ path, @errorName(err) });7597 warn("unable to open library directory '{s}': {s}", .{ path, @errorName(err) });
7597 return;7598 return;