authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-08 17:14:31-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-23 22:15:08-08:00
log950d18ef695bb7a28397e080dc3c201559ec4ee2
tree253209139275932ed503a5ea4529594ab70df8cc
parent314c906dba32e72317947a15254519b22745b13f

update all access() to access(io)


33 files changed, 159 insertions(+), 197 deletions(-)

lib/compiler/aro/aro/Driver.zig+3-3
...@@ -1333,7 +1333,7 @@ fn processSource(...@@ -1333,7 +1333,7 @@ fn processSource(
1333 Io.File.stdout();1333 Io.File.stdout();
1334 defer if (dep_file_name != null) file.close(io);1334 defer if (dep_file_name != null) file.close(io);
13351335
1336 var file_writer = file.writer(&writer_buf);1336 var file_writer = file.writer(io, &writer_buf);
1337 dep_file.write(&file_writer.interface) catch1337 dep_file.write(&file_writer.interface) catch
1338 return d.fatal("unable to write dependency file: {s}", .{errorDescription(file_writer.err.?)});1338 return d.fatal("unable to write dependency file: {s}", .{errorDescription(file_writer.err.?)});
1339 }1339 }
...@@ -1358,7 +1358,7 @@ fn processSource(...@@ -1358,7 +1358,7 @@ fn processSource(
1358 Io.File.stdout();1358 Io.File.stdout();
1359 defer if (d.output_name != null) file.close(io);1359 defer if (d.output_name != null) file.close(io);
13601360
1361 var file_writer = file.writer(&writer_buf);1361 var file_writer = file.writer(io, &writer_buf);
1362 pp.prettyPrintTokens(&file_writer.interface, dump_mode) catch1362 pp.prettyPrintTokens(&file_writer.interface, dump_mode) catch
1363 return d.fatal("unable to write result: {s}", .{errorDescription(file_writer.err.?)});1363 return d.fatal("unable to write result: {s}", .{errorDescription(file_writer.err.?)});
13641364
...@@ -1459,7 +1459,7 @@ fn processSource(...@@ -1459,7 +1459,7 @@ fn processSource(
1459 return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) });1459 return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) });
1460 defer out_file.close(io);1460 defer out_file.close(io);
14611461
1462 var file_writer = out_file.writer(&writer_buf);1462 var file_writer = out_file.writer(io, &writer_buf);
1463 obj.finish(&file_writer.interface) catch1463 obj.finish(&file_writer.interface) catch
1464 return d.fatal("could not output to object file '{s}': {s}", .{ out_file_name, errorDescription(file_writer.err.?) });1464 return d.fatal("could not output to object file '{s}': {s}", .{ out_file_name, errorDescription(file_writer.err.?) });
1465 }1465 }
lib/compiler/aro/aro/Driver/Filesystem.zig+4-4
...@@ -57,8 +57,8 @@ fn existsFake(entries: []const Filesystem.Entry, path: []const u8) bool {...@@ -57,8 +57,8 @@ fn existsFake(entries: []const Filesystem.Entry, path: []const u8) bool {
57 return false;57 return false;
58}58}
5959
60fn canExecutePosix(path: []const u8) bool {60fn canExecutePosix(io: Io, path: []const u8) bool {
61 std.posix.access(path, std.posix.X_OK) catch return false;61 Io.Dir.accessAbsolute(io, path, .{ .execute = true }) catch return false;
62 // Todo: ensure path is not a directory62 // Todo: ensure path is not a directory
63 return true;63 return true;
64}64}
...@@ -172,10 +172,10 @@ pub const Filesystem = union(enum) {...@@ -172,10 +172,10 @@ pub const Filesystem = union(enum) {
172 }172 }
173 };173 };
174174
175 pub fn exists(fs: Filesystem, path: []const u8) bool {175 pub fn exists(fs: Filesystem, io: Io, path: []const u8) bool {
176 switch (fs) {176 switch (fs) {
177 .real => |cwd| {177 .real => |cwd| {
178 cwd.access(path, .{}) catch return false;178 cwd.access(io, path, .{}) catch return false;
179 return true;179 return true;
180 },180 },
181 .fake => |paths| return existsFake(paths, path),181 .fake => |paths| return existsFake(paths, path),
lib/compiler/aro/aro/Toolchain.zig+8-5
...@@ -501,7 +501,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void {...@@ -501,7 +501,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void {
501 try d.includes.ensureUnusedCapacity(gpa, 1);501 try d.includes.ensureUnusedCapacity(gpa, 1);
502 if (d.resource_dir) |resource_dir| {502 if (d.resource_dir) |resource_dir| {
503 const path = try std.fs.path.join(arena, &.{ resource_dir, "include" });503 const path = try std.fs.path.join(arena, &.{ resource_dir, "include" });
504 comp.cwd.access(path, .{}) catch {504 comp.cwd.access(io, path, .{}) catch {
505 return d.fatal("Aro builtin headers not found in provided -resource-dir", .{});505 return d.fatal("Aro builtin headers not found in provided -resource-dir", .{});
506 };506 };
507 d.includes.appendAssumeCapacity(.{ .kind = .system, .path = path });507 d.includes.appendAssumeCapacity(.{ .kind = .system, .path = path });
...@@ -512,7 +512,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void {...@@ -512,7 +512,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void {
512 var base_dir = d.comp.cwd.openDir(io, 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(io, "include/stddef.h", .{}) catch continue;
516 const path = try std.fs.path.join(arena, &.{ dirname, "include" });516 const path = try std.fs.path.join(arena, &.{ dirname, "include" });
517 d.includes.appendAssumeCapacity(.{ .kind = .system, .path = path });517 d.includes.appendAssumeCapacity(.{ .kind = .system, .path = path });
518 break;518 break;
...@@ -524,12 +524,14 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void {...@@ -524,12 +524,14 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void {
524/// Otherwise returns a slice of `buf`. If the file is larger than `buf` partial contents are returned524/// Otherwise returns a slice of `buf`. If the file is larger than `buf` partial contents are returned
525pub fn readFile(tc: *const Toolchain, path: []const u8, buf: []u8) ?[]const u8 {525pub fn readFile(tc: *const Toolchain, path: []const u8, buf: []u8) ?[]const u8 {
526 const comp = tc.driver.comp;526 const comp = tc.driver.comp;
527 return comp.cwd.readFile(comp.io, path, buf) catch null;527 const io = comp.io;
528 return comp.cwd.readFile(io, path, buf) catch null;
528}529}
529530
530pub fn exists(tc: *const Toolchain, path: []const u8) bool {531pub fn exists(tc: *const Toolchain, path: []const u8) bool {
531 const comp = tc.driver.comp;532 const comp = tc.driver.comp;
532 comp.cwd.access(comp.io, path, .{}) catch return false;533 const io = comp.io;
534 comp.cwd.access(io, path, .{}) catch return false;
533 return true;535 return true;
534}536}
535537
...@@ -547,7 +549,8 @@ pub fn canExecute(tc: *const Toolchain, path: []const u8) bool {...@@ -547,7 +549,8 @@ pub fn canExecute(tc: *const Toolchain, path: []const u8) bool {
547 }549 }
548550
549 const comp = tc.driver.comp;551 const comp = tc.driver.comp;
550 comp.cwd.access(comp.io, path, .{ .execute = true }) catch return false;552 const io = comp.io;
553 comp.cwd.access(io, path, .{ .execute = true }) catch return false;
551 // Todo: ensure path is not a directory554 // Todo: ensure path is not a directory
552 return true;555 return true;
553}556}
lib/compiler/aro/backend/Assembly.zig+2-2
...@@ -12,8 +12,8 @@ pub fn deinit(self: *const Assembly, gpa: Allocator) void {...@@ -12,8 +12,8 @@ pub fn deinit(self: *const Assembly, gpa: Allocator) void {
12 gpa.free(self.text);12 gpa.free(self.text);
13}13}
1414
15pub fn writeToFile(self: Assembly, file: Io.File) !void {15pub fn writeToFile(self: Assembly, io: Io, file: Io.File) !void {
16 var file_writer = file.writer(&.{});16 var file_writer = file.writer(io, &.{});
1717
18 var buffers = [_][]const u8{ self.data, self.text };18 var buffers = [_][]const u8{ self.data, self.text };
19 try file_writer.interface.writeSplatAll(&buffers, 1);19 try file_writer.interface.writeSplatAll(&buffers, 1);
lib/compiler/resinator/cli.zig+5-5
...@@ -250,13 +250,13 @@ pub const Options = struct {...@@ -250,13 +250,13 @@ pub const Options = struct {
250 /// worlds' situation where we'll be compatible with most use-cases250 /// worlds' situation where we'll be compatible with most use-cases
251 /// of the .rc extension being omitted from the CLI args, but still251 /// of the .rc extension being omitted from the CLI args, but still
252 /// work fine if the file itself does not have an extension.252 /// work fine if the file itself does not have an extension.
253 pub fn maybeAppendRC(options: *Options, cwd: Io.Dir) !void {253 pub fn maybeAppendRC(options: *Options, io: Io, cwd: Io.Dir) !void {
254 switch (options.input_source) {254 switch (options.input_source) {
255 .stdio => return,255 .stdio => return,
256 .filename => {},256 .filename => {},
257 }257 }
258 if (options.input_format == .rc and std.fs.path.extension(options.input_source.filename).len == 0) {258 if (options.input_format == .rc and std.fs.path.extension(options.input_source.filename).len == 0) {
259 cwd.access(options.input_source.filename, .{}) catch |err| switch (err) {259 cwd.access(io, options.input_source.filename, .{}) catch |err| switch (err) {
260 error.FileNotFound => {260 error.FileNotFound => {
261 var filename_bytes = try options.allocator.alloc(u8, options.input_source.filename.len + 3);261 var filename_bytes = try options.allocator.alloc(u8, options.input_source.filename.len + 3);
262 @memcpy(filename_bytes[0..options.input_source.filename.len], options.input_source.filename);262 @memcpy(filename_bytes[0..options.input_source.filename.len], options.input_source.filename);
...@@ -2005,19 +2005,19 @@ test "maybeAppendRC" {...@@ -2005,19 +2005,19 @@ test "maybeAppendRC" {
2005 // appended.2005 // appended.
2006 var file = try tmp.dir.createFile(io, "foo", .{});2006 var file = try tmp.dir.createFile(io, "foo", .{});
2007 file.close(io);2007 file.close(io);
2008 try options.maybeAppendRC(tmp.dir);2008 try options.maybeAppendRC(io, tmp.dir);
2009 try std.testing.expectEqualStrings("foo", options.input_source.filename);2009 try std.testing.expectEqualStrings("foo", options.input_source.filename);
20102010
2011 // Now delete the file and try again. But this time change the input format2011 // Now delete the file and try again. But this time change the input format
2012 // to non-rc.2012 // to non-rc.
2013 try tmp.dir.deleteFile("foo");2013 try tmp.dir.deleteFile("foo");
2014 options.input_format = .res;2014 options.input_format = .res;
2015 try options.maybeAppendRC(tmp.dir);2015 try options.maybeAppendRC(io, tmp.dir);
2016 try std.testing.expectEqualStrings("foo", options.input_source.filename);2016 try std.testing.expectEqualStrings("foo", options.input_source.filename);
20172017
2018 // Finally, reset the input format to rc. Since the verbatim name is no longer found2018 // Finally, reset the input format to rc. Since the verbatim name is no longer found
2019 // and the input filename does not have an extension, .rc should get appended.2019 // and the input filename does not have an extension, .rc should get appended.
2020 options.input_format = .rc;2020 options.input_format = .rc;
2021 try options.maybeAppendRC(tmp.dir);2021 try options.maybeAppendRC(io, tmp.dir);
2022 try std.testing.expectEqualStrings("foo.rc", options.input_source.filename);2022 try std.testing.expectEqualStrings("foo.rc", options.input_source.filename);
2023}2023}
lib/compiler/resinator/main.zig+3-3
...@@ -318,7 +318,7 @@ pub fn main() !void {...@@ -318,7 +318,7 @@ pub fn main() !void {
318 defer depfile.close(io);318 defer depfile.close(io);
319319
320 var depfile_buffer: [1024]u8 = undefined;320 var depfile_buffer: [1024]u8 = undefined;
321 var depfile_writer = depfile.writer(&depfile_buffer);321 var depfile_writer = depfile.writer(io, &depfile_buffer);
322 switch (options.depfile_fmt) {322 switch (options.depfile_fmt) {
323 .json => {323 .json => {
324 var write_stream: std.json.Stringify = .{324 var write_stream: std.json.Stringify = .{
...@@ -521,9 +521,9 @@ const IoStream = struct {...@@ -521,9 +521,9 @@ const IoStream = struct {
521 }521 }
522 };522 };
523523
524 pub fn writer(source: *Source, allocator: Allocator, buffer: []u8) Writer {524 pub fn writer(source: *Source, allocator: Allocator, io: Io, buffer: []u8) Writer {
525 return switch (source.*) {525 return switch (source.*) {
526 .file, .stdio => |file| .{ .file = file.writer(buffer) },526 .file, .stdio => |file| .{ .file = file.writer(io, buffer) },
527 .memory => |*list| .{ .allocating = .fromArrayList(allocator, list) },527 .memory => |*list| .{ .allocating = .fromArrayList(allocator, list) },
528 .closed => unreachable,528 .closed => unreachable,
529 };529 };
lib/compiler/std-docs.zig+4-4
...@@ -334,8 +334,8 @@ fn buildWasmBinary(...@@ -334,8 +334,8 @@ fn buildWasmBinary(
334 });334 });
335 defer poller.deinit();335 defer poller.deinit();
336336
337 try sendMessage(child.stdin.?, .update);337 try sendMessage(io, child.stdin.?, .update);
338 try sendMessage(child.stdin.?, .exit);338 try sendMessage(io, child.stdin.?, .exit);
339339
340 var result: ?Cache.Path = null;340 var result: ?Cache.Path = null;
341 var result_error_bundle = std.zig.ErrorBundle.empty;341 var result_error_bundle = std.zig.ErrorBundle.empty;
...@@ -421,12 +421,12 @@ fn buildWasmBinary(...@@ -421,12 +421,12 @@ fn buildWasmBinary(
421 };421 };
422}422}
423423
424fn sendMessage(file: std.Io.File, tag: std.zig.Client.Message.Tag) !void {424fn sendMessage(io: Io, file: std.Io.File, tag: std.zig.Client.Message.Tag) !void {
425 const header: std.zig.Client.Message.Header = .{425 const header: std.zig.Client.Message.Header = .{
426 .tag = tag,426 .tag = tag,
427 .bytes_len = 0,427 .bytes_len = 0,
428 };428 };
429 var w = file.writer(&.{});429 var w = file.writer(io, &.{});
430 w.interface.writeStruct(header, .little) catch |err| switch (err) {430 w.interface.writeStruct(header, .little) catch |err| switch (err) {
431 error.WriteFailed => return w.err.?,431 error.WriteFailed => return w.err.?,
432 };432 };
lib/compiler/translate-c/main.zig+2-2
...@@ -232,7 +232,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration...@@ -232,7 +232,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration
232 Io.File.stdout();232 Io.File.stdout();
233 defer if (dep_file_name != null) file.close(io);233 defer if (dep_file_name != null) file.close(io);
234234
235 var file_writer = file.writer(&out_buf);235 var file_writer = file.writer(io, &out_buf);
236 dep_file.write(&file_writer.interface) catch236 dep_file.write(&file_writer.interface) catch
237 return d.fatal("unable to write dependency file: {s}", .{aro.Driver.errorDescription(file_writer.err.?)});237 return d.fatal("unable to write dependency file: {s}", .{aro.Driver.errorDescription(file_writer.err.?)});
238 }238 }
...@@ -263,7 +263,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration...@@ -263,7 +263,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration
263 out_file_path = path;263 out_file_path = path;
264 }264 }
265265
266 var out_writer = out_file.writer(&out_buf);266 var out_writer = out_file.writer(io, &out_buf);
267 out_writer.interface.writeAll(rendered_zig) catch {};267 out_writer.interface.writeAll(rendered_zig) catch {};
268 out_writer.interface.flush() catch {};268 out_writer.interface.flush() catch {};
269 if (out_writer.err) |write_err|269 if (out_writer.err) |write_err|
lib/std/Build.zig+1-1
...@@ -1699,7 +1699,7 @@ pub fn addCheckFile(...@@ -1699,7 +1699,7 @@ pub fn addCheckFile(
1699 return Step.CheckFile.create(b, file_source, options);1699 return Step.CheckFile.create(b, file_source, options);
1700}1700}
17011701
1702pub fn truncateFile(b: *Build, dest_path: []const u8) (Io.Dir.MakeError || Io.Dir.StatFileError)!void {1702pub fn truncateFile(b: *Build, dest_path: []const u8) (Io.Dir.MakeError || Io.Dir.StatPathError)!void {
1703 const io = b.graph.io;1703 const io = b.graph.io;
1704 if (b.verbose) log.info("truncate {s}", .{dest_path});1704 if (b.verbose) log.info("truncate {s}", .{dest_path});
1705 const cwd = Io.Dir.cwd();1705 const cwd = Io.Dir.cwd();
lib/std/Build/Cache/Path.zig+2-2
...@@ -118,14 +118,14 @@ pub fn atomicFile(...@@ -118,14 +118,14 @@ pub fn atomicFile(
118 return p.root_dir.handle.atomicFile(joined_path, options);118 return p.root_dir.handle.atomicFile(joined_path, options);
119}119}
120120
121pub fn access(p: Path, sub_path: []const u8, flags: Io.Dir.AccessOptions) !void {121pub fn access(p: Path, io: Io, sub_path: []const u8, flags: Io.Dir.AccessOptions) !void {
122 var buf: [fs.max_path_bytes]u8 = undefined;122 var buf: [fs.max_path_bytes]u8 = undefined;
123 const joined_path = if (p.sub_path.len == 0) sub_path else p: {123 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
124 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{124 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
125 p.sub_path, sub_path,125 p.sub_path, sub_path,
126 }) catch return error.NameTooLong;126 }) catch return error.NameTooLong;
127 };127 };
128 return p.root_dir.handle.access(joined_path, flags);128 return p.root_dir.handle.access(io, joined_path, flags);
129}129}
130130
131pub fn makePath(p: Path, io: Io, sub_path: []const u8) !void {131pub fn makePath(p: Path, io: Io, sub_path: []const u8) !void {
lib/std/Build/Step.zig+7-5
...@@ -519,19 +519,21 @@ pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u...@@ -519,19 +519,21 @@ pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u
519/// Wrapper around `Io.Dir.makePathStatus` that handles verbose and error output.519/// Wrapper around `Io.Dir.makePathStatus` that handles verbose and error output.
520pub fn installDir(s: *Step, dest_path: []const u8) !Io.Dir.MakePathStatus {520pub fn installDir(s: *Step, dest_path: []const u8) !Io.Dir.MakePathStatus {
521 const b = s.owner;521 const b = s.owner;
522 const io = b.graph.io;
522 try handleVerbose(b, null, &.{ "install", "-d", dest_path });523 try handleVerbose(b, null, &.{ "install", "-d", dest_path });
523 return Io.Dir.cwd().makePathStatus(dest_path) catch |err|524 return Io.Dir.cwd().makePathStatus(io, dest_path, .default_dir) catch |err|
524 return s.fail("unable to create dir '{s}': {t}", .{ dest_path, err });525 return s.fail("unable to create dir '{s}': {t}", .{ dest_path, err });
525}526}
526527
527fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool, web_server: ?*Build.WebServer, gpa: Allocator) !?Path {528fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool, web_server: ?*Build.WebServer, gpa: Allocator) !?Path {
528 const b = s.owner;529 const b = s.owner;
529 const arena = b.allocator;530 const arena = b.allocator;
531 const io = b.graph.io;
530532
531 var timer = try std.time.Timer.start();533 var timer = try std.time.Timer.start();
532534
533 try sendMessage(zp.child.stdin.?, .update);535 try sendMessage(io, zp.child.stdin.?, .update);
534 if (!watch) try sendMessage(zp.child.stdin.?, .exit);536 if (!watch) try sendMessage(io, zp.child.stdin.?, .exit);
535537
536 var result: ?Path = null;538 var result: ?Path = null;
537539
...@@ -668,12 +670,12 @@ fn clearZigProcess(s: *Step, gpa: Allocator) void {...@@ -668,12 +670,12 @@ fn clearZigProcess(s: *Step, gpa: Allocator) void {
668 }670 }
669}671}
670672
671fn sendMessage(file: Io.File, tag: std.zig.Client.Message.Tag) !void {673fn sendMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag) !void {
672 const header: std.zig.Client.Message.Header = .{674 const header: std.zig.Client.Message.Header = .{
673 .tag = tag,675 .tag = tag,
674 .bytes_len = 0,676 .bytes_len = 0,
675 };677 };
676 var w = file.writer(&.{});678 var w = file.writer(io, &.{});
677 w.interface.writeStruct(header, .little) catch |err| switch (err) {679 w.interface.writeStruct(header, .little) catch |err| switch (err) {
678 error.WriteFailed => return w.err.?,680 error.WriteFailed => return w.err.?,
679 };681 };
lib/std/Build/Step/InstallDir.zig+1-1
...@@ -71,7 +71,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {...@@ -71,7 +71,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
71 defer src_dir.close(io);71 defer src_dir.close(io);
72 var it = try src_dir.walk(arena);72 var it = try src_dir.walk(arena);
73 var all_cached = true;73 var all_cached = true;
74 next_entry: while (try it.next()) |entry| {74 next_entry: while (try it.next(io)) |entry| {
75 for (install_dir.options.exclude_extensions) |ext| {75 for (install_dir.options.exclude_extensions) |ext| {
76 if (mem.endsWith(u8, entry.path, ext)) continue :next_entry;76 if (mem.endsWith(u8, entry.path, ext)) continue :next_entry;
77 }77 }
lib/std/Build/Step/Run.zig+25-22
...@@ -1310,7 +1310,7 @@ fn runCommand(...@@ -1310,7 +1310,7 @@ fn runCommand(
1310 const need_cross_libc = exe.is_linking_libc and1310 const need_cross_libc = exe.is_linking_libc and
1311 (root_target.isGnuLibC() or (root_target.isMuslLibC() and exe.linkage == .dynamic));1311 (root_target.isGnuLibC() or (root_target.isMuslLibC() and exe.linkage == .dynamic));
1312 const other_target = exe.root_module.resolved_target.?.result;1312 const other_target = exe.root_module.resolved_target.?.result;
1313 switch (std.zig.system.getExternalExecutor(&b.graph.host.result, &other_target, .{1313 switch (std.zig.system.getExternalExecutor(io, &b.graph.host.result, &other_target, .{
1314 .qemu_fixes_dl = need_cross_libc and b.libc_runtimes_dir != null,1314 .qemu_fixes_dl = need_cross_libc and b.libc_runtimes_dir != null,
1315 .link_libc = exe.is_linking_libc,1315 .link_libc = exe.is_linking_libc,
1316 })) {1316 })) {
...@@ -1702,7 +1702,7 @@ fn evalZigTest(...@@ -1702,7 +1702,7 @@ fn evalZigTest(
1702 });1702 });
1703 var child_killed = false;1703 var child_killed = false;
1704 defer if (!child_killed) {1704 defer if (!child_killed) {
1705 _ = child.kill() catch {};1705 _ = child.kill(io) catch {};
1706 poller.deinit();1706 poller.deinit();
1707 run.step.result_peak_rss = @max(1707 run.step.result_peak_rss = @max(
1708 run.step.result_peak_rss,1708 run.step.result_peak_rss,
...@@ -1732,7 +1732,7 @@ fn evalZigTest(...@@ -1732,7 +1732,7 @@ fn evalZigTest(
1732 child.stdin = null;1732 child.stdin = null;
1733 poller.deinit();1733 poller.deinit();
1734 child_killed = true;1734 child_killed = true;
1735 const term = try child.wait();1735 const term = try child.wait(io);
1736 run.step.result_peak_rss = @max(1736 run.step.result_peak_rss = @max(
1737 run.step.result_peak_rss,1737 run.step.result_peak_rss,
1738 child.resource_usage_statistics.getMaxRss() orelse 0,1738 child.resource_usage_statistics.getMaxRss() orelse 0,
...@@ -1752,7 +1752,7 @@ fn evalZigTest(...@@ -1752,7 +1752,7 @@ fn evalZigTest(
1752 child.stdin = null;1752 child.stdin = null;
1753 poller.deinit();1753 poller.deinit();
1754 child_killed = true;1754 child_killed = true;
1755 const term = try child.wait();1755 const term = try child.wait(io);
1756 run.step.result_peak_rss = @max(1756 run.step.result_peak_rss = @max(
1757 run.step.result_peak_rss,1757 run.step.result_peak_rss,
1758 child.resource_usage_statistics.getMaxRss() orelse 0,1758 child.resource_usage_statistics.getMaxRss() orelse 0,
...@@ -1840,6 +1840,7 @@ fn pollZigTest(...@@ -1840,6 +1840,7 @@ fn pollZigTest(
1840 switch (ctx.fuzz.mode) {1840 switch (ctx.fuzz.mode) {
1841 .forever => {1841 .forever => {
1842 sendRunFuzzTestMessage(1842 sendRunFuzzTestMessage(
1843 io,
1843 child.stdin.?,1844 child.stdin.?,
1844 ctx.unit_test_index,1845 ctx.unit_test_index,
1845 .forever,1846 .forever,
...@@ -1848,6 +1849,7 @@ fn pollZigTest(...@@ -1848,6 +1849,7 @@ fn pollZigTest(
1848 },1849 },
1849 .limit => |limit| {1850 .limit => |limit| {
1850 sendRunFuzzTestMessage(1851 sendRunFuzzTestMessage(
1852 io,
1851 child.stdin.?,1853 child.stdin.?,
1852 ctx.unit_test_index,1854 ctx.unit_test_index,
1853 .iterations,1855 .iterations,
...@@ -1857,11 +1859,11 @@ fn pollZigTest(...@@ -1857,11 +1859,11 @@ fn pollZigTest(
1857 }1859 }
1858 } else if (opt_metadata.*) |*md| {1860 } else if (opt_metadata.*) |*md| {
1859 // Previous unit test process died or was killed; we're continuing where it left off1861 // Previous unit test process died or was killed; we're continuing where it left off
1860 requestNextTest(child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err };1862 requestNextTest(io, child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err };
1861 } else {1863 } else {
1862 // Running unit tests normally1864 // Running unit tests normally
1863 run.fuzz_tests.clearRetainingCapacity();1865 run.fuzz_tests.clearRetainingCapacity();
1864 sendMessage(child.stdin.?, .query_test_metadata) catch |err| return .{ .write_failed = err };1866 sendMessage(io, child.stdin.?, .query_test_metadata) catch |err| return .{ .write_failed = err };
1865 }1867 }
18661868
1867 var active_test_index: ?u32 = null;1869 var active_test_index: ?u32 = null;
...@@ -1977,7 +1979,7 @@ fn pollZigTest(...@@ -1977,7 +1979,7 @@ fn pollZigTest(
1977 active_test_index = null;1979 active_test_index = null;
1978 if (timer) |*t| t.reset();1980 if (timer) |*t| t.reset();
19791981
1980 requestNextTest(child.stdin.?, &opt_metadata.*.?, &sub_prog_node) catch |err| return .{ .write_failed = err };1982 requestNextTest(io, child.stdin.?, &opt_metadata.*.?, &sub_prog_node) catch |err| return .{ .write_failed = err };
1981 },1983 },
1982 .test_started => {1984 .test_started => {
1983 active_test_index = opt_metadata.*.?.next_index - 1;1985 active_test_index = opt_metadata.*.?.next_index - 1;
...@@ -2026,7 +2028,7 @@ fn pollZigTest(...@@ -2026,7 +2028,7 @@ fn pollZigTest(
2026 active_test_index = null;2028 active_test_index = null;
2027 if (timer) |*t| md.ns_per_test[tr_hdr.index] = t.lap();2029 if (timer) |*t| md.ns_per_test[tr_hdr.index] = t.lap();
20282030
2029 requestNextTest(child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err };2031 requestNextTest(io, child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err };
2030 },2032 },
2031 .coverage_id => {2033 .coverage_id => {
2032 coverage_id = body_r.takeInt(u64, .little) catch unreachable;2034 coverage_id = body_r.takeInt(u64, .little) catch unreachable;
...@@ -2097,7 +2099,7 @@ pub const CachedTestMetadata = struct {...@@ -2097,7 +2099,7 @@ pub const CachedTestMetadata = struct {
2097 }2099 }
2098};2100};
20992101
2100fn requestNextTest(in: Io.File, metadata: *TestMetadata, sub_prog_node: *?std.Progress.Node) !void {2102fn requestNextTest(io: Io, in: Io.File, metadata: *TestMetadata, sub_prog_node: *?std.Progress.Node) !void {
2101 while (metadata.next_index < metadata.names.len) {2103 while (metadata.next_index < metadata.names.len) {
2102 const i = metadata.next_index;2104 const i = metadata.next_index;
2103 metadata.next_index += 1;2105 metadata.next_index += 1;
...@@ -2108,31 +2110,31 @@ fn requestNextTest(in: Io.File, metadata: *TestMetadata, sub_prog_node: *?std.Pr...@@ -2108,31 +2110,31 @@ fn requestNextTest(in: Io.File, metadata: *TestMetadata, sub_prog_node: *?std.Pr
2108 if (sub_prog_node.*) |n| n.end();2110 if (sub_prog_node.*) |n| n.end();
2109 sub_prog_node.* = metadata.prog_node.start(name, 0);2111 sub_prog_node.* = metadata.prog_node.start(name, 0);
21102112
2111 try sendRunTestMessage(in, .run_test, i);2113 try sendRunTestMessage(io, in, .run_test, i);
2112 return;2114 return;
2113 } else {2115 } else {
2114 metadata.next_index = std.math.maxInt(u32); // indicate that all tests are done2116 metadata.next_index = std.math.maxInt(u32); // indicate that all tests are done
2115 try sendMessage(in, .exit);2117 try sendMessage(io, in, .exit);
2116 }2118 }
2117}2119}
21182120
2119fn sendMessage(file: Io.File, tag: std.zig.Client.Message.Tag) !void {2121fn sendMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag) !void {
2120 const header: std.zig.Client.Message.Header = .{2122 const header: std.zig.Client.Message.Header = .{
2121 .tag = tag,2123 .tag = tag,
2122 .bytes_len = 0,2124 .bytes_len = 0,
2123 };2125 };
2124 var w = file.writer(&.{});2126 var w = file.writer(io, &.{});
2125 w.interface.writeStruct(header, .little) catch |err| switch (err) {2127 w.interface.writeStruct(header, .little) catch |err| switch (err) {
2126 error.WriteFailed => return w.err.?,2128 error.WriteFailed => return w.err.?,
2127 };2129 };
2128}2130}
21292131
2130fn sendRunTestMessage(file: Io.File, tag: std.zig.Client.Message.Tag, index: u32) !void {2132fn sendRunTestMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag, index: u32) !void {
2131 const header: std.zig.Client.Message.Header = .{2133 const header: std.zig.Client.Message.Header = .{
2132 .tag = tag,2134 .tag = tag,
2133 .bytes_len = 4,2135 .bytes_len = 4,
2134 };2136 };
2135 var w = file.writer(&.{});2137 var w = file.writer(io, &.{});
2136 w.interface.writeStruct(header, .little) catch |err| switch (err) {2138 w.interface.writeStruct(header, .little) catch |err| switch (err) {
2137 error.WriteFailed => return w.err.?,2139 error.WriteFailed => return w.err.?,
2138 };2140 };
...@@ -2142,6 +2144,7 @@ fn sendRunTestMessage(file: Io.File, tag: std.zig.Client.Message.Tag, index: u32...@@ -2142,6 +2144,7 @@ fn sendRunTestMessage(file: Io.File, tag: std.zig.Client.Message.Tag, index: u32
2142}2144}
21432145
2144fn sendRunFuzzTestMessage(2146fn sendRunFuzzTestMessage(
2147 io: Io,
2145 file: Io.File,2148 file: Io.File,
2146 index: u32,2149 index: u32,
2147 kind: std.Build.abi.fuzz.LimitKind,2150 kind: std.Build.abi.fuzz.LimitKind,
...@@ -2151,7 +2154,7 @@ fn sendRunFuzzTestMessage(...@@ -2151,7 +2154,7 @@ fn sendRunFuzzTestMessage(
2151 .tag = .start_fuzzing,2154 .tag = .start_fuzzing,
2152 .bytes_len = 4 + 1 + 8,2155 .bytes_len = 4 + 1 + 8,
2153 };2156 };
2154 var w = file.writer(&.{});2157 var w = file.writer(io, &.{});
2155 w.interface.writeStruct(header, .little) catch |err| switch (err) {2158 w.interface.writeStruct(header, .little) catch |err| switch (err) {
2156 error.WriteFailed => return w.err.?,2159 error.WriteFailed => return w.err.?,
2157 };2160 };
...@@ -2172,14 +2175,14 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult {...@@ -2172,14 +2175,14 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult {
2172 const arena = b.allocator;2175 const arena = b.allocator;
21732176
2174 try child.spawn();2177 try child.spawn();
2175 errdefer _ = child.kill() catch {};2178 errdefer _ = child.kill(io) catch {};
21762179
2177 try child.waitForSpawn();2180 try child.waitForSpawn();
21782181
2179 switch (run.stdin) {2182 switch (run.stdin) {
2180 .bytes => |bytes| {2183 .bytes => |bytes| {
2181 child.stdin.?.writeAll(bytes) catch |err| {2184 child.stdin.?.writeStreamingAll(io, bytes) catch |err| {
2182 return run.step.fail("unable to write stdin: {s}", .{@errorName(err)});2185 return run.step.fail("unable to write stdin: {t}", .{err});
2183 };2186 };
2184 child.stdin.?.close(io);2187 child.stdin.?.close(io);
2185 child.stdin = null;2188 child.stdin = null;
...@@ -2187,14 +2190,14 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult {...@@ -2187,14 +2190,14 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult {
2187 .lazy_path => |lazy_path| {2190 .lazy_path => |lazy_path| {
2188 const path = lazy_path.getPath3(b, &run.step);2191 const path = lazy_path.getPath3(b, &run.step);
2189 const file = path.root_dir.handle.openFile(io, path.subPathOrDot(), .{}) catch |err| {2192 const file = path.root_dir.handle.openFile(io, path.subPathOrDot(), .{}) catch |err| {
2190 return run.step.fail("unable to open stdin file: {s}", .{@errorName(err)});2193 return run.step.fail("unable to open stdin file: {t}", .{err});
2191 };2194 };
2192 defer file.close(io);2195 defer file.close(io);
2193 // TODO https://github.com/ziglang/zig/issues/239552196 // TODO https://github.com/ziglang/zig/issues/23955
2194 var read_buffer: [1024]u8 = undefined;2197 var read_buffer: [1024]u8 = undefined;
2195 var file_reader = file.reader(io, &read_buffer);2198 var file_reader = file.reader(io, &read_buffer);
2196 var write_buffer: [1024]u8 = undefined;2199 var write_buffer: [1024]u8 = undefined;
2197 var stdin_writer = child.stdin.?.writer(&write_buffer);2200 var stdin_writer = child.stdin.?.writer(io, &write_buffer);
2198 _ = stdin_writer.interface.sendFileAll(&file_reader, .unlimited) catch |err| switch (err) {2201 _ = stdin_writer.interface.sendFileAll(&file_reader, .unlimited) catch |err| switch (err) {
2199 error.ReadFailed => return run.step.fail("failed to read from {f}: {t}", .{2202 error.ReadFailed => return run.step.fail("failed to read from {f}: {t}", .{
2200 path, file_reader.err.?,2203 path, file_reader.err.?,
...@@ -2267,7 +2270,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult {...@@ -2267,7 +2270,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult {
2267 run.step.result_peak_rss = child.resource_usage_statistics.getMaxRss() orelse 0;2270 run.step.result_peak_rss = child.resource_usage_statistics.getMaxRss() orelse 0;
22682271
2269 return .{2272 return .{
2270 .term = try child.wait(),2273 .term = try child.wait(io),
2271 .stdout = stdout_bytes,2274 .stdout = stdout_bytes,
2272 .stderr = stderr_bytes,2275 .stderr = stderr_bytes,
2273 };2276 };
lib/std/Build/Step/WriteFile.zig+3-6
...@@ -228,7 +228,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {...@@ -228,7 +228,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
228228
229 var it = try src_dir.walk(gpa);229 var it = try src_dir.walk(gpa);
230 defer it.deinit();230 defer it.deinit();
231 while (try it.next()) |entry| {231 while (try it.next(io)) |entry| {
232 if (!dir.options.pathIncluded(entry.path)) continue;232 if (!dir.options.pathIncluded(entry.path)) continue;
233233
234 switch (entry.kind) {234 switch (entry.kind) {
...@@ -259,11 +259,8 @@ fn make(step: *Step, options: Step.MakeOptions) !void {...@@ -259,11 +259,8 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
259259
260 write_file.generated_directory.path = try b.cache_root.join(arena, &.{ "o", &digest });260 write_file.generated_directory.path = try b.cache_root.join(arena, &.{ "o", &digest });
261261
262 var cache_dir = b.cache_root.handle.makeOpenPath(cache_path, .{}) catch |err| {262 var cache_dir = b.cache_root.handle.makeOpenPath(io, cache_path, .{}) catch |err|
263 return step.fail("unable to make path '{f}{s}': {s}", .{263 return step.fail("unable to make path '{f}{s}': {t}", .{ b.cache_root, cache_path, err });
264 b.cache_root, cache_path, @errorName(err),
265 });
266 };
267 defer cache_dir.close(io);264 defer cache_dir.close(io);
268265
269 for (write_file.files.items) |file| {266 for (write_file.files.items) |file| {
lib/std/Io.zig+2-2
...@@ -664,13 +664,13 @@ pub const VTable = struct {...@@ -664,13 +664,13 @@ pub const VTable = struct {
664664
665 dirMake: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.MakeError!void,665 dirMake: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.MakeError!void,
666 dirMakePath: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.MakePathError!Dir.MakePathStatus,666 dirMakePath: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.MakePathError!Dir.MakePathStatus,
667 dirMakeOpenPath: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.MakeOpenPathError!Dir,667 dirMakeOpenPath: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions, Dir.OpenOptions) Dir.MakeOpenPathError!Dir,
668 dirOpenDir: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.OpenError!Dir,
668 dirStat: *const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat,669 dirStat: *const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat,
669 dirStatPath: *const fn (?*anyopaque, Dir, []const u8, Dir.StatPathOptions) Dir.StatPathError!File.Stat,670 dirStatPath: *const fn (?*anyopaque, Dir, []const u8, Dir.StatPathOptions) Dir.StatPathError!File.Stat,
670 dirAccess: *const fn (?*anyopaque, Dir, []const u8, Dir.AccessOptions) Dir.AccessError!void,671 dirAccess: *const fn (?*anyopaque, Dir, []const u8, Dir.AccessOptions) Dir.AccessError!void,
671 dirCreateFile: *const fn (?*anyopaque, Dir, []const u8, File.CreateFlags) File.OpenError!File,672 dirCreateFile: *const fn (?*anyopaque, Dir, []const u8, File.CreateFlags) File.OpenError!File,
672 dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, File.OpenFlags) File.OpenError!File,673 dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, File.OpenFlags) File.OpenError!File,
673 dirOpenDir: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.OpenError!Dir,
674 dirClose: *const fn (?*anyopaque, []const Dir) void,674 dirClose: *const fn (?*anyopaque, []const Dir) void,
675 dirRead: *const fn (?*anyopaque, *Dir.Reader, []Dir.Entry) Dir.Reader.Error!usize,675 dirRead: *const fn (?*anyopaque, *Dir.Reader, []Dir.Entry) Dir.Reader.Error!usize,
676 dirRealPath: *const fn (?*anyopaque, Dir, path_name: []const u8, out_buffer: []u8) Dir.RealPathError!usize,676 dirRealPath: *const fn (?*anyopaque, Dir, path_name: []const u8, out_buffer: []u8) Dir.RealPathError!usize,
lib/std/Io/Dir.zig+8-8
...@@ -191,7 +191,7 @@ pub const SelectiveWalker = struct {...@@ -191,7 +191,7 @@ pub const SelectiveWalker = struct {
191 while (self.stack.items.len > 0) {191 while (self.stack.items.len > 0) {
192 const top = &self.stack.items[self.stack.items.len - 1];192 const top = &self.stack.items[self.stack.items.len - 1];
193 var dirname_len = top.dirname_len;193 var dirname_len = top.dirname_len;
194 if (top.iter.next() catch |err| {194 if (top.iter.next(io) catch |err| {
195 // If we get an error, then we want the user to be able to continue195 // If we get an error, then we want the user to be able to continue
196 // walking if they want, which means that we need to pop the directory196 // walking if they want, which means that we need to pop the directory
197 // that errored from the stack. Otherwise, all future `next` calls would197 // that errored from the stack. Otherwise, all future `next` calls would
...@@ -302,7 +302,7 @@ pub const Walker = struct {...@@ -302,7 +302,7 @@ pub const Walker = struct {
302 dir: Dir,302 dir: Dir,
303 basename: [:0]const u8,303 basename: [:0]const u8,
304 path: [:0]const u8,304 path: [:0]const u8,
305 kind: Dir.Entry.Kind,305 kind: File.Kind,
306306
307 /// Returns the depth of the entry relative to the initial directory.307 /// Returns the depth of the entry relative to the initial directory.
308 /// Returns 1 for a direct child of the initial directory, 2 for an entry308 /// Returns 1 for a direct child of the initial directory, 2 for an entry
...@@ -320,10 +320,10 @@ pub const Walker = struct {...@@ -320,10 +320,10 @@ pub const Walker = struct {
320 /// After each call to this function, and on deinit(), the memory returned320 /// After each call to this function, and on deinit(), the memory returned
321 /// from this function becomes invalid. A copy must be made in order to keep321 /// from this function becomes invalid. A copy must be made in order to keep
322 /// a reference to the path.322 /// a reference to the path.
323 pub fn next(self: *Walker) !?Walker.Entry {323 pub fn next(self: *Walker, io: Io) !?Walker.Entry {
324 const entry = try self.inner.next();324 const entry = try self.inner.next(io);
325 if (entry != null and entry.?.kind == .directory) {325 if (entry != null and entry.?.kind == .directory) {
326 try self.inner.enter(entry.?);326 try self.inner.enter(io, entry.?);
327 }327 }
328 return entry;328 return entry;
329 }329 }
...@@ -495,7 +495,7 @@ pub const WriteFileOptions = struct {...@@ -495,7 +495,7 @@ pub const WriteFileOptions = struct {
495 flags: File.CreateFlags = .{},495 flags: File.CreateFlags = .{},
496};496};
497497
498pub const WriteFileError = File.WriteError || File.OpenError;498pub const WriteFileError = File.Writer.Error || File.OpenError;
499499
500/// Writes content to the file system, using the file creation flags provided.500/// Writes content to the file system, using the file creation flags provided.
501pub fn writeFile(dir: Dir, io: Io, options: WriteFileOptions) WriteFileError!void {501pub fn writeFile(dir: Dir, io: Io, options: WriteFileOptions) WriteFileError!void {
...@@ -556,11 +556,11 @@ pub fn updateFile(...@@ -556,11 +556,11 @@ pub fn updateFile(
556 }556 }
557557
558 if (path.dirname(dest_path)) |dirname| {558 if (path.dirname(dest_path)) |dirname| {
559 try dest_dir.makePath(io, dirname, .default_dir);559 try dest_dir.makePath(io, dirname);
560 }560 }
561561
562 var buffer: [1000]u8 = undefined; // Used only when direct fd-to-fd is not available.562 var buffer: [1000]u8 = undefined; // Used only when direct fd-to-fd is not available.
563 var atomic_file = try Dir.atomicFile(dest_dir, dest_path, .{563 var atomic_file = try dest_dir.atomicFile(io, dest_path, .{
564 .permissions = actual_permissions,564 .permissions = actual_permissions,
565 .write_buffer = &buffer,565 .write_buffer = &buffer,
566 });566 });
lib/std/Io/Threaded.zig+9-4
...@@ -12,7 +12,7 @@ const std = @import("../std.zig");...@@ -12,7 +12,7 @@ const std = @import("../std.zig");
12const Io = std.Io;12const Io = std.Io;
13const net = std.Io.net;13const net = std.Io.net;
14const File = std.Io.File;14const File = std.Io.File;
15const Dir = std.Dir;15const Dir = std.Io.Dir;
16const HostName = std.Io.net.HostName;16const HostName = std.Io.net.HostName;
17const IpAddress = std.Io.net.IpAddress;17const IpAddress = std.Io.net.IpAddress;
18const Allocator = std.mem.Allocator;18const Allocator = std.mem.Allocator;
...@@ -1614,13 +1614,14 @@ fn dirMakeOpenPathPosix(...@@ -1614,13 +1614,14 @@ fn dirMakeOpenPathPosix(
1614 userdata: ?*anyopaque,1614 userdata: ?*anyopaque,
1615 dir: Dir,1615 dir: Dir,
1616 sub_path: []const u8,1616 sub_path: []const u8,
1617 permissions: Dir.Permissions,
1617 options: Dir.OpenOptions,1618 options: Dir.OpenOptions,
1618) Dir.MakeOpenPathError!Dir {1619) Dir.MakeOpenPathError!Dir {
1619 const t: *Threaded = @ptrCast(@alignCast(userdata));1620 const t: *Threaded = @ptrCast(@alignCast(userdata));
1620 const t_io = ioBasic(t);1621 const t_io = ioBasic(t);
1621 return dirOpenDirPosix(t, dir, sub_path, options) catch |err| switch (err) {1622 return dirOpenDirPosix(t, dir, sub_path, permissions, options) catch |err| switch (err) {
1622 error.FileNotFound => {1623 error.FileNotFound => {
1623 try dir.makePath(t_io, sub_path);1624 _ = try dir.makePathStatus(t_io, sub_path, permissions);
1624 return dirOpenDirPosix(t, dir, sub_path, options);1625 return dirOpenDirPosix(t, dir, sub_path, options);
1625 },1626 },
1626 else => |e| return e,1627 else => |e| return e,
...@@ -1631,12 +1632,15 @@ fn dirMakeOpenPathWindows(...@@ -1631,12 +1632,15 @@ fn dirMakeOpenPathWindows(
1631 userdata: ?*anyopaque,1632 userdata: ?*anyopaque,
1632 dir: Dir,1633 dir: Dir,
1633 sub_path: []const u8,1634 sub_path: []const u8,
1635 permissions: Dir.Permissions,
1634 options: Dir.OpenOptions,1636 options: Dir.OpenOptions,
1635) Dir.MakeOpenPathError!Dir {1637) Dir.MakeOpenPathError!Dir {
1636 const t: *Threaded = @ptrCast(@alignCast(userdata));1638 const t: *Threaded = @ptrCast(@alignCast(userdata));
1637 const current_thread = Thread.getCurrent(t);1639 const current_thread = Thread.getCurrent(t);
1638 const w = windows;1640 const w = windows;
16391641
1642 _ = permissions; // TODO apply these permissions
1643
1640 var it = std.fs.path.componentIterator(sub_path);1644 var it = std.fs.path.componentIterator(sub_path);
1641 // If there are no components in the path, then create a dummy component with the full path.1645 // If there are no components in the path, then create a dummy component with the full path.
1642 var component: std.fs.path.NativeComponentIterator.Component = it.last() orelse .{1646 var component: std.fs.path.NativeComponentIterator.Component = it.last() orelse .{
...@@ -1746,13 +1750,14 @@ fn dirMakeOpenPathWasi(...@@ -1746,13 +1750,14 @@ fn dirMakeOpenPathWasi(
1746 userdata: ?*anyopaque,1750 userdata: ?*anyopaque,
1747 dir: Dir,1751 dir: Dir,
1748 sub_path: []const u8,1752 sub_path: []const u8,
1753 permissions: Dir.Permissions,
1749 options: Dir.OpenOptions,1754 options: Dir.OpenOptions,
1750) Dir.MakeOpenPathError!Dir {1755) Dir.MakeOpenPathError!Dir {
1751 const t: *Threaded = @ptrCast(@alignCast(userdata));1756 const t: *Threaded = @ptrCast(@alignCast(userdata));
1752 const t_io = ioBasic(t);1757 const t_io = ioBasic(t);
1753 return dirOpenDirWasi(t, dir, sub_path, options) catch |err| switch (err) {1758 return dirOpenDirWasi(t, dir, sub_path, options) catch |err| switch (err) {
1754 error.FileNotFound => {1759 error.FileNotFound => {
1755 try dir.makePath(t_io, sub_path);1760 _ = try dir.makePathStatus(t_io, sub_path, permissions);
1756 return dirOpenDirWasi(t, dir, sub_path, options);1761 return dirOpenDirWasi(t, dir, sub_path, options);
1757 },1762 },
1758 else => |e| return e,1763 else => |e| return e,
lib/std/Io/test.zig+1-1
...@@ -30,7 +30,7 @@ test "write a file, read it, then delete it" {...@@ -30,7 +30,7 @@ test "write a file, read it, then delete it" {
30 var file = try tmp.dir.createFile(io, tmp_file_name, .{});30 var file = try tmp.dir.createFile(io, tmp_file_name, .{});
31 defer file.close(io);31 defer file.close(io);
3232
33 var file_writer = file.writer(&.{});33 var file_writer = file.writer(io, &.{});
34 const st = &file_writer.interface;34 const st = &file_writer.interface;
35 try st.print("begin", .{});35 try st.print("begin", .{});
36 try st.writeAll(&data);36 try st.writeAll(&data);
lib/std/debug.zig+4-4
...@@ -1279,7 +1279,7 @@ test printLineFromFile {...@@ -1279,7 +1279,7 @@ test printLineFromFile {
12791279
1280 const overlap = 10;1280 const overlap = 10;
1281 var buf: [16]u8 = undefined;1281 var buf: [16]u8 = undefined;
1282 var file_writer = file.writer(&buf);1282 var file_writer = file.writer(io, &buf);
1283 const writer = &file_writer.interface;1283 const writer = &file_writer.interface;
1284 try writer.splatByteAll('a', std.heap.page_size_min - overlap);1284 try writer.splatByteAll('a', std.heap.page_size_min - overlap);
1285 try writer.writeByte('\n');1285 try writer.writeByte('\n');
...@@ -1296,7 +1296,7 @@ test printLineFromFile {...@@ -1296,7 +1296,7 @@ test printLineFromFile {
1296 const path = try fs.path.join(gpa, &.{ test_dir_path, "file_ends_on_page_boundary.zig" });1296 const path = try fs.path.join(gpa, &.{ test_dir_path, "file_ends_on_page_boundary.zig" });
1297 defer gpa.free(path);1297 defer gpa.free(path);
12981298
1299 var file_writer = file.writer(&.{});1299 var file_writer = file.writer(io, &.{});
1300 const writer = &file_writer.interface;1300 const writer = &file_writer.interface;
1301 try writer.splatByteAll('a', std.heap.page_size_max);1301 try writer.splatByteAll('a', std.heap.page_size_max);
13021302
...@@ -1310,7 +1310,7 @@ test printLineFromFile {...@@ -1310,7 +1310,7 @@ test printLineFromFile {
1310 const path = try fs.path.join(gpa, &.{ test_dir_path, "very_long_first_line_spanning_multiple_pages.zig" });1310 const path = try fs.path.join(gpa, &.{ test_dir_path, "very_long_first_line_spanning_multiple_pages.zig" });
1311 defer gpa.free(path);1311 defer gpa.free(path);
13121312
1313 var file_writer = file.writer(&.{});1313 var file_writer = file.writer(io, &.{});
1314 const writer = &file_writer.interface;1314 const writer = &file_writer.interface;
1315 try writer.splatByteAll('a', 3 * std.heap.page_size_max);1315 try writer.splatByteAll('a', 3 * std.heap.page_size_max);
13161316
...@@ -1336,7 +1336,7 @@ test printLineFromFile {...@@ -1336,7 +1336,7 @@ test printLineFromFile {
1336 const path = try fs.path.join(gpa, &.{ test_dir_path, "file_of_newlines.zig" });1336 const path = try fs.path.join(gpa, &.{ test_dir_path, "file_of_newlines.zig" });
1337 defer gpa.free(path);1337 defer gpa.free(path);
13381338
1339 var file_writer = file.writer(&.{});1339 var file_writer = file.writer(io, &.{});
1340 const writer = &file_writer.interface;1340 const writer = &file_writer.interface;
1341 const real_file_start = 3 * std.heap.page_size_min;1341 const real_file_start = 3 * std.heap.page_size_min;
1342 try writer.splatByteAll('\n', real_file_start);1342 try writer.splatByteAll('\n', real_file_start);
lib/std/fs/test.zig+12-12
...@@ -1206,8 +1206,8 @@ test "deleteTree does not follow symlinks" {...@@ -1206,8 +1206,8 @@ test "deleteTree does not follow symlinks" {
12061206
1207 try tmp.dir.deleteTree("a");1207 try tmp.dir.deleteTree("a");
12081208
1209 try testing.expectError(error.FileNotFound, tmp.dir.access("a", .{}));1209 try testing.expectError(error.FileNotFound, tmp.dir.access(io, "a", .{}));
1210 try tmp.dir.access("b", .{});1210 try tmp.dir.access(io, "b", .{});
1211}1211}
12121212
1213test "deleteTree on a symlink" {1213test "deleteTree on a symlink" {
...@@ -1221,16 +1221,16 @@ test "deleteTree on a symlink" {...@@ -1221,16 +1221,16 @@ test "deleteTree on a symlink" {
1221 try setupSymlink(tmp.dir, "file", "filelink", .{});1221 try setupSymlink(tmp.dir, "file", "filelink", .{});
12221222
1223 try tmp.dir.deleteTree("filelink");1223 try tmp.dir.deleteTree("filelink");
1224 try testing.expectError(error.FileNotFound, tmp.dir.access("filelink", .{}));1224 try testing.expectError(error.FileNotFound, tmp.dir.access(io, "filelink", .{}));
1225 try tmp.dir.access("file", .{});1225 try tmp.dir.access(io, "file", .{});
12261226
1227 // Symlink to a directory1227 // Symlink to a directory
1228 try tmp.dir.makePath(io, "dir");1228 try tmp.dir.makePath(io, "dir");
1229 try setupSymlink(tmp.dir, "dir", "dirlink", .{ .is_directory = true });1229 try setupSymlink(tmp.dir, "dir", "dirlink", .{ .is_directory = true });
12301230
1231 try tmp.dir.deleteTree("dirlink");1231 try tmp.dir.deleteTree("dirlink");
1232 try testing.expectError(error.FileNotFound, tmp.dir.access("dirlink", .{}));1232 try testing.expectError(error.FileNotFound, tmp.dir.access(io, "dirlink", .{}));
1233 try tmp.dir.access("dir", .{});1233 try tmp.dir.access(io, "dir", .{});
1234}1234}
12351235
1236test "makePath, put some files in it, deleteTree" {1236test "makePath, put some files in it, deleteTree" {
...@@ -1358,8 +1358,8 @@ test "makepath relative walks" {...@@ -1358,8 +1358,8 @@ test "makepath relative walks" {
1358 // On Windows, .. is resolved before passing the path to NtCreateFile,1358 // On Windows, .. is resolved before passing the path to NtCreateFile,
1359 // meaning everything except `first/C` drops out.1359 // meaning everything except `first/C` drops out.
1360 try expectDir(io, tmp.dir, "first" ++ fs.path.sep_str ++ "C");1360 try expectDir(io, tmp.dir, "first" ++ fs.path.sep_str ++ "C");
1361 try testing.expectError(error.FileNotFound, tmp.dir.access("second", .{}));1361 try testing.expectError(error.FileNotFound, tmp.dir.access(io, "second", .{}));
1362 try testing.expectError(error.FileNotFound, tmp.dir.access("third", .{}));1362 try testing.expectError(error.FileNotFound, tmp.dir.access(io, "third", .{}));
1363 },1363 },
1364 else => {1364 else => {
1365 try expectDir(io, tmp.dir, "first" ++ fs.path.sep_str ++ "A");1365 try expectDir(io, tmp.dir, "first" ++ fs.path.sep_str ++ "A");
...@@ -1561,10 +1561,10 @@ test "access file" {...@@ -1561,10 +1561,10 @@ test "access file" {
1561 const file_path = try ctx.transformPath("os_test_tmp" ++ fs.path.sep_str ++ "file.txt");1561 const file_path = try ctx.transformPath("os_test_tmp" ++ fs.path.sep_str ++ "file.txt");
15621562
1563 try ctx.dir.makePath(io, dir_path);1563 try ctx.dir.makePath(io, dir_path);
1564 try testing.expectError(error.FileNotFound, ctx.dir.access(file_path, .{}));1564 try testing.expectError(error.FileNotFound, ctx.dir.access(io, file_path, .{}));
15651565
1566 try ctx.dir.writeFile(.{ .sub_path = file_path, .data = "" });1566 try ctx.dir.writeFile(.{ .sub_path = file_path, .data = "" });
1567 try ctx.dir.access(file_path, .{});1567 try ctx.dir.access(io, file_path, .{});
1568 try ctx.dir.deleteTree(dir_path);1568 try ctx.dir.deleteTree(dir_path);
1569 }1569 }
1570 }.impl);1570 }.impl);
...@@ -2036,13 +2036,13 @@ test "'.' and '..' in Io.Dir functions" {...@@ -2036,13 +2036,13 @@ test "'.' and '..' in Io.Dir functions" {
2036 const update_path = try ctx.transformPath("./subdir/../update");2036 const update_path = try ctx.transformPath("./subdir/../update");
20372037
2038 try ctx.dir.makeDir(subdir_path);2038 try ctx.dir.makeDir(subdir_path);
2039 try ctx.dir.access(subdir_path, .{});2039 try ctx.dir.access(io, subdir_path, .{});
2040 var created_subdir = try ctx.dir.openDir(io, subdir_path, .{});2040 var created_subdir = try ctx.dir.openDir(io, subdir_path, .{});
2041 created_subdir.close(io);2041 created_subdir.close(io);
20422042
2043 const created_file = try ctx.dir.createFile(io, file_path, .{});2043 const created_file = try ctx.dir.createFile(io, file_path, .{});
2044 created_file.close(io);2044 created_file.close(io);
2045 try ctx.dir.access(file_path, .{});2045 try ctx.dir.access(io, file_path, .{});
20462046
2047 try ctx.dir.copyFile(file_path, ctx.dir, copy_path, .{});2047 try ctx.dir.copyFile(file_path, ctx.dir, copy_path, .{});
2048 try ctx.dir.rename(copy_path, rename_path);2048 try ctx.dir.rename(copy_path, rename_path);
lib/std/posix.zig-61
...@@ -2842,67 +2842,6 @@ pub fn msync(memory: []align(page_size_min) u8, flags: i32) MSyncError!void {...@@ -2842,67 +2842,6 @@ pub fn msync(memory: []align(page_size_min) u8, flags: i32) MSyncError!void {
2842 }2842 }
2843}2843}
28442844
2845pub const AccessError = error{
2846 AccessDenied,
2847 PermissionDenied,
2848 FileNotFound,
2849 NameTooLong,
2850 InputOutput,
2851 SystemResources,
2852 FileBusy,
2853 SymLinkLoop,
2854 ReadOnlyFileSystem,
2855 /// WASI: file paths must be valid UTF-8.
2856 /// Windows: file paths provided by the user must be valid WTF-8.
2857 /// https://wtf-8.codeberg.page/
2858 BadPathName,
2859 Canceled,
2860} || UnexpectedError;
2861
2862/// check user's permissions for a file
2863///
2864/// * On Windows, asserts `path` is valid [WTF-8](https://wtf-8.codeberg.page/).
2865/// * On WASI, invalid UTF-8 passed to `path` causes `error.BadPathName`.
2866/// * On other platforms, `path` is an opaque sequence of bytes with no particular encoding.
2867///
2868/// On Windows, `mode` is ignored. This is a POSIX API that is only partially supported by
2869/// Windows. See `fs` for the cross-platform file system API.
2870pub fn access(path: []const u8, mode: u32) AccessError!void {
2871 if (native_os == .windows) {
2872 @compileError("use std.Io instead");
2873 } else if (native_os == .wasi and !builtin.link_libc) {
2874 @compileError("wasi doesn't support absolute paths");
2875 }
2876 const path_c = try toPosixPath(path);
2877 return accessZ(&path_c, mode);
2878}
2879
2880/// Same as `access` except `path` is null-terminated.
2881pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
2882 if (native_os == .windows) {
2883 @compileError("use std.Io instead");
2884 } else if (native_os == .wasi and !builtin.link_libc) {
2885 return access(mem.sliceTo(path, 0), mode);
2886 }
2887 switch (errno(system.access(path, mode))) {
2888 .SUCCESS => return,
2889 .ACCES => return error.AccessDenied,
2890 .PERM => return error.PermissionDenied,
2891 .ROFS => return error.ReadOnlyFileSystem,
2892 .LOOP => return error.SymLinkLoop,
2893 .TXTBSY => return error.FileBusy,
2894 .NOTDIR => return error.FileNotFound,
2895 .NOENT => return error.FileNotFound,
2896 .NAMETOOLONG => return error.NameTooLong,
2897 .INVAL => unreachable,
2898 .FAULT => unreachable,
2899 .IO => return error.InputOutput,
2900 .NOMEM => return error.SystemResources,
2901 .ILSEQ => return error.BadPathName,
2902 else => |err| return unexpectedErrno(err),
2903 }
2904}
2905
2906pub const PipeError = error{2845pub const PipeError = error{
2907 SystemFdQuotaExceeded,2846 SystemFdQuotaExceeded,
2908 ProcessFdQuotaExceeded,2847 ProcessFdQuotaExceeded,
lib/std/posix/test.zig+7-5
...@@ -376,7 +376,7 @@ test "mmap" {...@@ -376,7 +376,7 @@ test "mmap" {
376 const file = try tmp.dir.createFile(io, test_out_file, .{});376 const file = try tmp.dir.createFile(io, test_out_file, .{});
377 defer file.close(io);377 defer file.close(io);
378378
379 var stream = file.writer(&.{});379 var stream = file.writer(io, &.{});
380380
381 var i: usize = 0;381 var i: usize = 0;
382 while (i < alloc_size / @sizeOf(u32)) : (i += 1) {382 while (i < alloc_size / @sizeOf(u32)) : (i += 1) {
...@@ -741,6 +741,8 @@ test "access smoke test" {...@@ -741,6 +741,8 @@ test "access smoke test" {
741 if (native_os == .windows) return error.SkipZigTest;741 if (native_os == .windows) return error.SkipZigTest;
742 if (native_os == .openbsd) return error.SkipZigTest;742 if (native_os == .openbsd) return error.SkipZigTest;
743743
744 const io = testing.io;
745
744 var tmp = tmpDir(.{});746 var tmp = tmpDir(.{});
745 defer tmp.cleanup();747 defer tmp.cleanup();
746748
...@@ -761,9 +763,9 @@ test "access smoke test" {...@@ -761,9 +763,9 @@ test "access smoke test" {
761 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });763 const file_path = try fs.path.join(a, &.{ base_path, "some_file" });
762 defer a.free(file_path);764 defer a.free(file_path);
763 if (native_os == .windows) {765 if (native_os == .windows) {
764 try posix.access(file_path, posix.F_OK);766 try posix.access(io, file_path, posix.F_OK);
765 } else {767 } else {
766 try posix.access(file_path, posix.F_OK | posix.W_OK | posix.R_OK);768 try posix.access(io, file_path, posix.F_OK | posix.W_OK | posix.R_OK);
767 }769 }
768 }770 }
769771
...@@ -771,7 +773,7 @@ test "access smoke test" {...@@ -771,7 +773,7 @@ test "access smoke test" {
771 // Try to access() a non-existent file - should fail with error.FileNotFound773 // Try to access() a non-existent file - should fail with error.FileNotFound
772 const file_path = try fs.path.join(a, &.{ base_path, "some_other_file" });774 const file_path = try fs.path.join(a, &.{ base_path, "some_other_file" });
773 defer a.free(file_path);775 defer a.free(file_path);
774 try expectError(error.FileNotFound, posix.access(file_path, posix.F_OK));776 try expectError(error.FileNotFound, posix.access(io, file_path, posix.F_OK));
775 }777 }
776778
777 {779 {
...@@ -786,7 +788,7 @@ test "access smoke test" {...@@ -786,7 +788,7 @@ test "access smoke test" {
786 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });788 const file_path = try fs.path.join(a, &.{ base_path, "some_dir" });
787 defer a.free(file_path);789 defer a.free(file_path);
788790
789 try posix.access(file_path, posix.F_OK);791 try posix.access(io, file_path, posix.F_OK);
790 }792 }
791}793}
792794
lib/std/zig/LibCInstallation.zig+5-5
...@@ -357,7 +357,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F...@@ -357,7 +357,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
357 }357 }
358358
359 if (self.sys_include_dir == null) {359 if (self.sys_include_dir == null) {
360 if (search_dir.access(sys_include_dir_example_file, .{})) |_| {360 if (search_dir.access(io, sys_include_dir_example_file, .{})) |_| {
361 self.sys_include_dir = try allocator.dupeZ(u8, search_path);361 self.sys_include_dir = try allocator.dupeZ(u8, search_path);
362 } else |err| switch (err) {362 } else |err| switch (err) {
363 error.FileNotFound => {},363 error.FileNotFound => {},
...@@ -402,7 +402,7 @@ fn findNativeIncludeDirWindows(...@@ -402,7 +402,7 @@ fn findNativeIncludeDirWindows(
402 };402 };
403 defer dir.close(io);403 defer dir.close(io);
404404
405 dir.access("stdlib.h", .{}) catch |err| switch (err) {405 dir.access(io, "stdlib.h", .{}) catch |err| switch (err) {
406 error.FileNotFound => continue,406 error.FileNotFound => continue,
407 else => return error.FileSystem,407 else => return error.FileSystem,
408 };408 };
...@@ -450,7 +450,7 @@ fn findNativeCrtDirWindows(...@@ -450,7 +450,7 @@ fn findNativeCrtDirWindows(
450 };450 };
451 defer dir.close(io);451 defer dir.close(io);
452452
453 dir.access("ucrt.lib", .{}) catch |err| switch (err) {453 dir.access(io, "ucrt.lib", .{}) catch |err| switch (err) {
454 error.FileNotFound => continue,454 error.FileNotFound => continue,
455 else => return error.FileSystem,455 else => return error.FileSystem,
456 };456 };
...@@ -518,7 +518,7 @@ fn findNativeKernel32LibDir(...@@ -518,7 +518,7 @@ fn findNativeKernel32LibDir(
518 };518 };
519 defer dir.close(io);519 defer dir.close(io);
520520
521 dir.access("kernel32.lib", .{}) catch |err| switch (err) {521 dir.access(io, "kernel32.lib", .{}) catch |err| switch (err) {
522 error.FileNotFound => continue,522 error.FileNotFound => continue,
523 else => return error.FileSystem,523 else => return error.FileSystem,
524 };524 };
...@@ -554,7 +554,7 @@ fn findNativeMsvcIncludeDir(...@@ -554,7 +554,7 @@ fn findNativeMsvcIncludeDir(
554 };554 };
555 defer dir.close(io);555 defer dir.close(io);
556556
557 dir.access("vcruntime.h", .{}) catch |err| switch (err) {557 dir.access(io, "vcruntime.h", .{}) catch |err| switch (err) {
558 error.FileNotFound => return error.LibCStdLibHeaderNotFound,558 error.FileNotFound => return error.LibCStdLibHeaderNotFound,
559 else => return error.FileSystem,559 else => return error.FileSystem,
560 };560 };
lib/std/zig/llvm/Builder.zig+2-2
...@@ -9589,8 +9589,8 @@ pub fn printToFilePath(b: *Builder, io: Io, dir: Io.Dir, path: []const u8) !void...@@ -9589,8 +9589,8 @@ pub fn printToFilePath(b: *Builder, io: Io, dir: Io.Dir, path: []const u8) !void
9589 try b.printToFile(io, file, &buffer);9589 try b.printToFile(io, file, &buffer);
9590}9590}
95919591
9592pub fn printToFile(b: *Builder, file: Io.File, buffer: []u8) !void {9592pub fn printToFile(b: *Builder, io: Io, file: Io.File, buffer: []u8) !void {
9593 var fw = file.writer(buffer);9593 var fw = file.writer(io, buffer);
9594 try print(b, &fw.interface);9594 try print(b, &fw.interface);
9595 try fw.interface.flush();9595 try fw.interface.flush();
9596}9596}
lib/std/zig/system.zig+2-1
...@@ -40,6 +40,7 @@ pub const GetExternalExecutorOptions = struct {...@@ -40,6 +40,7 @@ pub const GetExternalExecutorOptions = struct {
40/// Return whether or not the given host is capable of running executables of40/// Return whether or not the given host is capable of running executables of
41/// the other target.41/// the other target.
42pub fn getExternalExecutor(42pub fn getExternalExecutor(
43 io: Io,
43 host: *const std.Target,44 host: *const std.Target,
44 candidate: *const std.Target,45 candidate: *const std.Target,
45 options: GetExternalExecutorOptions,46 options: GetExternalExecutorOptions,
...@@ -70,7 +71,7 @@ pub fn getExternalExecutor(...@@ -70,7 +71,7 @@ pub fn getExternalExecutor(
70 if (os_match and cpu_ok) native: {71 if (os_match and cpu_ok) native: {
71 if (options.link_libc) {72 if (options.link_libc) {
72 if (candidate.dynamic_linker.get()) |candidate_dl| {73 if (candidate.dynamic_linker.get()) |candidate_dl| {
73 Io.Dir.cwd().access(candidate_dl, .{}) catch {74 Io.Dir.cwd().access(io, candidate_dl, .{}) catch {
74 bad_result = .{ .bad_dl = candidate_dl };75 bad_result = .{ .bad_dl = candidate_dl };
75 break :native;76 break :native;
76 };77 };
src/Compilation.zig+1-1
...@@ -788,7 +788,7 @@ pub const Directories = struct {...@@ -788,7 +788,7 @@ pub const Directories = struct {
788 const local_cache: Cache.Directory = switch (local_cache_strat) {788 const local_cache: Cache.Directory = switch (local_cache_strat) {
789 .override => |path| openUnresolved(arena, io, cwd, path, .@"local cache"),789 .override => |path| openUnresolved(arena, io, cwd, path, .@"local cache"),
790 .search => d: {790 .search => d: {
791 const maybe_path = introspect.resolveSuitableLocalCacheDir(arena, cwd) catch |err| {791 const maybe_path = introspect.resolveSuitableLocalCacheDir(arena, io, cwd) catch |err| {
792 fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)});792 fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)});
793 };793 };
794 const path = maybe_path orelse break :d global_cache;794 const path = maybe_path orelse break :d global_cache;
src/Package/Fetch.zig+3-2
...@@ -418,7 +418,7 @@ pub fn run(f: *Fetch) RunError!void {...@@ -418,7 +418,7 @@ pub fn run(f: *Fetch) RunError!void {
418 const prefixed_pkg_sub_path = prefixed_pkg_sub_path_buffer[0 .. 2 + hash_slice.len];418 const prefixed_pkg_sub_path = prefixed_pkg_sub_path_buffer[0 .. 2 + hash_slice.len];
419 const prefix_len: usize = if (f.job_queue.read_only) "p/".len else 0;419 const prefix_len: usize = if (f.job_queue.read_only) "p/".len else 0;
420 const pkg_sub_path = prefixed_pkg_sub_path[prefix_len..];420 const pkg_sub_path = prefixed_pkg_sub_path[prefix_len..];
421 if (cache_root.handle.access(pkg_sub_path, .{})) |_| {421 if (cache_root.handle.access(io, pkg_sub_path, .{})) |_| {
422 assert(f.lazy_status != .unavailable);422 assert(f.lazy_status != .unavailable);
423 f.package_root = .{423 f.package_root = .{
424 .root_dir = cache_root,424 .root_dir = cache_root,
...@@ -637,8 +637,9 @@ pub fn computedPackageHash(f: *const Fetch) Package.Hash {...@@ -637,8 +637,9 @@ pub fn computedPackageHash(f: *const Fetch) Package.Hash {
637/// `computeHash` gets a free check for the existence of `build.zig`, but when637/// `computeHash` gets a free check for the existence of `build.zig`, but when
638/// not computing a hash, we need to do a syscall to check for it.638/// not computing a hash, we need to do a syscall to check for it.
639fn checkBuildFileExistence(f: *Fetch) RunError!void {639fn checkBuildFileExistence(f: *Fetch) RunError!void {
640 const io = f.job_queue.io;
640 const eb = &f.error_bundle;641 const eb = &f.error_bundle;
641 if (f.package_root.access(Package.build_zig_basename, .{})) |_| {642 if (f.package_root.access(io, Package.build_zig_basename, .{})) |_| {
642 f.has_build_zig = true;643 f.has_build_zig = true;
643 } else |err| switch (err) {644 } else |err| switch (err) {
644 error.FileNotFound => {},645 error.FileNotFound => {},
src/introspect.zig+2-2
...@@ -202,11 +202,11 @@ pub const default_local_zig_cache_basename = ".zig-cache";...@@ -202,11 +202,11 @@ pub const default_local_zig_cache_basename = ".zig-cache";
202/// Searches upwards from `cwd` for a directory containing a `build.zig` file.202/// Searches upwards from `cwd` for a directory containing a `build.zig` file.
203/// If such a directory is found, returns the path to it joined to the `.zig_cache` name.203/// If such a directory is found, returns the path to it joined to the `.zig_cache` name.
204/// Otherwise, returns `null`, indicating no suitable local cache location.204/// Otherwise, returns `null`, indicating no suitable local cache location.
205pub fn resolveSuitableLocalCacheDir(arena: Allocator, cwd: []const u8) Allocator.Error!?[]u8 {205pub fn resolveSuitableLocalCacheDir(arena: Allocator, io: Io, cwd: []const u8) Allocator.Error!?[]u8 {
206 var cur_dir = cwd;206 var cur_dir = cwd;
207 while (true) {207 while (true) {
208 const joined = try fs.path.join(arena, &.{ cur_dir, Package.build_zig_basename });208 const joined = try fs.path.join(arena, &.{ cur_dir, Package.build_zig_basename });
209 if (Io.Dir.cwd().access(joined, .{})) |_| {209 if (Io.Dir.cwd().access(io, joined, .{})) |_| {
210 return try fs.path.join(arena, &.{ cur_dir, default_local_zig_cache_basename });210 return try fs.path.join(arena, &.{ cur_dir, default_local_zig_cache_basename });
211 } else |err| switch (err) {211 } else |err| switch (err) {
212 error.FileNotFound => {212 error.FileNotFound => {
src/libs/mingw.zig+7-5
...@@ -242,7 +242,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {...@@ -242,7 +242,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
242 defer arena_allocator.deinit();242 defer arena_allocator.deinit();
243 const arena = arena_allocator.allocator();243 const arena = arena_allocator.allocator();
244244
245 const def_file_path = findDef(arena, comp.getTarget(), comp.dirs.zig_lib, lib_name) catch |err| switch (err) {245 const def_file_path = findDef(arena, io, comp.getTarget(), comp.dirs.zig_lib, lib_name) catch |err| switch (err) {
246 error.FileNotFound => {246 error.FileNotFound => {
247 log.debug("no {s}.def file available to make a DLL import {s}.lib", .{ lib_name, lib_name });247 log.debug("no {s}.def file available to make a DLL import {s}.lib", .{ lib_name, lib_name });
248 // In this case we will end up putting foo.lib onto the linker line and letting the linker248 // In this case we will end up putting foo.lib onto the linker line and letting the linker
...@@ -402,11 +402,12 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {...@@ -402,11 +402,12 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
402402
403pub fn libExists(403pub fn libExists(
404 allocator: Allocator,404 allocator: Allocator,
405 io: Io,
405 target: *const std.Target,406 target: *const std.Target,
406 zig_lib_directory: Cache.Directory,407 zig_lib_directory: Cache.Directory,
407 lib_name: []const u8,408 lib_name: []const u8,
408) !bool {409) !bool {
409 const s = findDef(allocator, target, zig_lib_directory, lib_name) catch |err| switch (err) {410 const s = findDef(allocator, io, target, zig_lib_directory, lib_name) catch |err| switch (err) {
410 error.FileNotFound => return false,411 error.FileNotFound => return false,
411 else => |e| return e,412 else => |e| return e,
412 };413 };
...@@ -418,6 +419,7 @@ pub fn libExists(...@@ -418,6 +419,7 @@ pub fn libExists(
418/// see if a .def file exists.419/// see if a .def file exists.
419fn findDef(420fn findDef(
420 allocator: Allocator,421 allocator: Allocator,
422 io: Io,
421 target: *const std.Target,423 target: *const std.Target,
422 zig_lib_directory: Cache.Directory,424 zig_lib_directory: Cache.Directory,
423 lib_name: []const u8,425 lib_name: []const u8,
...@@ -443,7 +445,7 @@ fn findDef(...@@ -443,7 +445,7 @@ fn findDef(
443 } else {445 } else {
444 try override_path.print(fmt_path, .{ lib_path, lib_name });446 try override_path.print(fmt_path, .{ lib_path, lib_name });
445 }447 }
446 if (Io.Dir.cwd().access(override_path.items, .{})) |_| {448 if (Io.Dir.cwd().access(io, override_path.items, .{})) |_| {
447 return override_path.toOwnedSlice();449 return override_path.toOwnedSlice();
448 } else |err| switch (err) {450 } else |err| switch (err) {
449 error.FileNotFound => {},451 error.FileNotFound => {},
...@@ -460,7 +462,7 @@ fn findDef(...@@ -460,7 +462,7 @@ fn findDef(
460 } else {462 } else {
461 try override_path.print(fmt_path, .{lib_name});463 try override_path.print(fmt_path, .{lib_name});
462 }464 }
463 if (Io.Dir.cwd().access(override_path.items, .{})) |_| {465 if (Io.Dir.cwd().access(io, override_path.items, .{})) |_| {
464 return override_path.toOwnedSlice();466 return override_path.toOwnedSlice();
465 } else |err| switch (err) {467 } else |err| switch (err) {
466 error.FileNotFound => {},468 error.FileNotFound => {},
...@@ -477,7 +479,7 @@ fn findDef(...@@ -477,7 +479,7 @@ fn findDef(
477 } else {479 } else {
478 try override_path.print(fmt_path, .{lib_name});480 try override_path.print(fmt_path, .{lib_name});
479 }481 }
480 if (Io.Dir.cwd().access(override_path.items, .{})) |_| {482 if (Io.Dir.cwd().access(io, override_path.items, .{})) |_| {
481 return override_path.toOwnedSlice();483 return override_path.toOwnedSlice();
482 } else |err| switch (err) {484 } else |err| switch (err) {
483 error.FileNotFound => {},485 error.FileNotFound => {},
src/link/C.zig+2-1
...@@ -371,6 +371,7 @@ pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.P...@@ -371,6 +371,7 @@ pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.P
371 const comp = self.base.comp;371 const comp = self.base.comp;
372 const diags = &comp.link_diags;372 const diags = &comp.link_diags;
373 const gpa = comp.gpa;373 const gpa = comp.gpa;
374 const io = comp.io;
374 const zcu = self.base.comp.zcu.?;375 const zcu = self.base.comp.zcu.?;
375 const ip = &zcu.intern_pool;376 const ip = &zcu.intern_pool;
376 const pt: Zcu.PerThread = .activate(zcu, tid);377 const pt: Zcu.PerThread = .activate(zcu, tid);
...@@ -509,7 +510,7 @@ pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.P...@@ -509,7 +510,7 @@ pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.P
509510
510 const file = self.base.file.?;511 const file = self.base.file.?;
511 file.setEndPos(f.file_size) catch |err| return diags.fail("failed to allocate file: {s}", .{@errorName(err)});512 file.setEndPos(f.file_size) catch |err| return diags.fail("failed to allocate file: {s}", .{@errorName(err)});
512 var fw = file.writer(&.{});513 var fw = file.writer(io, &.{});
513 var w = &fw.interface;514 var w = &fw.interface;
514 w.writeVecAll(f.all_buffers.items) catch |err| switch (err) {515 w.writeVecAll(f.all_buffers.items) catch |err| switch (err) {
515 error.WriteFailed => return diags.fail("failed to write to '{f}': {s}", .{516 error.WriteFailed => return diags.fail("failed to write to '{f}': {s}", .{
src/link/Lld.zig+5-4
...@@ -359,6 +359,7 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void {...@@ -359,6 +359,7 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void {
359fn coffLink(lld: *Lld, arena: Allocator) !void {359fn coffLink(lld: *Lld, arena: Allocator) !void {
360 const comp = lld.base.comp;360 const comp = lld.base.comp;
361 const gpa = comp.gpa;361 const gpa = comp.gpa;
362 const io = comp.io;
362 const base = &lld.base;363 const base = &lld.base;
363 const coff = &lld.ofmt.coff;364 const coff = &lld.ofmt.coff;
364365
...@@ -718,13 +719,13 @@ fn coffLink(lld: *Lld, arena: Allocator) !void {...@@ -718,13 +719,13 @@ fn coffLink(lld: *Lld, arena: Allocator) !void {
718 argv.appendAssumeCapacity(try crt_file.full_object_path.toString(arena));719 argv.appendAssumeCapacity(try crt_file.full_object_path.toString(arena));
719 continue;720 continue;
720 }721 }
721 if (try findLib(arena, lib_basename, coff.lib_directories)) |full_path| {722 if (try findLib(arena, io, lib_basename, coff.lib_directories)) |full_path| {
722 argv.appendAssumeCapacity(full_path);723 argv.appendAssumeCapacity(full_path);
723 continue;724 continue;
724 }725 }
725 if (target.abi.isGnu()) {726 if (target.abi.isGnu()) {
726 const fallback_name = try allocPrint(arena, "lib{s}.dll.a", .{key});727 const fallback_name = try allocPrint(arena, "lib{s}.dll.a", .{key});
727 if (try findLib(arena, fallback_name, coff.lib_directories)) |full_path| {728 if (try findLib(arena, io, fallback_name, coff.lib_directories)) |full_path| {
728 argv.appendAssumeCapacity(full_path);729 argv.appendAssumeCapacity(full_path);
729 continue;730 continue;
730 }731 }
...@@ -741,9 +742,9 @@ fn coffLink(lld: *Lld, arena: Allocator) !void {...@@ -741,9 +742,9 @@ fn coffLink(lld: *Lld, arena: Allocator) !void {
741 try spawnLld(comp, arena, argv.items);742 try spawnLld(comp, arena, argv.items);
742 }743 }
743}744}
744fn findLib(arena: Allocator, name: []const u8, lib_directories: []const Cache.Directory) !?[]const u8 {745fn findLib(arena: Allocator, io: Io, name: []const u8, lib_directories: []const Cache.Directory) !?[]const u8 {
745 for (lib_directories) |lib_directory| {746 for (lib_directories) |lib_directory| {
746 lib_directory.handle.access(name, .{}) catch |err| switch (err) {747 lib_directory.handle.access(io, name, .{}) catch |err| switch (err) {
747 error.FileNotFound => continue,748 error.FileNotFound => continue,
748 else => |e| return e,749 else => |e| return e,
749 };750 };
src/link/MachO.zig+12-9
...@@ -829,7 +829,8 @@ pub fn resolveLibSystem(...@@ -829,7 +829,8 @@ pub fn resolveLibSystem(
829 comp: *Compilation,829 comp: *Compilation,
830 out_libs: anytype,830 out_libs: anytype,
831) !void {831) !void {
832 const diags = &self.base.comp.link_diags;832 const io = comp.io;
833 const diags = &comp.link_diags;
833834
834 var test_path = std.array_list.Managed(u8).init(arena);835 var test_path = std.array_list.Managed(u8).init(arena);
835 var checked_paths = std.array_list.Managed([]const u8).init(arena);836 var checked_paths = std.array_list.Managed([]const u8).init(arena);
...@@ -838,16 +839,16 @@ pub fn resolveLibSystem(...@@ -838,16 +839,16 @@ pub fn resolveLibSystem(
838 if (self.sdk_layout) |sdk_layout| switch (sdk_layout) {839 if (self.sdk_layout) |sdk_layout| switch (sdk_layout) {
839 .sdk => {840 .sdk => {
840 const dir = try fs.path.join(arena, &.{ comp.sysroot.?, "usr", "lib" });841 const dir = try fs.path.join(arena, &.{ comp.sysroot.?, "usr", "lib" });
841 if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success;842 if (try accessLibPath(arena, io, &test_path, &checked_paths, dir, "System")) break :success;
842 },843 },
843 .vendored => {844 .vendored => {
844 const dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "darwin" });845 const dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "darwin" });
845 if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success;846 if (try accessLibPath(arena, io, &test_path, &checked_paths, dir, "System")) break :success;
846 },847 },
847 };848 };
848849
849 for (self.lib_directories) |directory| {850 for (self.lib_directories) |directory| {
850 if (try accessLibPath(arena, &test_path, &checked_paths, directory.path orelse ".", "System")) break :success;851 if (try accessLibPath(arena, io, &test_path, &checked_paths, directory.path orelse ".", "System")) break :success;
851 }852 }
852853
853 diags.addMissingLibraryError(checked_paths.items, "unable to find libSystem system library", .{});854 diags.addMissingLibraryError(checked_paths.items, "unable to find libSystem system library", .{});
...@@ -1074,6 +1075,7 @@ fn isHoisted(self: *MachO, install_name: []const u8) bool {...@@ -1074,6 +1075,7 @@ fn isHoisted(self: *MachO, install_name: []const u8) bool {
1074/// TODO delete this, libraries must be instead resolved when instantiating the compilation pipeline1075/// TODO delete this, libraries must be instead resolved when instantiating the compilation pipeline
1075fn accessLibPath(1076fn accessLibPath(
1076 arena: Allocator,1077 arena: Allocator,
1078 io: Io,
1077 test_path: *std.array_list.Managed(u8),1079 test_path: *std.array_list.Managed(u8),
1078 checked_paths: *std.array_list.Managed([]const u8),1080 checked_paths: *std.array_list.Managed([]const u8),
1079 search_dir: []const u8,1081 search_dir: []const u8,
...@@ -1085,7 +1087,7 @@ fn accessLibPath(...@@ -1085,7 +1087,7 @@ fn accessLibPath(
1085 test_path.clearRetainingCapacity();1087 test_path.clearRetainingCapacity();
1086 try test_path.print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext });1088 try test_path.print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext });
1087 try checked_paths.append(try arena.dupe(u8, test_path.items));1089 try checked_paths.append(try arena.dupe(u8, test_path.items));
1088 Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) {1090 Io.Dir.cwd().access(io, test_path.items, .{}) catch |err| switch (err) {
1089 error.FileNotFound => continue,1091 error.FileNotFound => continue,
1090 else => |e| return e,1092 else => |e| return e,
1091 };1093 };
...@@ -1097,6 +1099,7 @@ fn accessLibPath(...@@ -1097,6 +1099,7 @@ fn accessLibPath(
10971099
1098fn accessFrameworkPath(1100fn accessFrameworkPath(
1099 arena: Allocator,1101 arena: Allocator,
1102 io: Io,
1100 test_path: *std.array_list.Managed(u8),1103 test_path: *std.array_list.Managed(u8),
1101 checked_paths: *std.array_list.Managed([]const u8),1104 checked_paths: *std.array_list.Managed([]const u8),
1102 search_dir: []const u8,1105 search_dir: []const u8,
...@@ -1113,7 +1116,7 @@ fn accessFrameworkPath(...@@ -1113,7 +1116,7 @@ fn accessFrameworkPath(
1113 ext,1116 ext,
1114 });1117 });
1115 try checked_paths.append(try arena.dupe(u8, test_path.items));1118 try checked_paths.append(try arena.dupe(u8, test_path.items));
1116 Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) {1119 Io.Dir.cwd().access(io, test_path.items, .{}) catch |err| switch (err) {
1117 error.FileNotFound => continue,1120 error.FileNotFound => continue,
1118 else => |e| return e,1121 else => |e| return e,
1119 };1122 };
...@@ -1172,14 +1175,14 @@ fn parseDependentDylibs(self: *MachO) !void {...@@ -1172,14 +1175,14 @@ fn parseDependentDylibs(self: *MachO) !void {
1172 // Framework1175 // Framework
1173 for (framework_dirs) |dir| {1176 for (framework_dirs) |dir| {
1174 test_path.clearRetainingCapacity();1177 test_path.clearRetainingCapacity();
1175 if (try accessFrameworkPath(arena, &test_path, &checked_paths, dir, stem)) break :full_path test_path.items;1178 if (try accessFrameworkPath(arena, io, &test_path, &checked_paths, dir, stem)) break :full_path test_path.items;
1176 }1179 }
11771180
1178 // Library1181 // Library
1179 const lib_name = eatPrefix(stem, "lib") orelse stem;1182 const lib_name = eatPrefix(stem, "lib") orelse stem;
1180 for (lib_directories) |lib_directory| {1183 for (lib_directories) |lib_directory| {
1181 test_path.clearRetainingCapacity();1184 test_path.clearRetainingCapacity();
1182 if (try accessLibPath(arena, &test_path, &checked_paths, lib_directory.path orelse ".", lib_name)) break :full_path test_path.items;1185 if (try accessLibPath(arena, io, &test_path, &checked_paths, lib_directory.path orelse ".", lib_name)) break :full_path test_path.items;
1183 }1186 }
1184 }1187 }
11851188
...@@ -1194,7 +1197,7 @@ fn parseDependentDylibs(self: *MachO) !void {...@@ -1194,7 +1197,7 @@ fn parseDependentDylibs(self: *MachO) !void {
1194 try test_path.print("{s}{s}", .{ path, ext });1197 try test_path.print("{s}{s}", .{ path, ext });
1195 }1198 }
1196 try checked_paths.append(try arena.dupe(u8, test_path.items));1199 try checked_paths.append(try arena.dupe(u8, test_path.items));
1197 Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) {1200 Io.Dir.cwd().access(io, test_path.items, .{}) catch |err| switch (err) {
1198 error.FileNotFound => continue,1201 error.FileNotFound => continue,
1199 else => |e| return e,1202 else => |e| return e,
1200 };1203 };
src/main.zig+5-3
...@@ -3208,6 +3208,7 @@ fn buildOutputType(...@@ -3208,6 +3208,7 @@ fn buildOutputType(
32083208
3209 for (create_module.framework_dirs.items) |framework_dir_path| {3209 for (create_module.framework_dirs.items) |framework_dir_path| {
3210 if (try accessFrameworkPath(3210 if (try accessFrameworkPath(
3211 io,
3211 &test_path,3212 &test_path,
3212 &checked_paths,3213 &checked_paths,
3213 framework_dir_path,3214 framework_dir_path,
...@@ -6626,7 +6627,7 @@ fn warnAboutForeignBinaries(...@@ -6626,7 +6627,7 @@ fn warnAboutForeignBinaries(
6626 const host_query: std.Target.Query = .{};6627 const host_query: std.Target.Query = .{};
6627 const host_target = std.zig.resolveTargetQueryOrFatal(io, host_query);6628 const host_target = std.zig.resolveTargetQueryOrFatal(io, host_query);
66286629
6629 switch (std.zig.system.getExternalExecutor(&host_target, target, .{ .link_libc = link_libc })) {6630 switch (std.zig.system.getExternalExecutor(io, &host_target, target, .{ .link_libc = link_libc })) {
6630 .native => return,6631 .native => return,
6631 .rosetta => {6632 .rosetta => {
6632 const host_name = try host_target.zigTriple(arena);6633 const host_name = try host_target.zigTriple(arena);
...@@ -6832,6 +6833,7 @@ const ClangSearchSanitizer = struct {...@@ -6832,6 +6833,7 @@ const ClangSearchSanitizer = struct {
6832};6833};
68336834
6834fn accessFrameworkPath(6835fn accessFrameworkPath(
6836 io: Io,
6835 test_path: *std.array_list.Managed(u8),6837 test_path: *std.array_list.Managed(u8),
6836 checked_paths: *std.array_list.Managed(u8),6838 checked_paths: *std.array_list.Managed(u8),
6837 framework_dir_path: []const u8,6839 framework_dir_path: []const u8,
...@@ -6845,7 +6847,7 @@ fn accessFrameworkPath(...@@ -6845,7 +6847,7 @@ fn accessFrameworkPath(
6845 framework_dir_path, framework_name, framework_name, ext,6847 framework_dir_path, framework_name, framework_name, ext,
6846 });6848 });
6847 try checked_paths.print("\n {s}", .{test_path.items});6849 try checked_paths.print("\n {s}", .{test_path.items});
6848 Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) {6850 Io.Dir.cwd().access(io, test_path.items, .{}) catch |err| switch (err) {
6849 error.FileNotFound => continue,6851 error.FileNotFound => continue,
6850 else => |e| fatal("unable to search for {s} framework '{s}': {s}", .{6852 else => |e| fatal("unable to search for {s} framework '{s}': {s}", .{
6851 ext, test_path.items, @errorName(e),6853 ext, test_path.items, @errorName(e),
...@@ -7280,7 +7282,7 @@ fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) !Build...@@ -7280,7 +7282,7 @@ fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) !Build
7280 var dirname: []const u8 = cwd_path;7282 var dirname: []const u8 = cwd_path;
7281 while (true) {7283 while (true) {
7282 const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename });7284 const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename });
7283 if (Io.Dir.cwd().access(joined_path, .{})) |_| {7285 if (Io.Dir.cwd().access(io, joined_path, .{})) |_| {
7284 const dir = Io.Dir.cwd().openDir(io, dirname, .{}) catch |err| {7286 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) });7287 fatal("unable to open directory while searching for build.zig file, '{s}': {s}", .{ dirname, @errorName(err) });
7286 };7288 };