authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-14 16:46:08-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-23 22:15:09-08:00
log4458e423bf2d2cf485031d1f527e407bfc9113df
tree346c1463c8bbf76bf690a056e2851754e8661dae
parent2a40c1b556d7ed7811d3d2432dce8ba5d7c2e753

link.MappedFile: update statx usage


6 files changed, 69 insertions(+), 31 deletions(-)

lib/std/Io/Threaded.zig+14-4
...@@ -1822,6 +1822,11 @@ fn dirStatFileLinux(...@@ -1822,6 +1822,11 @@ fn dirStatFileLinux(
1822 const t: *Threaded = @ptrCast(@alignCast(userdata));1822 const t: *Threaded = @ptrCast(@alignCast(userdata));
1823 const current_thread = Thread.getCurrent(t);1823 const current_thread = Thread.getCurrent(t);
1824 const linux = std.os.linux;1824 const linux = std.os.linux;
1825 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid())
1826 .{ .major = 30, .minor = 0, .patch = 0 }
1827 else
1828 .{ .major = 2, .minor = 28, .patch = 0 });
1829 const sys = if (use_c) std.c else std.os.linux;
18251830
1826 var path_buffer: [posix.PATH_MAX]u8 = undefined;1831 var path_buffer: [posix.PATH_MAX]u8 = undefined;
1827 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);1832 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
...@@ -1832,14 +1837,14 @@ fn dirStatFileLinux(...@@ -1832,14 +1837,14 @@ fn dirStatFileLinux(
1832 try current_thread.beginSyscall();1837 try current_thread.beginSyscall();
1833 while (true) {1838 while (true) {
1834 var statx = std.mem.zeroes(linux.Statx);1839 var statx = std.mem.zeroes(linux.Statx);
1835 const rc = linux.statx(1840 const rc = sys.statx(
1836 dir.handle,1841 dir.handle,
1837 sub_path_posix,1842 sub_path_posix,
1838 flags,1843 flags,
1839 .{ .TYPE = true, .MODE = true, .ATIME = true, .MTIME = true, .CTIME = true, .INO = true, .SIZE = true },1844 .{ .TYPE = true, .MODE = true, .ATIME = true, .MTIME = true, .CTIME = true, .INO = true, .SIZE = true },
1840 &statx,1845 &statx,
1841 );1846 );
1842 switch (linux.errno(rc)) {1847 switch (sys.errno(rc)) {
1843 .SUCCESS => {1848 .SUCCESS => {
1844 current_thread.endSyscall();1849 current_thread.endSyscall();
1845 assert(statx.mask.TYPE);1850 assert(statx.mask.TYPE);
...@@ -2076,18 +2081,23 @@ fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {...@@ -2076,18 +2081,23 @@ fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
2076 const t: *Threaded = @ptrCast(@alignCast(userdata));2081 const t: *Threaded = @ptrCast(@alignCast(userdata));
2077 const current_thread = Thread.getCurrent(t);2082 const current_thread = Thread.getCurrent(t);
2078 const linux = std.os.linux;2083 const linux = std.os.linux;
2084 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid())
2085 .{ .major = 30, .minor = 0, .patch = 0 }
2086 else
2087 .{ .major = 2, .minor = 28, .patch = 0 });
2088 const sys = if (use_c) std.c else std.os.linux;
20792089
2080 try current_thread.beginSyscall();2090 try current_thread.beginSyscall();
2081 while (true) {2091 while (true) {
2082 var statx = std.mem.zeroes(linux.Statx);2092 var statx = std.mem.zeroes(linux.Statx);
2083 const rc = linux.statx(2093 const rc = sys.statx(
2084 file.handle,2094 file.handle,
2085 "",2095 "",
2086 linux.AT.EMPTY_PATH,2096 linux.AT.EMPTY_PATH,
2087 .{ .TYPE = true, .MODE = true, .ATIME = true, .MTIME = true, .CTIME = true, .INO = true, .SIZE = true },2097 .{ .TYPE = true, .MODE = true, .ATIME = true, .MTIME = true, .CTIME = true, .INO = true, .SIZE = true },
2088 &statx,2098 &statx,
2089 );2099 );
2090 switch (linux.errno(rc)) {2100 switch (sys.errno(rc)) {
2091 .SUCCESS => {2101 .SUCCESS => {
2092 current_thread.endSyscall();2102 current_thread.endSyscall();
2093 assert(statx.mask.TYPE);2103 assert(statx.mask.TYPE);
lib/std/testing.zig+4-3
...@@ -1148,9 +1148,10 @@ pub fn checkAllAllocationFailures(backing_allocator: std.mem.Allocator, comptime...@@ -1148,9 +1148,10 @@ pub fn checkAllAllocationFailures(backing_allocator: std.mem.Allocator, comptime
1148 break :x failing_allocator_inst.alloc_index;1148 break :x failing_allocator_inst.alloc_index;
1149 };1149 };
11501150
1151 var fail_index: usize = 0;1151 for (0..needed_alloc_count) |fail_index| {
1152 while (fail_index < needed_alloc_count) : (fail_index += 1) {1152 var failing_allocator_inst = std.testing.FailingAllocator.init(backing_allocator, .{
1153 var failing_allocator_inst = std.testing.FailingAllocator.init(backing_allocator, .{ .fail_index = fail_index });1153 .fail_index = fail_index,
1154 });
1154 args.@"0" = failing_allocator_inst.allocator();1155 args.@"0" = failing_allocator_inst.allocator();
11551156
1156 if (@call(.auto, test_fn, args)) |_| {1157 if (@call(.auto, test_fn, args)) |_| {
lib/std/zig/ErrorBundle.zig+4-1
...@@ -168,7 +168,10 @@ pub fn renderToStderr(eb: ErrorBundle, io: Io, options: RenderOptions, color: st...@@ -168,7 +168,10 @@ pub fn renderToStderr(eb: ErrorBundle, io: Io, options: RenderOptions, color: st
168 var buffer: [256]u8 = undefined;168 var buffer: [256]u8 = undefined;
169 const stderr = try io.lockStderrWriter(&buffer);169 const stderr = try io.lockStderrWriter(&buffer);
170 defer io.unlockStderrWriter();170 defer io.unlockStderrWriter();
171 try renderToWriter(eb, options, &stderr.interface, color.getTtyConf(stderr.mode));171 renderToWriter(eb, options, &stderr.interface, color.getTtyConf(stderr.mode)) catch |err| switch (err) {
172 error.WriteFailed => return stderr.interface.err.?,
173 else => |e| return e,
174 };
172}175}
173176
174pub fn renderToWriter(177pub fn renderToWriter(
lib/std/zig/parser_test.zig+2-2
...@@ -6362,9 +6362,9 @@ fn testParse(io: Io, source: [:0]const u8, allocator: Allocator, anything_change...@@ -6362,9 +6362,9 @@ fn testParse(io: Io, source: [:0]const u8, allocator: Allocator, anything_change
6362 return formatted;6362 return formatted;
6363}6363}
6364fn testTransformImpl(6364fn testTransformImpl(
6365 io: Io,
6366 allocator: Allocator,6365 allocator: Allocator,
6367 fba: *std.heap.FixedBufferAllocator,6366 fba: *std.heap.FixedBufferAllocator,
6367 io: Io,
6368 source: [:0]const u8,6368 source: [:0]const u8,
6369 expected_source: []const u8,6369 expected_source: []const u8,
6370) !void {6370) !void {
...@@ -6386,7 +6386,7 @@ fn testTransform(source: [:0]const u8, expected_source: []const u8) !void {...@@ -6386,7 +6386,7 @@ fn testTransform(source: [:0]const u8, expected_source: []const u8) !void {
6386 const io = std.testing.io;6386 const io = std.testing.io;
6387 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);6387 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
6388 return std.testing.checkAllAllocationFailures(fixed_allocator.allocator(), testTransformImpl, .{6388 return std.testing.checkAllAllocationFailures(fixed_allocator.allocator(), testTransformImpl, .{
6389 io, &fixed_allocator, source, expected_source,6389 &fixed_allocator, io, source, expected_source,
6390 });6390 });
6391}6391}
6392fn testCanonical(source: [:0]const u8) !void {6392fn testCanonical(source: [:0]const u8) !void {
src/link/MappedFile.zig+36-12
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1/// TODO add a mapped file abstraction to std.Io
1const MappedFile = @This();2const MappedFile = @This();
23
3const builtin = @import("builtin");4const builtin = @import("builtin");
...@@ -74,18 +75,41 @@ pub fn init(file: std.Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile {...@@ -74,18 +75,41 @@ pub fn init(file: std.Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile {
74 };75 };
75 }76 }
76 if (is_linux) {77 if (is_linux) {
77 const statx = try linux.wrapped.statx(78 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid())
78 mf.file.handle,79 .{ .major = 30, .minor = 0, .patch = 0 }
79 "",80 else
80 std.posix.AT.EMPTY_PATH,81 .{ .major = 2, .minor = 28, .patch = 0 });
81 .{ .TYPE = true, .SIZE = true, .BLOCKS = true },82 const sys = if (use_c) std.c else std.os.linux;
82 );83 while (true) {
83 assert(statx.mask.TYPE);84 var statx = std.mem.zeroes(linux.Statx);
84 assert(statx.mask.SIZE);85 const rc = sys.statx(
85 assert(statx.mask.BLOCKS);86 mf.file.handle,
8687 "",
87 if (!std.posix.S.ISREG(statx.mode)) return error.PathAlreadyExists;88 std.posix.AT.EMPTY_PATH,
88 break :stat .{ statx.size, @max(std.heap.pageSize(), statx.blksize) };89 .{ .TYPE = true, .SIZE = true, .BLOCKS = true },
90 &statx,
91 );
92 switch (sys.errno(rc)) {
93 .SUCCESS => {
94 assert(statx.mask.TYPE);
95 assert(statx.mask.SIZE);
96 assert(statx.mask.BLOCKS);
97 if (!std.posix.S.ISREG(statx.mode)) return error.PathAlreadyExists;
98 break :stat .{ statx.size, @max(std.heap.pageSize(), statx.blksize) };
99 },
100 .INTR => continue,
101 .ACCES => return error.AccessDenied,
102 .BADF => if (std.debug.runtime_safety) unreachable else return error.Unexpected,
103 .FAULT => if (std.debug.runtime_safety) unreachable else return error.Unexpected,
104 .INVAL => if (std.debug.runtime_safety) unreachable else return error.Unexpected,
105 .LOOP => return error.SymLinkLoop,
106 .NAMETOOLONG => return error.NameTooLong,
107 .NOENT => return error.FileNotFound,
108 .NOTDIR => return error.FileNotFound,
109 .NOMEM => return error.SystemResources,
110 else => |err| return std.posix.unexpectedErrno(err),
111 }
112 }
89 }113 }
90 const stat = try std.posix.fstat(mf.file.handle);114 const stat = try std.posix.fstat(mf.file.handle);
91 if (!std.posix.S.ISREG(stat.mode)) return error.PathAlreadyExists;115 if (!std.posix.S.ISREG(stat.mode)) return error.PathAlreadyExists;
src/main.zig+9-9
...@@ -4607,7 +4607,7 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node)...@@ -4607,7 +4607,7 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node)
46074607
4608 if (errors.errorMessageCount() > 0) {4608 if (errors.errorMessageCount() > 0) {
4609 const io = comp.io;4609 const io = comp.io;
4610 errors.renderToStderr(io, .{}, color);4610 try errors.renderToStderr(io, .{}, color);
4611 return error.CompileErrorsReported;4611 return error.CompileErrorsReported;
4612 }4612 }
4613}4613}
...@@ -4660,7 +4660,7 @@ fn cmdTranslateC(...@@ -4660,7 +4660,7 @@ fn cmdTranslateC(
4660 return;4660 return;
4661 } else {4661 } else {
4662 const color: Color = .auto;4662 const color: Color = .auto;
4663 result.errors.renderToStderr(io, .{}, color);4663 result.errors.renderToStderr(io, .{}, color) catch {};
4664 process.exit(1);4664 process.exit(1);
4665 }4665 }
4666 }4666 }
...@@ -5281,7 +5281,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)...@@ -5281,7 +5281,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
52815281
5282 if (fetch.error_bundle.root_list.items.len > 0) {5282 if (fetch.error_bundle.root_list.items.len > 0) {
5283 var errors = try fetch.error_bundle.toOwnedBundle("");5283 var errors = try fetch.error_bundle.toOwnedBundle("");
5284 errors.renderToStderr(io, .{}, color);5284 errors.renderToStderr(io, .{}, color) catch {};
5285 process.exit(1);5285 process.exit(1);
5286 }5286 }
52875287
...@@ -6213,7 +6213,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {...@@ -6213,7 +6213,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {
6213 try wip_errors.init(arena);6213 try wip_errors.init(arena);
6214 try wip_errors.addZirErrorMessages(zir, tree, source, display_path);6214 try wip_errors.addZirErrorMessages(zir, tree, source, display_path);
6215 var error_bundle = try wip_errors.toOwnedBundle("");6215 var error_bundle = try wip_errors.toOwnedBundle("");
6216 error_bundle.renderToStderr(io, .{}, color);6216 try error_bundle.renderToStderr(io, .{}, color);
6217 if (zir.loweringFailed()) {6217 if (zir.loweringFailed()) {
6218 process.exit(1);6218 process.exit(1);
6219 }6219 }
...@@ -6284,7 +6284,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {...@@ -6284,7 +6284,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {
6284 try wip_errors.init(arena);6284 try wip_errors.init(arena);
6285 try wip_errors.addZoirErrorMessages(zoir, tree, source, display_path);6285 try wip_errors.addZoirErrorMessages(zoir, tree, source, display_path);
6286 var error_bundle = try wip_errors.toOwnedBundle("");6286 var error_bundle = try wip_errors.toOwnedBundle("");
6287 error_bundle.renderToStderr(io, .{}, color);6287 error_bundle.renderToStderr(io, .{}, color) catch {};
6288 process.exit(1);6288 process.exit(1);
6289 }6289 }
62906290
...@@ -6558,7 +6558,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {...@@ -6558,7 +6558,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {
6558 try wip_errors.init(arena);6558 try wip_errors.init(arena);
6559 try wip_errors.addZirErrorMessages(old_zir, old_tree, old_source, old_source_path);6559 try wip_errors.addZirErrorMessages(old_zir, old_tree, old_source, old_source_path);
6560 var error_bundle = try wip_errors.toOwnedBundle("");6560 var error_bundle = try wip_errors.toOwnedBundle("");
6561 error_bundle.renderToStderr(io, .{}, color);6561 error_bundle.renderToStderr(io, .{}, color) catch {};
6562 process.exit(1);6562 process.exit(1);
6563 }6563 }
65646564
...@@ -6570,7 +6570,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {...@@ -6570,7 +6570,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {
6570 try wip_errors.init(arena);6570 try wip_errors.init(arena);
6571 try wip_errors.addZirErrorMessages(new_zir, new_tree, new_source, new_source_path);6571 try wip_errors.addZirErrorMessages(new_zir, new_tree, new_source, new_source_path);
6572 var error_bundle = try wip_errors.toOwnedBundle("");6572 var error_bundle = try wip_errors.toOwnedBundle("");
6573 error_bundle.renderToStderr(io, .{}, color);6573 error_bundle.renderToStderr(io, .{}, color) catch {};
6574 process.exit(1);6574 process.exit(1);
6575 }6575 }
65766576
...@@ -7006,7 +7006,7 @@ fn cmdFetch(...@@ -7006,7 +7006,7 @@ fn cmdFetch(
70067006
7007 if (fetch.error_bundle.root_list.items.len > 0) {7007 if (fetch.error_bundle.root_list.items.len > 0) {
7008 var errors = try fetch.error_bundle.toOwnedBundle("");7008 var errors = try fetch.error_bundle.toOwnedBundle("");
7009 errors.renderToStderr(io, .{}, color);7009 errors.renderToStderr(io, .{}, color) catch {};
7010 process.exit(1);7010 process.exit(1);
7011 }7011 }
70127012
...@@ -7363,7 +7363,7 @@ fn loadManifest(...@@ -7363,7 +7363,7 @@ fn loadManifest(
73637363
7364 var error_bundle = try wip_errors.toOwnedBundle("");7364 var error_bundle = try wip_errors.toOwnedBundle("");
7365 defer error_bundle.deinit(gpa);7365 defer error_bundle.deinit(gpa);
7366 error_bundle.renderToStderr(io, .{}, options.color);7366 error_bundle.renderToStderr(io, .{}, options.color) catch {};
73677367
7368 process.exit(2);7368 process.exit(2);
7369 }7369 }