update occurences of setEndPos to setLength

This commit is contained in:
Andrew Kelley 2025-12-11 23:41:57 -08:00
parent 16f8af1b9a
commit 1ed845e1f6
11 changed files with 89 additions and 73 deletions

View file

@ -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" {

View file

@ -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;

View file

@ -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 {

View file

@ -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,
};

View file

@ -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);
}

View file

@ -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)});
};
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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 {

View file

@ -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,
}
};