authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-08 14:17:52-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-23 22:15:08-08:00
log9f4d40b1f9bffc4137055b8a07f042ecfa398124
treebe2a20f7e4f0d09a955c654e6627d147836954da
parent264d714321d3e5f1f189af393e1fb24d101a7e91

update all stat() to stat(io)


23 files changed, 80 insertions(+), 68 deletions(-)

lib/compiler/objcopy.zig+1-1
...@@ -155,7 +155,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void...@@ -155,7 +155,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void
155 const input_file = Io.Dir.cwd().openFile(input, .{}) catch |err| fatal("failed to open {s}: {t}", .{ input, err });155 const input_file = Io.Dir.cwd().openFile(input, .{}) catch |err| fatal("failed to open {s}: {t}", .{ input, err });
156 defer input_file.close(io);156 defer input_file.close(io);
157157
158 const stat = input_file.stat() catch |err| fatal("failed to stat {s}: {t}", .{ input, err });158 const stat = input_file.stat(io) catch |err| fatal("failed to stat {s}: {t}", .{ input, err });
159159
160 var in: File.Reader = .initSize(input_file, io, &input_buffer, stat.size);160 var in: File.Reader = .initSize(input_file, io, &input_buffer, stat.size);
161161
lib/compiler/resinator/utils.zig+1-1
...@@ -38,7 +38,7 @@ pub fn openFileNotDir(...@@ -38,7 +38,7 @@ pub fn openFileNotDir(
38 errdefer file.close(io);38 errdefer file.close(io);
39 // https://github.com/ziglang/zig/issues/573239 // https://github.com/ziglang/zig/issues/5732
40 if (builtin.os.tag != .windows) {40 if (builtin.os.tag != .windows) {
41 const stat = try file.stat();41 const stat = try file.stat(io);
4242
43 if (stat.kind == .directory)43 if (stat.kind == .directory)
44 return error.IsDir;44 return error.IsDir;
lib/compiler/std-docs.zig+1-1
...@@ -227,7 +227,7 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void {...@@ -227,7 +227,7 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void {
227 }227 }
228 var file = try entry.dir.openFile(io, entry.basename, .{});228 var file = try entry.dir.openFile(io, entry.basename, .{});
229 defer file.close(io);229 defer file.close(io);
230 const stat = try file.stat();230 const stat = try file.stat(io);
231 var file_reader: std.Io.File.Reader = .{231 var file_reader: std.Io.File.Reader = .{
232 .file = file,232 .file = file,
233 .interface = std.Io.File.Reader.initInterface(&.{}),233 .interface = std.Io.File.Reader.initInterface(&.{}),
lib/std/Build/Cache.zig+5-4
...@@ -775,7 +775,7 @@ pub const Manifest = struct {...@@ -775,7 +775,7 @@ pub const Manifest = struct {
775 };775 };
776 defer this_file.close(io);776 defer this_file.close(io);
777777
778 const actual_stat = this_file.stat() catch |err| {778 const actual_stat = this_file.stat(io) catch |err| {
779 self.diagnostic = .{ .file_stat = .{779 self.diagnostic = .{ .file_stat = .{
780 .file_index = idx,780 .file_index = idx,
781 .err = err,781 .err = err,
...@@ -883,7 +883,7 @@ pub const Manifest = struct {...@@ -883,7 +883,7 @@ pub const Manifest = struct {
883 defer file.close(io);883 defer file.close(io);
884884
885 // Save locally and also save globally (we still hold the global lock).885 // Save locally and also save globally (we still hold the global lock).
886 const stat = file.stat() catch |err| switch (err) {886 const stat = file.stat(io) catch |err| switch (err) {
887 error.Canceled => return error.Canceled,887 error.Canceled => return error.Canceled,
888 else => return true,888 else => return true,
889 };889 };
...@@ -909,7 +909,8 @@ pub const Manifest = struct {...@@ -909,7 +909,8 @@ pub const Manifest = struct {
909 }909 }
910910
911 fn populateFileHashHandle(self: *Manifest, ch_file: *File, handle: Io.File) !void {911 fn populateFileHashHandle(self: *Manifest, ch_file: *File, handle: Io.File) !void {
912 const actual_stat = try handle.stat();912 const io = self.cache.io;
913 const actual_stat = try handle.stat(io);
913 ch_file.stat = .{914 ch_file.stat = .{
914 .size = actual_stat.size,915 .size = actual_stat.size,
915 .mtime = actual_stat.mtime,916 .mtime = actual_stat.mtime,
...@@ -1333,7 +1334,7 @@ fn testGetCurrentFileTimestamp(io: Io, dir: Io.Dir) !Io.Timestamp {...@@ -1333,7 +1334,7 @@ fn testGetCurrentFileTimestamp(io: Io, dir: Io.Dir) !Io.Timestamp {
1333 dir.deleteFile(test_out_file) catch {};1334 dir.deleteFile(test_out_file) catch {};
1334 }1335 }
13351336
1336 return (try file.stat()).mtime;1337 return (try file.stat(io)).mtime;
1337}1338}
13381339
1339test "cache file and then recall it" {1340test "cache file and then recall it" {
lib/std/Build/WebServer.zig+1-1
...@@ -509,7 +509,7 @@ pub fn serveTarFile(ws: *WebServer, request: *http.Server.Request, paths: []cons...@@ -509,7 +509,7 @@ pub fn serveTarFile(ws: *WebServer, request: *http.Server.Request, paths: []cons
509 continue;509 continue;
510 };510 };
511 defer file.close(io);511 defer file.close(io);
512 const stat = try file.stat();512 const stat = try file.stat(io);
513 var read_buffer: [1024]u8 = undefined;513 var read_buffer: [1024]u8 = undefined;
514 var file_reader: Io.File.Reader = .initSize(file, io, &read_buffer, stat.size);514 var file_reader: Io.File.Reader = .initSize(file, io, &read_buffer, stat.size);
515515
lib/std/Io/test.zig+2-2
...@@ -124,13 +124,13 @@ test "updateTimes" {...@@ -124,13 +124,13 @@ test "updateTimes" {
124 var file = try tmp.dir.createFile(io, tmp_file_name, .{ .read = true });124 var file = try tmp.dir.createFile(io, tmp_file_name, .{ .read = true });
125 defer file.close(io);125 defer file.close(io);
126126
127 const stat_old = try file.stat();127 const stat_old = try file.stat(io);
128 // Set atime and mtime to 5s before128 // Set atime and mtime to 5s before
129 try file.updateTimes(129 try file.updateTimes(
130 stat_old.atime.subDuration(.fromSeconds(5)),130 stat_old.atime.subDuration(.fromSeconds(5)),
131 stat_old.mtime.subDuration(.fromSeconds(5)),131 stat_old.mtime.subDuration(.fromSeconds(5)),
132 );132 );
133 const stat_new = try file.stat();133 const stat_new = try file.stat(io);
134 try expect(stat_new.atime.nanoseconds < stat_old.atime.nanoseconds);134 try expect(stat_new.atime.nanoseconds < stat_old.atime.nanoseconds);
135 try expect(stat_new.mtime.nanoseconds < stat_old.mtime.nanoseconds);135 try expect(stat_new.mtime.nanoseconds < stat_old.mtime.nanoseconds);
136}136}
lib/std/dynamic_library.zig+1-1
...@@ -226,7 +226,7 @@ pub const ElfDynLib = struct {...@@ -226,7 +226,7 @@ pub const ElfDynLib = struct {
226 defer posix.close(fd);226 defer posix.close(fd);
227227
228 const file: Io.File = .{ .handle = fd };228 const file: Io.File = .{ .handle = fd };
229 const stat = try file.stat();229 const stat = try file.stat(io);
230 const size = std.math.cast(usize, stat.size) orelse return error.FileTooBig;230 const size = std.math.cast(usize, stat.size) orelse return error.FileTooBig;
231231
232 const page_size = std.heap.pageSize();232 const page_size = std.heap.pageSize();
lib/std/fs/test.zig+11-11
...@@ -350,7 +350,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {...@@ -350,7 +350,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {
350 };350 };
351 defer symlink.close(io);351 defer symlink.close(io);
352352
353 const stat = try symlink.stat();353 const stat = try symlink.stat(io);
354 try testing.expectEqual(File.Kind.sym_link, stat.kind);354 try testing.expectEqual(File.Kind.sym_link, stat.kind);
355 }355 }
356 }.impl);356 }.impl);
...@@ -396,7 +396,7 @@ test "openDirAbsolute" {...@@ -396,7 +396,7 @@ test "openDirAbsolute" {
396 var tmp = tmpDir(.{});396 var tmp = tmpDir(.{});
397 defer tmp.cleanup();397 defer tmp.cleanup();
398398
399 const tmp_ino = (try tmp.dir.stat()).inode;399 const tmp_ino = (try tmp.dir.stat(io)).inode;
400400
401 try tmp.dir.makeDir("subdir");401 try tmp.dir.makeDir("subdir");
402 const sub_path = try tmp.dir.realpathAlloc(testing.allocator, "subdir");402 const sub_path = try tmp.dir.realpathAlloc(testing.allocator, "subdir");
...@@ -406,7 +406,7 @@ test "openDirAbsolute" {...@@ -406,7 +406,7 @@ test "openDirAbsolute" {
406 var tmp_sub = try fs.openDirAbsolute(sub_path, .{});406 var tmp_sub = try fs.openDirAbsolute(sub_path, .{});
407 defer tmp_sub.close(io);407 defer tmp_sub.close(io);
408408
409 const sub_ino = (try tmp_sub.stat()).inode;409 const sub_ino = (try tmp_sub.stat(io)).inode;
410410
411 {411 {
412 // Can open sub_path + ".."412 // Can open sub_path + ".."
...@@ -416,7 +416,7 @@ test "openDirAbsolute" {...@@ -416,7 +416,7 @@ test "openDirAbsolute" {
416 var dir = try fs.openDirAbsolute(dir_path, .{});416 var dir = try fs.openDirAbsolute(dir_path, .{});
417 defer dir.close(io);417 defer dir.close(io);
418418
419 const ino = (try dir.stat()).inode;419 const ino = (try dir.stat(io)).inode;
420 try testing.expectEqual(tmp_ino, ino);420 try testing.expectEqual(tmp_ino, ino);
421 }421 }
422422
...@@ -428,7 +428,7 @@ test "openDirAbsolute" {...@@ -428,7 +428,7 @@ test "openDirAbsolute" {
428 var dir = try fs.openDirAbsolute(dir_path, .{});428 var dir = try fs.openDirAbsolute(dir_path, .{});
429 defer dir.close(io);429 defer dir.close(io);
430430
431 const ino = (try dir.stat()).inode;431 const ino = (try dir.stat(io)).inode;
432 try testing.expectEqual(sub_ino, ino);432 try testing.expectEqual(sub_ino, ino);
433 }433 }
434434
...@@ -440,7 +440,7 @@ test "openDirAbsolute" {...@@ -440,7 +440,7 @@ test "openDirAbsolute" {
440 var dir = try fs.openDirAbsolute(dir_path, .{});440 var dir = try fs.openDirAbsolute(dir_path, .{});
441 defer dir.close(io);441 defer dir.close(io);
442442
443 const ino = (try dir.stat()).inode;443 const ino = (try dir.stat(io)).inode;
444 try testing.expectEqual(tmp_ino, ino);444 try testing.expectEqual(tmp_ino, ino);
445 }445 }
446}446}
...@@ -849,7 +849,7 @@ test "directory operations on files" {...@@ -849,7 +849,7 @@ test "directory operations on files" {
849849
850 // ensure the file still exists and is a file as a sanity check850 // ensure the file still exists and is a file as a sanity check
851 file = try ctx.dir.openFile(io, test_file_name, .{});851 file = try ctx.dir.openFile(io, test_file_name, .{});
852 const stat = try file.stat();852 const stat = try file.stat(io);
853 try testing.expectEqual(File.Kind.file, stat.kind);853 try testing.expectEqual(File.Kind.file, stat.kind);
854 file.close(io);854 file.close(io);
855 }855 }
...@@ -1151,7 +1151,7 @@ test "renameAbsolute" {...@@ -1151,7 +1151,7 @@ test "renameAbsolute" {
1151 // ensure the file was renamed1151 // ensure the file was renamed
1152 try testing.expectError(error.FileNotFound, tmp_dir.dir.openFile(io, test_file_name, .{}));1152 try testing.expectError(error.FileNotFound, tmp_dir.dir.openFile(io, test_file_name, .{}));
1153 file = try tmp_dir.dir.openFile(io, renamed_test_file_name, .{});1153 file = try tmp_dir.dir.openFile(io, renamed_test_file_name, .{});
1154 const stat = try file.stat();1154 const stat = try file.stat(io);
1155 try testing.expectEqual(File.Kind.file, stat.kind);1155 try testing.expectEqual(File.Kind.file, stat.kind);
1156 file.close(io);1156 file.close(io);
11571157
...@@ -2099,17 +2099,17 @@ test "chmod" {...@@ -2099,17 +2099,17 @@ test "chmod" {
20992099
2100 const file = try tmp.dir.createFile(io, "test_file", .{ .mode = 0o600 });2100 const file = try tmp.dir.createFile(io, "test_file", .{ .mode = 0o600 });
2101 defer file.close(io);2101 defer file.close(io);
2102 try testing.expectEqual(@as(File.Mode, 0o600), (try file.stat()).mode & 0o7777);2102 try testing.expectEqual(@as(File.Mode, 0o600), (try file.stat(io)).mode & 0o7777);
21032103
2104 try file.chmod(0o644);2104 try file.chmod(0o644);
2105 try testing.expectEqual(@as(File.Mode, 0o644), (try file.stat()).mode & 0o7777);2105 try testing.expectEqual(@as(File.Mode, 0o644), (try file.stat(io)).mode & 0o7777);
21062106
2107 try tmp.dir.makeDir("test_dir");2107 try tmp.dir.makeDir("test_dir");
2108 var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true });2108 var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true });
2109 defer dir.close(io);2109 defer dir.close(io);
21102110
2111 try dir.chmod(0o700);2111 try dir.chmod(0o700);
2112 try testing.expectEqual(@as(File.Mode, 0o700), (try dir.stat()).mode & 0o7777);2112 try testing.expectEqual(@as(File.Mode, 0o700), (try dir.stat(io)).mode & 0o7777);
2113}2113}
21142114
2115test "chown" {2115test "chown" {
lib/std/os/linux/IoUring.zig+3-3
...@@ -2655,7 +2655,7 @@ test "fallocate" {...@@ -2655,7 +2655,7 @@ test "fallocate" {
2655 const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 });2655 const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 });
2656 defer file.close(io);2656 defer file.close(io);
26572657
2658 try testing.expectEqual(@as(u64, 0), (try file.stat()).size);2658 try testing.expectEqual(@as(u64, 0), (try file.stat(io)).size);
26592659
2660 const len: u64 = 65536;2660 const len: u64 = 65536;
2661 const sqe = try ring.fallocate(0xaaaaaaaa, file.handle, 0, 0, len);2661 const sqe = try ring.fallocate(0xaaaaaaaa, file.handle, 0, 0, len);
...@@ -2681,7 +2681,7 @@ test "fallocate" {...@@ -2681,7 +2681,7 @@ test "fallocate" {
2681 .flags = 0,2681 .flags = 0,
2682 }, cqe);2682 }, cqe);
26832683
2684 try testing.expectEqual(len, (try file.stat()).size);2684 try testing.expectEqual(len, (try file.stat(io)).size);
2685}2685}
26862686
2687test "statx" {2687test "statx" {
...@@ -2702,7 +2702,7 @@ test "statx" {...@@ -2702,7 +2702,7 @@ test "statx" {
2702 const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 });2702 const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 });
2703 defer file.close(io);2703 defer file.close(io);
27042704
2705 try testing.expectEqual(@as(u64, 0), (try file.stat()).size);2705 try testing.expectEqual(@as(u64, 0), (try file.stat(io)).size);
27062706
2707 try file.writeAll("foobar");2707 try file.writeAll("foobar");
27082708
lib/std/os/linux/test.zig+2-2
...@@ -21,7 +21,7 @@ test "fallocate" {...@@ -21,7 +21,7 @@ test "fallocate" {
21 const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 });21 const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 });
22 defer file.close(io);22 defer file.close(io);
2323
24 try expect((try file.stat()).size == 0);24 try expect((try file.stat(io)).size == 0);
2525
26 const len: i64 = 65536;26 const len: i64 = 65536;
27 switch (linux.errno(linux.fallocate(file.handle, 0, 0, len))) {27 switch (linux.errno(linux.fallocate(file.handle, 0, 0, len))) {
...@@ -31,7 +31,7 @@ test "fallocate" {...@@ -31,7 +31,7 @@ test "fallocate" {
31 else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),31 else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
32 }32 }
3333
34 try expect((try file.stat()).size == len);34 try expect((try file.stat(io)).size == len);
35}35}
3636
37test "getpid" {37test "getpid" {
src/Compilation.zig+1-1
...@@ -5367,7 +5367,7 @@ fn docsCopyModule(...@@ -5367,7 +5367,7 @@ fn docsCopyModule(
5367 });5367 });
5368 };5368 };
5369 defer file.close(io);5369 defer file.close(io);
5370 const stat = try file.stat();5370 const stat = try file.stat(io);
5371 var file_reader: Io.File.Reader = .initSize(file, io, &buffer, stat.size);5371 var file_reader: Io.File.Reader = .initSize(file, io, &buffer, stat.size);
53725372
5373 archiver.writeFileTimestamp(entry.path, &file_reader, stat.mtime) catch |err| {5373 archiver.writeFileTimestamp(entry.path, &file_reader, stat.mtime) catch |err| {
src/Zcu.zig+1-1
...@@ -1080,7 +1080,7 @@ pub const File = struct {...@@ -1080,7 +1080,7 @@ pub const File = struct {
1080 };1080 };
1081 defer f.close(io);1081 defer f.close(io);
10821082
1083 const stat = f.stat() catch |err| switch (err) {1083 const stat = f.stat(io) catch |err| switch (err) {
1084 error.Streaming => {1084 error.Streaming => {
1085 // Since `file.stat` is populated, this was previously a file stream; since it is1085 // Since `file.stat` is populated, this was previously a file stream; since it is
1086 // now not a file stream, it must have changed.1086 // now not a file stream, it must have changed.
src/Zcu/PerThread.zig+2-2
...@@ -98,7 +98,7 @@ pub fn updateFile(...@@ -98,7 +98,7 @@ pub fn updateFile(
98 };98 };
99 defer source_file.close(io);99 defer source_file.close(io);
100100
101 const stat = try source_file.stat();101 const stat = try source_file.stat(io);
102102
103 const want_local_cache = switch (file.path.root) {103 const want_local_cache = switch (file.path.root) {
104 .none, .local_cache => true,104 .none, .local_cache => true,
...@@ -2470,7 +2470,7 @@ fn updateEmbedFileInner(...@@ -2470,7 +2470,7 @@ fn updateEmbedFileInner(
2470 };2470 };
2471 defer file.close(io);2471 defer file.close(io);
24722472
2473 const stat: Cache.File.Stat = .fromFs(try file.stat());2473 const stat: Cache.File.Stat = .fromFs(try file.stat(io));
24742474
2475 if (ef.val != .none) {2475 if (ef.val != .none) {
2476 const old_stat = ef.stat;2476 const old_stat = ef.stat;
src/fmt.zig+3-3
...@@ -188,7 +188,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !...@@ -188,7 +188,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !
188 error.IsDir => dir: {188 error.IsDir => dir: {
189 var dir = try Io.Dir.cwd().openDir(io, file_path, .{});189 var dir = try Io.Dir.cwd().openDir(io, file_path, .{});
190 defer dir.close(io);190 defer dir.close(io);
191 break :dir try dir.stat();191 break :dir try dir.stat(io);
192 },192 },
193 else => |e| return e,193 else => |e| return e,
194 };194 };
...@@ -227,7 +227,7 @@ fn fmtPathDir(...@@ -227,7 +227,7 @@ fn fmtPathDir(
227 var dir = try parent_dir.openDir(io, parent_sub_path, .{ .iterate = true });227 var dir = try parent_dir.openDir(io, parent_sub_path, .{ .iterate = true });
228 defer dir.close(io);228 defer dir.close(io);
229229
230 const stat = try dir.stat();230 const stat = try dir.stat(io);
231 if (try fmt.seen.fetchPut(stat.inode, {})) |_| return;231 if (try fmt.seen.fetchPut(stat.inode, {})) |_| return;
232232
233 var dir_it = dir.iterate();233 var dir_it = dir.iterate();
...@@ -266,7 +266,7 @@ fn fmtPathFile(...@@ -266,7 +266,7 @@ fn fmtPathFile(
266 var file_closed = false;266 var file_closed = false;
267 errdefer if (!file_closed) source_file.close(io);267 errdefer if (!file_closed) source_file.close(io);
268268
269 const stat = try source_file.stat();269 const stat = try source_file.stat(io);
270270
271 if (stat.kind == .directory)271 if (stat.kind == .directory)
272 return error.IsDir;272 return error.IsDir;
src/link.zig+3-3
...@@ -1112,10 +1112,10 @@ pub const File = struct {...@@ -1112,10 +1112,10 @@ pub const File = struct {
11121112
1113 fn loadGnuLdScript(base: *File, path: Path, parent_query: UnresolvedInput.Query, file: Io.File) anyerror!void {1113 fn loadGnuLdScript(base: *File, path: Path, parent_query: UnresolvedInput.Query, file: Io.File) anyerror!void {
1114 const comp = base.comp;1114 const comp = base.comp;
1115 const io = comp.io;
1115 const diags = &comp.link_diags;1116 const diags = &comp.link_diags;
1116 const gpa = comp.gpa;1117 const gpa = comp.gpa;
1117 const io = comp.io;1118 const stat = try file.stat(io);
1118 const stat = try file.stat();
1119 const size = std.math.cast(u32, stat.size) orelse return error.FileTooBig;1119 const size = std.math.cast(u32, stat.size) orelse return error.FileTooBig;
1120 const buf = try gpa.alloc(u8, size);1120 const buf = try gpa.alloc(u8, size);
1121 defer gpa.free(buf);1121 defer gpa.free(buf);
...@@ -2180,7 +2180,7 @@ fn resolvePathInputLib(...@@ -2180,7 +2180,7 @@ fn resolvePathInputLib(
2180 // Appears to be an ELF or archive file.2180 // Appears to be an ELF or archive file.
2181 return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);2181 return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);
2182 }2182 }
2183 const stat = file.stat() catch |err|2183 const stat = file.stat(io) catch |err|
2184 fatal("failed to stat {f}: {s}", .{ test_path, @errorName(err) });2184 fatal("failed to stat {f}: {s}", .{ test_path, @errorName(err) });
2185 const size = std.math.cast(u32, stat.size) orelse2185 const size = std.math.cast(u32, stat.size) orelse
2186 fatal("{f}: linker script too big", .{test_path});2186 fatal("{f}: linker script too big", .{test_path});
src/link/Elf.zig+3-2
...@@ -742,7 +742,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {...@@ -742,7 +742,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {
742 .dso_exact => @panic("TODO"),742 .dso_exact => @panic("TODO"),
743 .object => |obj| try parseObject(self, obj),743 .object => |obj| try parseObject(self, obj),
744 .archive => |obj| try parseArchive(gpa, diags, &self.file_handles, &self.files, target, debug_fmt_strip, default_sym_version, &self.objects, obj, is_static_lib),744 .archive => |obj| try parseArchive(gpa, diags, &self.file_handles, &self.files, target, debug_fmt_strip, default_sym_version, &self.objects, obj, is_static_lib),
745 .dso => |dso| try parseDso(gpa, diags, dso, &self.shared_objects, &self.files, target),745 .dso => |dso| try parseDso(gpa, io, diags, dso, &self.shared_objects, &self.files, target),
746 }746 }
747}747}
748748
...@@ -1136,6 +1136,7 @@ fn parseArchive(...@@ -1136,6 +1136,7 @@ fn parseArchive(
11361136
1137fn parseDso(1137fn parseDso(
1138 gpa: Allocator,1138 gpa: Allocator,
1139 io: Io,
1139 diags: *Diags,1140 diags: *Diags,
1140 dso: link.Input.Dso,1141 dso: link.Input.Dso,
1141 shared_objects: *std.StringArrayHashMapUnmanaged(File.Index),1142 shared_objects: *std.StringArrayHashMapUnmanaged(File.Index),
...@@ -1147,7 +1148,7 @@ fn parseDso(...@@ -1147,7 +1148,7 @@ fn parseDso(
11471148
1148 const handle = dso.file;1149 const handle = dso.file;
11491150
1150 const stat = Stat.fromFs(try handle.stat());1151 const stat = Stat.fromFs(try handle.stat(io));
1151 var header = try SharedObject.parseHeader(gpa, diags, dso.path, handle, stat, target);1152 var header = try SharedObject.parseHeader(gpa, diags, dso.path, handle, stat, target);
1152 defer header.deinit(gpa);1153 defer header.deinit(gpa);
11531154
src/link/Elf/Archive.zig+24-21
...@@ -1,3 +1,21 @@...@@ -1,3 +1,21 @@
1const Archive = @This();
2
3const std = @import("std");
4const Io = std.Io;
5const assert = std.debug.assert;
6const elf = std.elf;
7const fs = std.fs;
8const log = std.log.scoped(.link);
9const mem = std.mem;
10const Path = std.Build.Cache.Path;
11const Allocator = std.mem.Allocator;
12
13const Diags = @import("../../link.zig").Diags;
14const Elf = @import("../Elf.zig");
15const File = @import("file.zig").File;
16const Object = @import("Object.zig");
17const StringTable = @import("../StringTable.zig");
18
1objects: []const Object,19objects: []const Object,
2/// '\n'-delimited20/// '\n'-delimited
3strtab: []const u8,21strtab: []const u8,
...@@ -10,6 +28,7 @@ pub fn deinit(a: *Archive, gpa: Allocator) void {...@@ -10,6 +28,7 @@ pub fn deinit(a: *Archive, gpa: Allocator) void {
1028
11pub fn parse(29pub fn parse(
12 gpa: Allocator,30 gpa: Allocator,
31 io: Io,
13 diags: *Diags,32 diags: *Diags,
14 file_handles: *const std.ArrayList(File.Handle),33 file_handles: *const std.ArrayList(File.Handle),
15 path: Path,34 path: Path,
...@@ -25,7 +44,7 @@ pub fn parse(...@@ -25,7 +44,7 @@ pub fn parse(
25 pos += magic_buffer.len;44 pos += magic_buffer.len;
26 }45 }
2746
28 const size = (try handle.stat()).size;47 const size = (try handle.stat(io)).size;
2948
30 var objects: std.ArrayList(Object) = .empty;49 var objects: std.ArrayList(Object) = .empty;
31 defer objects.deinit(gpa);50 defer objects.deinit(gpa);
...@@ -120,7 +139,7 @@ pub fn setArHdr(opts: struct {...@@ -120,7 +139,7 @@ pub fn setArHdr(opts: struct {
120 @memset(mem.asBytes(&hdr), 0x20);139 @memset(mem.asBytes(&hdr), 0x20);
121140
122 {141 {
123 var writer: std.Io.Writer = .fixed(&hdr.ar_name);142 var writer: Io.Writer = .fixed(&hdr.ar_name);
124 switch (opts.name) {143 switch (opts.name) {
125 .symtab => writer.print("{s}", .{elf.SYM64NAME}) catch unreachable,144 .symtab => writer.print("{s}", .{elf.SYM64NAME}) catch unreachable,
126 .strtab => writer.print("//", .{}) catch unreachable,145 .strtab => writer.print("//", .{}) catch unreachable,
...@@ -133,7 +152,7 @@ pub fn setArHdr(opts: struct {...@@ -133,7 +152,7 @@ pub fn setArHdr(opts: struct {
133 hdr.ar_gid[0] = '0';152 hdr.ar_gid[0] = '0';
134 hdr.ar_mode[0] = '0';153 hdr.ar_mode[0] = '0';
135 {154 {
136 var writer: std.Io.Writer = .fixed(&hdr.ar_size);155 var writer: Io.Writer = .fixed(&hdr.ar_size);
137 writer.print("{d}", .{opts.size}) catch unreachable;156 writer.print("{d}", .{opts.size}) catch unreachable;
138 }157 }
139 hdr.ar_fmag = elf.ARFMAG.*;158 hdr.ar_fmag = elf.ARFMAG.*;
...@@ -206,7 +225,7 @@ pub const ArSymtab = struct {...@@ -206,7 +225,7 @@ pub const ArSymtab = struct {
206 ar: ArSymtab,225 ar: ArSymtab,
207 elf_file: *Elf,226 elf_file: *Elf,
208227
209 fn default(f: Format, writer: *std.Io.Writer) std.Io.Writer.Error!void {228 fn default(f: Format, writer: *Io.Writer) Io.Writer.Error!void {
210 const ar = f.ar;229 const ar = f.ar;
211 const elf_file = f.elf_file;230 const elf_file = f.elf_file;
212 for (ar.symtab.items, 0..) |entry, i| {231 for (ar.symtab.items, 0..) |entry, i| {
...@@ -261,7 +280,7 @@ pub const ArStrtab = struct {...@@ -261,7 +280,7 @@ pub const ArStrtab = struct {
261 try writer.writeAll(ar.buffer.items);280 try writer.writeAll(ar.buffer.items);
262 }281 }
263282
264 pub fn format(ar: ArStrtab, writer: *std.Io.Writer) std.Io.Writer.Error!void {283 pub fn format(ar: ArStrtab, writer: *Io.Writer) Io.Writer.Error!void {
265 try writer.print("{f}", .{std.ascii.hexEscape(ar.buffer.items, .lower)});284 try writer.print("{f}", .{std.ascii.hexEscape(ar.buffer.items, .lower)});
266 }285 }
267};286};
...@@ -277,19 +296,3 @@ pub const ArState = struct {...@@ -277,19 +296,3 @@ pub const ArState = struct {
277 /// Total size of the contributing object (excludes ar_hdr).296 /// Total size of the contributing object (excludes ar_hdr).
278 size: u64 = 0,297 size: u64 = 0,
279};298};
280
281const std = @import("std");
282const assert = std.debug.assert;
283const elf = std.elf;
284const fs = std.fs;
285const log = std.log.scoped(.link);
286const mem = std.mem;
287const Path = std.Build.Cache.Path;
288const Allocator = std.mem.Allocator;
289
290const Diags = @import("../../link.zig").Diags;
291const Archive = @This();
292const Elf = @import("../Elf.zig");
293const File = @import("file.zig").File;
294const Object = @import("Object.zig");
295const StringTable = @import("../StringTable.zig");
src/link/Elf/Object.zig+5-2
...@@ -122,13 +122,14 @@ pub fn parse(...@@ -122,13 +122,14 @@ pub fn parse(
122pub fn parseCommon(122pub fn parseCommon(
123 self: *Object,123 self: *Object,
124 gpa: Allocator,124 gpa: Allocator,
125 io: Io,
125 diags: *Diags,126 diags: *Diags,
126 path: Path,127 path: Path,
127 handle: Io.File,128 handle: Io.File,
128 target: *const std.Target,129 target: *const std.Target,
129) !void {130) !void {
130 const offset = if (self.archive) |ar| ar.offset else 0;131 const offset = if (self.archive) |ar| ar.offset else 0;
131 const file_size = (try handle.stat()).size;132 const file_size = (try handle.stat(io)).size;
132133
133 const header_buffer = try Elf.preadAllAlloc(gpa, handle, offset, @sizeOf(elf.Elf64_Ehdr));134 const header_buffer = try Elf.preadAllAlloc(gpa, handle, offset, @sizeOf(elf.Elf64_Ehdr));
134 defer gpa.free(header_buffer);135 defer gpa.free(header_buffer);
...@@ -1122,9 +1123,11 @@ pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf...@@ -1122,9 +1123,11 @@ pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf
1122}1123}
11231124
1124pub fn updateArSize(self: *Object, elf_file: *Elf) !void {1125pub fn updateArSize(self: *Object, elf_file: *Elf) !void {
1126 const comp = elf_file.base.comp;
1127 const io = comp.io;
1125 self.output_ar_state.size = if (self.archive) |ar| ar.size else size: {1128 self.output_ar_state.size = if (self.archive) |ar| ar.size else size: {
1126 const handle = elf_file.fileHandle(self.file_handle);1129 const handle = elf_file.fileHandle(self.file_handle);
1127 break :size (try handle.stat()).size;1130 break :size (try handle.stat(io)).size;
1128 };1131 };
1129}1132}
11301133
src/link/MachO.zig+2-1
...@@ -925,6 +925,7 @@ fn addObject(self: *MachO, path: Path, handle_index: File.HandleIndex, offset: u...@@ -925,6 +925,7 @@ fn addObject(self: *MachO, path: Path, handle_index: File.HandleIndex, offset: u
925925
926 const comp = self.base.comp;926 const comp = self.base.comp;
927 const gpa = comp.gpa;927 const gpa = comp.gpa;
928 const io = comp.io;
928929
929 const abs_path = try std.fs.path.resolvePosix(gpa, &.{930 const abs_path = try std.fs.path.resolvePosix(gpa, &.{
930 comp.dirs.cwd,931 comp.dirs.cwd,
...@@ -934,7 +935,7 @@ fn addObject(self: *MachO, path: Path, handle_index: File.HandleIndex, offset: u...@@ -934,7 +935,7 @@ fn addObject(self: *MachO, path: Path, handle_index: File.HandleIndex, offset: u
934 errdefer gpa.free(abs_path);935 errdefer gpa.free(abs_path);
935936
936 const file = self.getFileHandle(handle_index);937 const file = self.getFileHandle(handle_index);
937 const stat = try file.stat();938 const stat = try file.stat(io);
938 const mtime = stat.mtime.toSeconds();939 const mtime = stat.mtime.toSeconds();
939 const index: File.Index = @intCast(try self.files.addOne(gpa));940 const index: File.Index = @intCast(try self.files.addOne(gpa));
940 self.files.set(index, .{ .object = .{941 self.files.set(index, .{ .object = .{
src/link/MachO/Archive.zig+2-1
...@@ -6,6 +6,7 @@ pub fn deinit(self: *Archive, allocator: Allocator) void {...@@ -6,6 +6,7 @@ pub fn deinit(self: *Archive, allocator: Allocator) void {
66
7pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File.HandleIndex, fat_arch: ?fat.Arch) !void {7pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File.HandleIndex, fat_arch: ?fat.Arch) !void {
8 const comp = macho_file.base.comp;8 const comp = macho_file.base.comp;
9 const io = comp.io;
9 const gpa = comp.gpa;10 const gpa = comp.gpa;
10 const diags = &comp.link_diags;11 const diags = &comp.link_diags;
1112
...@@ -14,7 +15,7 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File...@@ -14,7 +15,7 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File
1415
15 const handle = macho_file.getFileHandle(handle_index);16 const handle = macho_file.getFileHandle(handle_index);
16 const offset = if (fat_arch) |ar| ar.offset else 0;17 const offset = if (fat_arch) |ar| ar.offset else 0;
17 const end_pos = if (fat_arch) |ar| offset + ar.size else (try handle.stat()).size;18 const end_pos = if (fat_arch) |ar| offset + ar.size else (try handle.stat(io)).size;
1819
19 var pos: usize = offset + SARMAG;20 var pos: usize = offset + SARMAG;
20 while (true) {21 while (true) {
src/link/MachO/Object.zig+3-1
...@@ -1689,9 +1689,11 @@ pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, macho_file: *M...@@ -1689,9 +1689,11 @@ pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, macho_file: *M
1689}1689}
16901690
1691pub fn updateArSize(self: *Object, macho_file: *MachO) !void {1691pub fn updateArSize(self: *Object, macho_file: *MachO) !void {
1692 const comp = macho_file.base.comp;
1693 const io = comp.io;
1692 self.output_ar_state.size = if (self.in_archive) |ar| ar.size else size: {1694 self.output_ar_state.size = if (self.in_archive) |ar| ar.size else size: {
1693 const file = macho_file.getFileHandle(self.file_handle);1695 const file = macho_file.getFileHandle(self.file_handle);
1694 break :size (try file.stat()).size;1696 break :size (try file.stat(io)).size;
1695 };1697 };
1696}1698}
16971699
src/link/MachO/relocatable.zig+1-1
...@@ -22,7 +22,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat...@@ -22,7 +22,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat
22 const path = positionals.items[0].path().?;22 const path = positionals.items[0].path().?;
23 const in_file = path.root_dir.handle.openFile(io, path.sub_path, .{}) catch |err|23 const in_file = path.root_dir.handle.openFile(io, path.sub_path, .{}) catch |err|
24 return diags.fail("failed to open {f}: {s}", .{ path, @errorName(err) });24 return diags.fail("failed to open {f}: {s}", .{ path, @errorName(err) });
25 const stat = in_file.stat() catch |err|25 const stat = in_file.stat(io) catch |err|
26 return diags.fail("failed to stat {f}: {s}", .{ path, @errorName(err) });26 return diags.fail("failed to stat {f}: {s}", .{ path, @errorName(err) });
27 const amt = in_file.copyRangeAll(0, macho_file.base.file.?, 0, stat.size) catch |err|27 const amt = in_file.copyRangeAll(0, macho_file.base.file.?, 0, stat.size) catch |err|
28 return diags.fail("failed to copy range of file {f}: {s}", .{ path, @errorName(err) });28 return diags.fail("failed to copy range of file {f}: {s}", .{ path, @errorName(err) });
src/link/tapi.zig+2-2
...@@ -139,9 +139,9 @@ pub const LibStub = struct {...@@ -139,9 +139,9 @@ pub const LibStub = struct {
139 /// Typed contents of the tbd file.139 /// Typed contents of the tbd file.
140 inner: []Tbd,140 inner: []Tbd,
141141
142 pub fn loadFromFile(allocator: Allocator, file: Io.File) TapiError!LibStub {142 pub fn loadFromFile(allocator: Allocator, io: Io, file: Io.File) TapiError!LibStub {
143 const filesize = blk: {143 const filesize = blk: {
144 const stat = file.stat() catch break :blk std.math.maxInt(u32);144 const stat = file.stat(io) catch break :blk std.math.maxInt(u32);
145 break :blk @min(stat.size, std.math.maxInt(u32));145 break :blk @min(stat.size, std.math.maxInt(u32));
146 };146 };
147 const source = try allocator.alloc(u8, filesize);147 const source = try allocator.alloc(u8, filesize);