authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-08 18:00:55-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-23 22:15:08-08:00
log1dcfc8787e86ed94d216976e621a49fc488e8214
treed5225fa3a0abee6f6ff8f2793fe1ccea951d20a8
parent4be8be1d2bd6959efae7df95e3f5713adf953a42

update all readFileAlloc() to accept Io instance


16 files changed, 62 insertions(+), 62 deletions(-)

lib/compiler/std-docs.zig+4-2
......@@ -179,10 +179,11 @@ fn serveDocsFile(
179179 content_type: []const u8,
180180) !void {
181181 const gpa = context.gpa;
182 const io = context.io;
182183 // The desired API is actually sendfile, which will require enhancing std.http.Server.
183184 // We load the file with every request so that the user can make changes to the file
184185 // and refresh the HTML page without restarting this server.
185 const file_contents = try context.lib_dir.readFileAlloc(name, gpa, .limited(10 * 1024 * 1024));
186 const file_contents = try context.lib_dir.readFileAlloc(io, name, gpa, .limited(10 * 1024 * 1024));
186187 defer gpa.free(file_contents);
187188 try request.respond(file_contents, .{
188189 .extra_headers = &.{
......@@ -255,6 +256,7 @@ fn serveWasm(
255256 optimize_mode: std.builtin.OptimizeMode,
256257) !void {
257258 const gpa = context.gpa;
259 const io = context.io;
258260
259261 var arena_instance = std.heap.ArenaAllocator.init(gpa);
260262 defer arena_instance.deinit();
......@@ -273,7 +275,7 @@ fn serveWasm(
273275 });
274276 // std.http.Server does not have a sendfile API yet.
275277 const bin_path = try wasm_base_path.join(arena, bin_name);
276 const file_contents = try bin_path.root_dir.handle.readFileAlloc(bin_path.sub_path, gpa, .limited(10 * 1024 * 1024));
278 const file_contents = try bin_path.root_dir.handle.readFileAlloc(io, bin_path.sub_path, gpa, .limited(10 * 1024 * 1024));
277279 defer gpa.free(file_contents);
278280 try request.respond(file_contents, .{
279281 .extra_headers = &.{
lib/std/Build/Cache.zig+2-1
......@@ -1075,7 +1075,8 @@ pub const Manifest = struct {
10751075
10761076 fn addDepFileMaybePost(self: *Manifest, dir: Io.Dir, dep_file_sub_path: []const u8) !void {
10771077 const gpa = self.cache.gpa;
1078 const dep_file_contents = try dir.readFileAlloc(dep_file_sub_path, gpa, .limited(manifest_file_size_max));
1078 const io = self.cache.io;
1079 const dep_file_contents = try dir.readFileAlloc(io, dep_file_sub_path, gpa, .limited(manifest_file_size_max));
10791080 defer gpa.free(dep_file_contents);
10801081
10811082 var error_buf: std.ArrayList(u8) = .empty;
lib/std/Build/Step/CheckFile.zig+2-1
......@@ -51,11 +51,12 @@ pub fn setName(check_file: *CheckFile, name: []const u8) void {
5151fn make(step: *Step, options: Step.MakeOptions) !void {
5252 _ = options;
5353 const b = step.owner;
54 const io = b.graph.io;
5455 const check_file: *CheckFile = @fieldParentPtr("step", step);
5556 try step.singleUnchangingWatchInput(check_file.source);
5657
5758 const src_path = check_file.source.getPath2(b, step);
58 const contents = Io.Dir.cwd().readFileAlloc(src_path, b.allocator, .limited(check_file.max_bytes)) catch |err| {
59 const contents = Io.Dir.cwd().readFileAlloc(io, src_path, b.allocator, .limited(check_file.max_bytes)) catch |err| {
5960 return step.fail("unable to read '{s}': {s}", .{
6061 src_path, @errorName(err),
6162 });
lib/std/Build/Step/ConfigHeader.zig+2-2
......@@ -208,7 +208,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
208208 .autoconf_undef, .autoconf_at => |file_source| {
209209 try bw.writeAll(c_generated_line);
210210 const src_path = file_source.getPath2(b, step);
211 const contents = Io.Dir.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| {
211 const contents = Io.Dir.cwd().readFileAlloc(io, src_path, arena, .limited(config_header.max_bytes)) catch |err| {
212212 return step.fail("unable to read autoconf input file '{s}': {s}", .{
213213 src_path, @errorName(err),
214214 });
......@@ -222,7 +222,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
222222 .cmake => |file_source| {
223223 try bw.writeAll(c_generated_line);
224224 const src_path = file_source.getPath2(b, step);
225 const contents = Io.Dir.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| {
225 const contents = Io.Dir.cwd().readFileAlloc(io, src_path, arena, .limited(config_header.max_bytes)) catch |err| {
226226 return step.fail("unable to read cmake input file '{s}': {s}", .{
227227 src_path, @errorName(err),
228228 });
lib/std/Build/WebServer.zig+3-2
......@@ -469,11 +469,12 @@ pub fn serveFile(
469469 content_type: []const u8,
470470) !void {
471471 const gpa = ws.gpa;
472 const io = ws.graph.io;
472473 // The desired API is actually sendfile, which will require enhancing http.Server.
473474 // We load the file with every request so that the user can make changes to the file
474475 // and refresh the HTML page without restarting this server.
475 const file_contents = path.root_dir.handle.readFileAlloc(path.sub_path, gpa, .limited(10 * 1024 * 1024)) catch |err| {
476 log.err("failed to read '{f}': {s}", .{ path, @errorName(err) });
476 const file_contents = path.root_dir.handle.readFileAlloc(io, path.sub_path, gpa, .limited(10 * 1024 * 1024)) catch |err| {
477 log.err("failed to read '{f}': {t}", .{ path, err });
477478 return error.AlreadyReported;
478479 };
479480 defer gpa.free(file_contents);
lib/std/Io/Dir.zig+3-3
......@@ -1117,10 +1117,10 @@ pub fn readLink(dir: Dir, io: Io, sub_path: []const u8, buffer: []u8) ReadLinkEr
11171117/// On other platforms, `path` is an opaque sequence of bytes with no particular encoding.
11181118pub fn readLinkAbsolute(io: Io, absolute_path: []const u8, buffer: []u8) ReadLinkError!usize {
11191119 assert(path.isAbsolute(absolute_path));
1120 return io.vtable.dirReadLink(io.userdata, .cwd(), path, buffer);
1120 return io.vtable.dirReadLink(io.userdata, .cwd(), absolute_path, buffer);
11211121}
11221122
1123pub const ReadFileAllocError = File.OpenError || File.ReadError || Allocator.Error || error{
1123pub const ReadFileAllocError = File.OpenError || File.Reader.Error || Allocator.Error || error{
11241124 /// File size reached or exceeded the provided limit.
11251125 StreamTooLong,
11261126};
......@@ -1603,7 +1603,7 @@ pub const CopyFileOptions = struct {
16031603
16041604pub const CopyFileError = File.OpenError || File.StatError ||
16051605 File.Atomic.InitError || File.Atomic.FinishError ||
1606 File.ReadError || File.WriteError || error{InvalidFileName};
1606 File.Reader.Error || File.WriteError || error{InvalidFileName};
16071607
16081608/// Atomically creates a new file at `dest_path` within `dest_dir` with the
16091609/// same contents as `source_path` within `source_dir`, overwriting any already
lib/std/crypto/Certificate/Bundle/macos.zig+1-2
......@@ -17,9 +17,8 @@ pub fn rescanMac(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanM
1717 "/Library/Keychains/System.keychain",
1818 };
1919
20 _ = io; // TODO migrate file system to use std.Io
2120 for (keychain_paths) |keychain_path| {
22 const bytes = Io.Dir.cwd().readFileAlloc(keychain_path, gpa, .limited(std.math.maxInt(u32))) catch |err| switch (err) {
21 const bytes = Io.Dir.cwd().readFileAlloc(io, keychain_path, gpa, .limited(std.math.maxInt(u32))) catch |err| switch (err) {
2322 error.StreamTooLong => return error.FileTooBig,
2423 else => |e| return e,
2524 };
lib/std/fs/test.zig+14-13
......@@ -767,7 +767,7 @@ test "readFileAlloc" {
767767 var file = try tmp_dir.dir.createFile(io, "test_file", .{ .read = true });
768768 defer file.close(io);
769769
770 const buf1 = try tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(1024));
770 const buf1 = try tmp_dir.dir.readFileAlloc(io, "test_file", testing.allocator, .limited(1024));
771771 defer testing.allocator.free(buf1);
772772 try testing.expectEqualStrings("", buf1);
773773
......@@ -776,7 +776,7 @@ test "readFileAlloc" {
776776
777777 {
778778 // max_bytes > file_size
779 const buf2 = try tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(1024));
779 const buf2 = try tmp_dir.dir.readFileAlloc(io, "test_file", testing.allocator, .limited(1024));
780780 defer testing.allocator.free(buf2);
781781 try testing.expectEqualStrings(write_buf, buf2);
782782 }
......@@ -785,13 +785,13 @@ test "readFileAlloc" {
785785 // max_bytes == file_size
786786 try testing.expectError(
787787 error.StreamTooLong,
788 tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(write_buf.len)),
788 tmp_dir.dir.readFileAlloc(io, "test_file", testing.allocator, .limited(write_buf.len)),
789789 );
790790 }
791791
792792 {
793793 // max_bytes == file_size + 1
794 const buf2 = try tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(write_buf.len + 1));
794 const buf2 = try tmp_dir.dir.readFileAlloc(io, "test_file", testing.allocator, .limited(write_buf.len + 1));
795795 defer testing.allocator.free(buf2);
796796 try testing.expectEqualStrings(write_buf, buf2);
797797 }
......@@ -799,7 +799,7 @@ test "readFileAlloc" {
799799 // max_bytes < file_size
800800 try testing.expectError(
801801 error.StreamTooLong,
802 tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(write_buf.len - 1)),
802 tmp_dir.dir.readFileAlloc(io, "test_file", testing.allocator, .limited(write_buf.len - 1)),
803803 );
804804}
805805
......@@ -877,16 +877,16 @@ test "file operations on directories" {
877877 switch (native_os) {
878878 .dragonfly, .netbsd => {
879879 // no error when reading a directory. See https://github.com/ziglang/zig/issues/5732
880 const buf = try ctx.dir.readFileAlloc(test_dir_name, testing.allocator, .unlimited);
880 const buf = try ctx.dir.readFileAlloc(io, test_dir_name, testing.allocator, .unlimited);
881881 testing.allocator.free(buf);
882882 },
883883 .wasi => {
884884 // WASI return EBADF, which gets mapped to NotOpenForReading.
885885 // See https://github.com/bytecodealliance/wasmtime/issues/1935
886 try testing.expectError(error.NotOpenForReading, ctx.dir.readFileAlloc(test_dir_name, testing.allocator, .unlimited));
886 try testing.expectError(error.NotOpenForReading, ctx.dir.readFileAlloc(io, test_dir_name, testing.allocator, .unlimited));
887887 },
888888 else => {
889 try testing.expectError(error.IsDir, ctx.dir.readFileAlloc(test_dir_name, testing.allocator, .unlimited));
889 try testing.expectError(error.IsDir, ctx.dir.readFileAlloc(io, test_dir_name, testing.allocator, .unlimited));
890890 },
891891 }
892892
......@@ -1679,14 +1679,14 @@ test "copyFile" {
16791679 try ctx.dir.copyFile(src_file, ctx.dir, dest_file2, .{ .override_mode = File.default_mode });
16801680 defer ctx.dir.deleteFile(dest_file2) catch {};
16811681
1682 try expectFileContents(ctx.dir, dest_file, data);
1683 try expectFileContents(ctx.dir, dest_file2, data);
1682 try expectFileContents(io, ctx.dir, dest_file, data);
1683 try expectFileContents(io, ctx.dir, dest_file2, data);
16841684 }
16851685 }.impl);
16861686}
16871687
1688fn expectFileContents(dir: Dir, file_path: []const u8, data: []const u8) !void {
1689 const contents = try dir.readFileAlloc(file_path, testing.allocator, .limited(1000));
1688fn expectFileContents(io: Io, dir: Dir, file_path: []const u8, data: []const u8) !void {
1689 const contents = try dir.readFileAlloc(io, file_path, testing.allocator, .limited(1000));
16901690 defer testing.allocator.free(contents);
16911691
16921692 try testing.expectEqualSlices(u8, data, contents);
......@@ -1695,6 +1695,7 @@ fn expectFileContents(dir: Dir, file_path: []const u8, data: []const u8) !void {
16951695test "AtomicFile" {
16961696 try testWithAllSupportedPathTypes(struct {
16971697 fn impl(ctx: *TestContext) !void {
1698 const io = ctx.io;
16981699 const allocator = ctx.arena.allocator();
16991700 const test_out_file = try ctx.transformPath("tmp_atomic_file_test_dest.txt");
17001701 const test_content =
......@@ -1709,7 +1710,7 @@ test "AtomicFile" {
17091710 try af.file_writer.interface.writeAll(test_content);
17101711 try af.finish();
17111712 }
1712 const content = try ctx.dir.readFileAlloc(test_out_file, allocator, .limited(9999));
1713 const content = try ctx.dir.readFileAlloc(io, test_out_file, allocator, .limited(9999));
17131714 try testing.expectEqualStrings(test_content, content);
17141715
17151716 try ctx.dir.deleteFile(test_out_file);
lib/std/zig/LibCInstallation.zig+2-6
......@@ -37,11 +37,7 @@ pub const FindError = error{
3737 ZigIsTheCCompiler,
3838};
3939
40pub fn parse(
41 allocator: Allocator,
42 libc_file: []const u8,
43 target: *const std.Target,
44) !LibCInstallation {
40pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const std.Target) !LibCInstallation {
4541 var self: LibCInstallation = .{};
4642
4743 const fields = std.meta.fields(LibCInstallation);
......@@ -57,7 +53,7 @@ pub fn parse(
5753 }
5854 }
5955
60 const contents = try Io.Dir.cwd().readFileAlloc(libc_file, allocator, .limited(std.math.maxInt(usize)));
56 const contents = try Io.Dir.cwd().readFileAlloc(io, libc_file, allocator, .limited(std.math.maxInt(usize)));
6157 defer allocator.free(contents);
6258
6359 var it = std.mem.tokenizeScalar(u8, contents, '\n');
lib/std/zig/WindowsSdk.zig+1-1
......@@ -775,7 +775,7 @@ const MsvcLibDir = struct {
775775 writer.writeByte(std.fs.path.sep) catch unreachable;
776776 writer.writeAll("state.json") catch unreachable;
777777
778 const json_contents = instances_dir.readFileAlloc(writer.buffered(), allocator, .limited(std.math.maxInt(usize))) catch continue;
778 const json_contents = instances_dir.readFileAlloc(io, writer.buffered(), allocator, .limited(std.math.maxInt(usize))) catch continue;
779779 defer allocator.free(json_contents);
780780
781781 var parsed = std.json.parseFromSlice(std.json.Value, allocator, json_contents, .{}) catch continue;
src/Compilation.zig+2-2
......@@ -6400,7 +6400,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
64006400
64016401 if (comp.file_system_inputs != null) {
64026402 // Use the same file size limit as the cache code does for dependency files.
6403 const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(dep_basename, gpa, .limited(Cache.manifest_file_size_max));
6403 const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(io, dep_basename, gpa, .limited(Cache.manifest_file_size_max));
64046404 defer gpa.free(dep_file_contents);
64056405
64066406 var str_buf: std.ArrayList(u8) = .empty;
......@@ -6665,7 +6665,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
66656665 // Read depfile and update cache manifest
66666666 {
66676667 const dep_basename = fs.path.basename(out_dep_path);
6668 const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(dep_basename, arena, .limited(50 * 1024 * 1024));
6668 const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(io, dep_basename, arena, .limited(50 * 1024 * 1024));
66696669 defer arena.free(dep_file_contents);
66706670
66716671 const value = try std.json.parseFromSliceLeaky(std.json.Value, arena, dep_file_contents, .{});
src/Package/Fetch/git.zig+2-2
......@@ -1602,7 +1602,7 @@ fn runRepositoryTest(io: Io, comptime format: Oid.Format, head_commit: []const u
16021602 const max_file_size = 8192;
16031603
16041604 if (!skip_checksums) {
1605 const index_file_data = try git_dir.dir.readFileAlloc("testrepo.idx", testing.allocator, .limited(max_file_size));
1605 const index_file_data = try git_dir.dir.readFileAlloc(io, "testrepo.idx", testing.allocator, .limited(max_file_size));
16061606 defer testing.allocator.free(index_file_data);
16071607 // testrepo.idx is generated by Git. The index created by this file should
16081608 // match it exactly. Running `git verify-pack -v testrepo.pack` can verify
......@@ -1678,7 +1678,7 @@ fn runRepositoryTest(io: Io, comptime format: Oid.Format, head_commit: []const u
16781678 \\revision 19
16791679 \\
16801680 ;
1681 const actual_file_contents = try worktree.dir.readFileAlloc("file", testing.allocator, .limited(max_file_size));
1681 const actual_file_contents = try worktree.dir.readFileAlloc(io, "file", testing.allocator, .limited(max_file_size));
16821682 defer testing.allocator.free(actual_file_contents);
16831683 try testing.expectEqualStrings(expected_file_contents, actual_file_contents);
16841684}
src/link.zig+2-2
......@@ -624,12 +624,12 @@ pub const File = struct {
624624 try emit.root_dir.handle.rename(tmp_sub_path, emit.root_dir.handle, emit.sub_path, io);
625625 switch (builtin.os.tag) {
626626 .linux => std.posix.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| {
627 log.warn("ptrace failure: {s}", .{@errorName(err)});
627 log.warn("ptrace failure: {t}", .{err});
628628 },
629629 .maccatalyst, .macos => {
630630 const macho_file = base.cast(.macho).?;
631631 macho_file.ptraceAttach(pid) catch |err| {
632 log.warn("attaching failed with error: {s}", .{@errorName(err)});
632 log.warn("attaching failed with error: {t}", .{err});
633633 };
634634 },
635635 .windows => unreachable,
src/link/MachO.zig+5-3
......@@ -4347,11 +4347,13 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi
43474347 defer arena_allocator.deinit();
43484348 const arena = arena_allocator.allocator();
43494349
4350 const io = comp.io;
4351
43504352 const sdk_dir = switch (sdk_layout) {
43514353 .sdk => comp.sysroot.?,
43524354 .vendored => fs.path.join(arena, &.{ comp.dirs.zig_lib.path.?, "libc", "darwin" }) catch return null,
43534355 };
4354 if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| {
4356 if (readSdkVersionFromSettings(arena, io, sdk_dir)) |ver| {
43554357 return parseSdkVersion(ver);
43564358 } else |_| {
43574359 // Read from settings should always succeed when vendored.
......@@ -4374,9 +4376,9 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi
43744376// Official Apple SDKs ship with a `SDKSettings.json` located at the top of SDK fs layout.
43754377// Use property `MinimalDisplayName` to determine version.
43764378// The file/property is also available with vendored libc.
4377fn readSdkVersionFromSettings(arena: Allocator, dir: []const u8) ![]const u8 {
4379fn readSdkVersionFromSettings(arena: Allocator, io: Io, dir: []const u8) ![]const u8 {
43784380 const sdk_path = try fs.path.join(arena, &.{ dir, "SDKSettings.json" });
4379 const contents = try Io.Dir.cwd().readFileAlloc(sdk_path, arena, .limited(std.math.maxInt(u16)));
4381 const contents = try Io.Dir.cwd().readFileAlloc(io, sdk_path, arena, .limited(std.math.maxInt(u16)));
43804382 const parsed = try std.json.parseFromSlice(std.json.Value, arena, contents, .{});
43814383 if (parsed.value.object.get("MinimalDisplayName")) |ver| return ver.string;
43824384 return error.SdkVersionFailure;
src/link/MachO/CodeSignature.zig+8-8
......@@ -17,6 +17,12 @@ const MachO = @import("../MachO.zig");
1717
1818const hash_size = Sha256.digest_length;
1919
20page_size: u16,
21code_directory: CodeDirectory,
22requirements: ?Requirements = null,
23entitlements: ?Entitlements = null,
24signature: ?Signature = null,
25
2026const Blob = union(enum) {
2127 code_directory: *CodeDirectory,
2228 requirements: *Requirements,
......@@ -220,12 +226,6 @@ const Signature = struct {
220226 }
221227};
222228
223page_size: u16,
224code_directory: CodeDirectory,
225requirements: ?Requirements = null,
226entitlements: ?Entitlements = null,
227signature: ?Signature = null,
228
229229pub fn init(page_size: u16) CodeSignature {
230230 return .{
231231 .page_size = page_size,
......@@ -246,8 +246,8 @@ pub fn deinit(self: *CodeSignature, allocator: Allocator) void {
246246 }
247247}
248248
249pub fn addEntitlements(self: *CodeSignature, allocator: Allocator, path: []const u8) !void {
250 const inner = try Io.Dir.cwd().readFileAlloc(path, allocator, .limited(std.math.maxInt(u32)));
249pub fn addEntitlements(self: *CodeSignature, allocator: Allocator, io: Io, path: []const u8) !void {
250 const inner = try Io.Dir.cwd().readFileAlloc(io, path, allocator, .limited(std.math.maxInt(u32)));
251251 self.entitlements = .{ .inner = inner };
252252}
253253
src/main.zig+9-12
......@@ -1029,9 +1029,8 @@ fn buildOutputType(
10291029 if (mem.cutPrefix(u8, arg, "@")) |resp_file_path| {
10301030 // This is a "compiler response file". We must parse the file and treat its
10311031 // contents as command line parameters.
1032 args_iter.resp_file = initArgIteratorResponseFile(arena, resp_file_path) catch |err| {
1033 fatal("unable to read response file '{s}': {s}", .{ resp_file_path, @errorName(err) });
1034 };
1032 args_iter.resp_file = initArgIteratorResponseFile(arena, io, resp_file_path) catch |err|
1033 fatal("unable to read response file '{s}': {t}", .{ resp_file_path, err });
10351034 } else if (mem.startsWith(u8, arg, "-")) {
10361035 if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
10371036 try Io.File.stdout().writeAll(usage_build_generic);
......@@ -5441,7 +5440,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
54415440 // that are missing.
54425441 const s = fs.path.sep_str;
54435442 const tmp_sub_path = "tmp" ++ s ++ results_tmp_file_nonce;
5444 const stdout = dirs.local_cache.handle.readFileAlloc(tmp_sub_path, arena, .limited(50 * 1024 * 1024)) catch |err| {
5443 const stdout = dirs.local_cache.handle.readFileAlloc(io, tmp_sub_path, arena, .limited(50 * 1024 * 1024)) catch |err| {
54455444 fatal("unable to read results of configure phase from '{f}{s}': {s}", .{
54465445 dirs.local_cache, tmp_sub_path, @errorName(err),
54475446 });
......@@ -5822,9 +5821,9 @@ pub fn lldMain(
58225821const ArgIteratorResponseFile = process.ArgIteratorGeneral(.{ .comments = true, .single_quotes = true });
58235822
58245823/// Initialize the arguments from a Response File. "*.rsp"
5825fn initArgIteratorResponseFile(allocator: Allocator, resp_file_path: []const u8) !ArgIteratorResponseFile {
5824fn initArgIteratorResponseFile(allocator: Allocator, io: Io, resp_file_path: []const u8) !ArgIteratorResponseFile {
58265825 const max_bytes = 10 * 1024 * 1024; // 10 MiB of command line arguments is a reasonable limit
5827 const cmd_line = try Io.Dir.cwd().readFileAlloc(resp_file_path, allocator, .limited(max_bytes));
5826 const cmd_line = try Io.Dir.cwd().readFileAlloc(io, resp_file_path, allocator, .limited(max_bytes));
58285827 errdefer allocator.free(cmd_line);
58295828
58305829 return ArgIteratorResponseFile.initTakeOwnership(allocator, cmd_line);
......@@ -5952,7 +5951,7 @@ pub const ClangArgIterator = struct {
59525951 };
59535952 }
59545953
5955 fn next(self: *ClangArgIterator) !void {
5954 fn next(self: *ClangArgIterator, io: Io) !void {
59565955 assert(self.has_next);
59575956 assert(self.next_index < self.argv.len);
59585957 // In this state we know that the parameter we are looking at is a root parameter
......@@ -5970,10 +5969,8 @@ pub const ClangArgIterator = struct {
59705969 const arena = self.arena;
59715970 const resp_file_path = arg[1..];
59725971
5973 self.arg_iterator_response_file =
5974 initArgIteratorResponseFile(arena, resp_file_path) catch |err| {
5975 fatal("unable to read response file '{s}': {s}", .{ resp_file_path, @errorName(err) });
5976 };
5972 self.arg_iterator_response_file = initArgIteratorResponseFile(arena, io, resp_file_path) catch |err|
5973 fatal("unable to read response file '{s}': {t}", .{ resp_file_path, err });
59775974 // NOTE: The ArgIteratorResponseFile returns tokens from next() that are slices of an
59785975 // internal buffer. This internal buffer is arena allocated, so it is not cleaned up here.
59795976
......@@ -7405,7 +7402,7 @@ const Templates = struct {
74057402 }
74067403
74077404 const max_bytes = 10 * 1024 * 1024;
7408 const contents = templates.dir.readFileAlloc(template_path, arena, .limited(max_bytes)) catch |err| {
7405 const contents = templates.dir.readFileAlloc(io, template_path, arena, .limited(max_bytes)) catch |err| {
74097406 fatal("unable to read template file '{s}': {t}", .{ template_path, err });
74107407 };
74117408 templates.buffer.clearRetainingCapacity();