From 1ed845e1f6fabdde8795513de2d06bc9b573779c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 11 Dec 2025 23:41:57 -0800 Subject: [PATCH] update occurences of setEndPos to setLength --- lib/compiler/objcopy.zig | 3 +- lib/std/Io/test.zig | 68 +++++++++++++++++++++++++++++---- lib/std/fs/test.zig | 51 ------------------------- src/Zcu/PerThread.zig | 2 +- src/link/C.zig | 4 +- src/link/Elf.zig | 13 +++++-- src/link/Elf/relocatable.zig | 3 +- src/link/MachO/DebugSymbols.zig | 6 ++- src/link/MachO/relocatable.zig | 3 +- src/link/MappedFile.zig | 5 +++ src/link/Wasm.zig | 4 +- 11 files changed, 89 insertions(+), 73 deletions(-) diff --git a/lib/compiler/objcopy.zig b/lib/compiler/objcopy.zig index d9b9b331861d37bebbe70b440627de3b29a6bc4d..90fd122294ea7d5c935b8b48e651271376dd1662 100644 --- a/lib/compiler/objcopy.zig +++ b/lib/compiler/objcopy.zig @@ -676,8 +676,9 @@ fn containsValidAddressRange(segments: []*BinaryElfSegment) bool { } fn padFile(out: *File.Writer, opt_size: ?u64) !void { + const io = out.io; const size = opt_size orelse return; - try out.file.setEndPos(size); + try out.file.setLength(io, size); } test "HexWriter.Record.Address has correct payload and checksum" { diff --git a/lib/std/Io/test.zig b/lib/std/Io/test.zig index 891c751ef21ad0abe34f7ca1257c27444070cba6..8f32555b52e96b22c2a8ee630feb4b3db18fb64b 100644 --- a/lib/std/Io/test.zig +++ b/lib/std/Io/test.zig @@ -3,16 +3,17 @@ const native_endian = builtin.cpu.arch.endian(); const std = @import("std"); const Io = std.Io; -const testing = std.testing; -const expect = std.testing.expect; -const expectEqual = std.testing.expectEqual; -const expectError = std.testing.expectError; const DefaultPrng = std.Random.DefaultPrng; const mem = std.mem; const fs = std.fs; const File = std.Io.File; const assert = std.debug.assert; +const testing = std.testing; +const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; +const expectError = std.testing.expectError; +const expectEqualStrings = std.testing.expectEqualStrings; const tmpDir = std.testing.tmpDir; test "write a file, read it, then delete it" { @@ -89,7 +90,7 @@ test "File seek ops" { try expect((try file.getPos()) == 1234); } -test "setEndPos" { +test "setLength" { const io = testing.io; var tmp = tmpDir(.{}); @@ -102,18 +103,69 @@ test "setEndPos" { // Verify that the file size changes and the file offset is not moved try expect((try file.length(io)) == 0); try expect((try file.getPos()) == 0); - try file.setEndPos(8192); + try file.setLength(io, 8192); try expect((try file.length(io)) == 8192); try expect((try file.getPos()) == 0); try file.seekTo(100); - try file.setEndPos(4096); + try file.setLength(io, 4096); try expect((try file.length(io)) == 4096); try expect((try file.getPos()) == 100); - try file.setEndPos(0); + try file.setLength(io, 0); try expect((try file.length(io)) == 0); try expect((try file.getPos()) == 100); } +test "legacy setLength" { + // https://github.com/ziglang/zig/issues/20747 (open fd does not have write permission) + if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest; + if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23806 + + const io = testing.io; + + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + + const file_name = "afile.txt"; + try tmp.dir.writeFile(io, .{ .sub_path = file_name, .data = "ninebytes" }); + const f = try tmp.dir.openFile(io, file_name, .{ .mode = .read_write }); + defer f.close(io); + + const initial_size = try f.length(io); + var buffer: [32]u8 = undefined; + var reader = f.reader(io, &.{}); + + { + try f.setLength(io, initial_size); + try expectEqual(initial_size, try f.length(io)); + try reader.seekTo(0); + try expectEqual(initial_size, try reader.interface.readSliceShort(&buffer)); + try expectEqualStrings("ninebytes", buffer[0..@intCast(initial_size)]); + } + + { + const larger = initial_size + 4; + try f.setLength(io, larger); + try expectEqual(larger, try f.length(io)); + try reader.seekTo(0); + try expectEqual(larger, try reader.interface.readSliceShort(&buffer)); + try expectEqualStrings("ninebytes\x00\x00\x00\x00", buffer[0..@intCast(larger)]); + } + + { + const smaller = initial_size - 5; + try f.setLength(io, smaller); + try expectEqual(smaller, try f.length(io)); + try reader.seekTo(0); + try expectEqual(smaller, try reader.interface.readSliceShort(&buffer)); + try expectEqualStrings("nine", buffer[0..@intCast(smaller)]); + } + + try f.setLength(io, 0); + try expectEqual(0, try f.length(io)); + try reader.seekTo(0); + try expectEqual(0, try reader.interface.readSliceShort(&buffer)); +} + test "setTimestamps" { const io = testing.io; diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 1a8e5adfbd56fa9aa6e63f12cc7621705fb186ad..0f4707c6cd87c0e674688c883f0d008702bd7485 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -1451,57 +1451,6 @@ test "pwritev, preadv" { try expectError(error.EndOfStream, reader.interface.readSliceAll(&buf1)); } -test "setEndPos" { - // https://github.com/ziglang/zig/issues/20747 (open fd does not have write permission) - if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest; - if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23806 - - const io = testing.io; - - var tmp = tmpDir(.{}); - defer tmp.cleanup(); - - const file_name = "afile.txt"; - try tmp.dir.writeFile(io, .{ .sub_path = file_name, .data = "ninebytes" }); - const f = try tmp.dir.openFile(io, file_name, .{ .mode = .read_write }); - defer f.close(io); - - const initial_size = try f.length(io); - var buffer: [32]u8 = undefined; - var reader = f.reader(io, &.{}); - - { - try f.setEndPos(initial_size); - try expectEqual(initial_size, try f.length(io)); - try reader.seekTo(0); - try expectEqual(initial_size, try reader.interface.readSliceShort(&buffer)); - try expectEqualStrings("ninebytes", buffer[0..@intCast(initial_size)]); - } - - { - const larger = initial_size + 4; - try f.setEndPos(larger); - try expectEqual(larger, try f.length(io)); - try reader.seekTo(0); - try expectEqual(larger, try reader.interface.readSliceShort(&buffer)); - try expectEqualStrings("ninebytes\x00\x00\x00\x00", buffer[0..@intCast(larger)]); - } - - { - const smaller = initial_size - 5; - try f.setEndPos(smaller); - try expectEqual(smaller, try f.length(io)); - try reader.seekTo(0); - try expectEqual(smaller, try reader.interface.readSliceShort(&buffer)); - try expectEqualStrings("nine", buffer[0..@intCast(smaller)]); - } - - try f.setEndPos(0); - try expectEqual(0, try f.length(io)); - try reader.seekTo(0); - try expectEqual(0, try reader.interface.readSliceShort(&buffer)); -} - test "access file" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 9d6a45ad2672c24bf4821bcc5becbafe4e03dbc6..2333d7f286c6db98ae09c945a3b4cdfc7a5477fc 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -245,7 +245,7 @@ pub fn updateFile( if (need_update) { // The cache is definitely stale so delete the contents to avoid an underwrite later. - cache_file.setEndPos(0) catch |err| switch (err) { + cache_file.setLength(io, 0) catch |err| switch (err) { error.FileTooBig => unreachable, // 0 is not too big else => |e| return e, }; diff --git a/src/link/C.zig b/src/link/C.zig index db5acebf07e9f8b94c4a3b13148dbad07bc3dcc5..93e771ebfc3d01a61f7fb5268bd84fe8b639f489 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -509,7 +509,7 @@ pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.P }, self.getString(av_block.code)); const file = self.base.file.?; - file.setEndPos(f.file_size) catch |err| return diags.fail("failed to allocate file: {s}", .{@errorName(err)}); + file.setLength(io, f.file_size) catch |err| return diags.fail("failed to allocate file: {t}", .{err}); var fw = file.writer(io, &.{}); var w = &fw.interface; w.writeVecAll(f.all_buffers.items) catch |err| switch (err) { @@ -800,7 +800,7 @@ pub fn flushEmitH(zcu: *Zcu) !void { }); defer file.close(io); - try file.setEndPos(file_size); + try file.setLength(io, file_size); try file.pwritevAll(all_buffers.items, 0); } diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 2916f5ee2598f72749185d21b5282aca08a57e7b..11bf4489579f31e74ab48b9021778e7af4aebf7e 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -487,6 +487,8 @@ pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.Relo /// Returns end pos of collision, if any. fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 { + const comp = self.base.comp; + const io = comp.io; const small_ptr = self.ptr_width == .p32; const ehdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Ehdr) else @sizeOf(elf.Elf64_Ehdr); if (start < ehdr_size) @@ -526,7 +528,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 { } } - if (at_end) try self.base.file.?.setEndPos(end); + if (at_end) try self.base.file.?.setLength(io, end); return null; } @@ -556,6 +558,8 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 { } pub fn growSection(self: *Elf, shdr_index: u32, needed_size: u64, min_alignment: u64) !void { + const comp = self.base.comp; + const io = comp.io; const shdr = &self.sections.items(.shdr)[shdr_index]; if (shdr.sh_type != elf.SHT_NOBITS) { @@ -589,7 +593,7 @@ pub fn growSection(self: *Elf, shdr_index: u32, needed_size: u64, min_alignment: shdr.sh_offset = new_offset; } else if (shdr.sh_offset + allocated_size == std.math.maxInt(u64)) { - try self.base.file.?.setEndPos(shdr.sh_offset + needed_size); + try self.base.file.?.setLength(io, shdr.sh_offset + needed_size); } } @@ -4446,10 +4450,11 @@ pub fn pwriteAll(elf_file: *Elf, bytes: []const u8, offset: u64) error{LinkFailu }; } -pub fn setEndPos(elf_file: *Elf, length: u64) error{LinkFailure}!void { +pub fn setLength(elf_file: *Elf, length: u64) error{LinkFailure}!void { const comp = elf_file.base.comp; + const io = comp.i; const diags = &comp.link_diags; - elf_file.base.file.?.setEndPos(length) catch |err| { + elf_file.base.file.?.setLength(io, length) catch |err| { return diags.fail("failed to set file end pos: {s}", .{@errorName(err)}); }; } diff --git a/src/link/Elf/relocatable.zig b/src/link/Elf/relocatable.zig index 7adeecdcdedbad72e3a6f0567bd3c596a37e9abb..0627d8586fdbb52fc3bb6cfd8260a1edb79d29e2 100644 --- a/src/link/Elf/relocatable.zig +++ b/src/link/Elf/relocatable.zig @@ -1,5 +1,6 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { const gpa = comp.gpa; + const io = comp.io; const diags = &comp.link_diags; if (diags.hasErrors()) return error.LinkFailure; @@ -125,7 +126,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { assert(writer.buffered().len == total_size); - try elf_file.base.file.?.setEndPos(total_size); + try elf_file.base.file.?.setLength(io, total_size); try elf_file.base.file.?.pwriteAll(writer.buffered(), 0); if (diags.hasErrors()) return error.LinkFailure; diff --git a/src/link/MachO/DebugSymbols.zig b/src/link/MachO/DebugSymbols.zig index 8a97f2844f2c41efc819bd8d6ce0760870414224..1ec19ecea79c01cf6e2ffdb92b32fde600dea046 100644 --- a/src/link/MachO/DebugSymbols.zig +++ b/src/link/MachO/DebugSymbols.zig @@ -125,6 +125,7 @@ pub fn growSection( requires_file_copy: bool, macho_file: *MachO, ) !void { + const io = self.io; const sect = self.getSectionPtr(sect_index); const allocated_size = self.allocatedSize(sect.offset); @@ -152,7 +153,7 @@ pub fn growSection( sect.offset = @intCast(new_offset); } else if (sect.offset + allocated_size == std.math.maxInt(u64)) { - try self.file.?.setEndPos(sect.offset + needed_size); + try self.file.?.setLength(io, sect.offset + needed_size); } sect.size = needed_size; @@ -176,6 +177,7 @@ pub fn markDirty(self: *DebugSymbols, sect_index: u8, macho_file: *MachO) void { } fn detectAllocCollision(self: *DebugSymbols, start: u64, size: u64) !?u64 { + const io = self.io; var at_end = true; const end = start + padToIdeal(size); @@ -188,7 +190,7 @@ fn detectAllocCollision(self: *DebugSymbols, start: u64, size: u64) !?u64 { } } - if (at_end) try self.file.?.setEndPos(end); + if (at_end) try self.file.?.setLength(io, end); return null; } diff --git a/src/link/MachO/relocatable.zig b/src/link/MachO/relocatable.zig index e9f78a8ef2fd6d04d652332cab95049c82c6a293..6bddfc63897583d1c838e244f4a4fbd375fcda21 100644 --- a/src/link/MachO/relocatable.zig +++ b/src/link/MachO/relocatable.zig @@ -80,6 +80,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void { const gpa = comp.gpa; + const io = comp.io; const diags = &macho_file.base.comp.link_diags; var positionals = std.array_list.Managed(link.Input).init(gpa); @@ -230,7 +231,7 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ? assert(writer.end == total_size); - try macho_file.setEndPos(total_size); + try macho_file.setLength(io, total_size); try macho_file.pwriteAll(writer.buffered(), 0); if (diags.hasErrors()) return error.LinkFailure; diff --git a/src/link/MappedFile.zig b/src/link/MappedFile.zig index 974b03ef7f753b3e77fb275a974d55342d08a95b..06767b3709bf53ee6e662734a0fc15803c6c2c21 100644 --- a/src/link/MappedFile.zig +++ b/src/link/MappedFile.zig @@ -35,6 +35,11 @@ pub const Error = std.posix.MMapError || std.posix.MRemapError || Io.File.Length IsDir, Unseekable, NoSpaceLeft, + + InputOutput, + FileTooBig, + FileBusy, + NonResizable, }; pub fn init(file: std.Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile { diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 489fb8e6fea1409a6417a9de22656ae6db331554..39e3bb3d5d4def35c3288e3dc7edfd5eaac69cab 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -3018,12 +3018,12 @@ pub fn createEmpty( fn openParseObjectReportingFailure(wasm: *Wasm, path: Path) void { const diags = &wasm.base.comp.link_diags; const obj = link.openObject(path, false, false) catch |err| { - switch (diags.failParse(path, "failed to open object: {s}", .{@errorName(err)})) { + switch (diags.failParse(path, "failed to open object: {t}", .{err})) { error.LinkFailure => return, } }; wasm.parseObject(obj) catch |err| { - switch (diags.failParse(path, "failed to parse object: {s}", .{@errorName(err)})) { + switch (diags.failParse(path, "failed to parse object: {t}", .{err})) { error.LinkFailure => return, } }; -- 2.54.0