authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-14 20:12:54-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-15 14:18:20-08:00
logc917f619f041f5494e1c2d13c28ce1b04cec11f7
tree94147a6fa971063c2fa28ef72cf482e540768cfb
parenteb163361d9d7b61ee0b93b6f49efd24943c6027d

std: fix compilation failures on various targets


6 files changed, 77 insertions(+), 35 deletions(-)

lib/std/Io.zig+1-1
......@@ -656,7 +656,7 @@ pub const VTable = struct {
656656
657657 fileMemoryMapCreate: *const fn (?*anyopaque, File, File.MemoryMap.CreateOptions) File.MemoryMap.CreateError!File.MemoryMap,
658658 fileMemoryMapDestroy: *const fn (?*anyopaque, *File.MemoryMap) void,
659 fileMemoryMapSetLength: *const fn (?*anyopaque, *File.MemoryMap, n: usize) File.MemoryMap.SetLengthError!void,
659 fileMemoryMapSetLength: *const fn (?*anyopaque, *File.MemoryMap, File.MemoryMap.CreateOptions) File.MemoryMap.SetLengthError!void,
660660 fileMemoryMapRead: *const fn (?*anyopaque, *File.MemoryMap) File.ReadPositionalError!void,
661661 fileMemoryMapWrite: *const fn (?*anyopaque, *File.MemoryMap) File.WritePositionalError!void,
662662
lib/std/Io/File/MemoryMap.zig+19-9
......@@ -52,7 +52,9 @@ pub const CreateOptions = struct {
5252 /// undefined, and bytes unwritten before calling `write` to write
5353 /// undefined memory to the file.
5454 undefined_contents: bool = false,
55 /// Prefault the pages.
55 /// Prefault the pages. If this option is unsupported, it is silently
56 /// ignored. Aside from custom Io implementations, this option is only
57 /// supported on Linux.
5658 populate: bool = true,
5759 /// Asserted to be a multiple of page size which can be obtained via
5860 /// `std.heap.pageSize`.
......@@ -72,21 +74,29 @@ pub fn destroy(mm: *MemoryMap, io: Io) void {
7274}
7375
7476pub const SetLengthError = error{
77 /// One of the following:
78 /// * The `File.Kind` is not `file`.
79 /// * The file is not open for reading and read access protections enabled.
80 /// * The file is not open for writing and write access protections enabled.
81 AccessDenied,
82 /// The `prot` argument asks for `PROT_EXEC` but the mapped area belongs to a file on
83 /// a filesystem that was mounted no-exec.
84 PermissionDenied,
7585 LockedMemoryLimitExceeded,
86 ProcessFdQuotaExceeded,
87 SystemFdQuotaExceeded,
7688} || Allocator.Error || File.SetLengthError;
7789
7890/// Change the size of the mapping. This does not sync the contents. The size
7991/// of the file after calling this is unspecified until `write` is called.
8092///
8193/// May change the pointer address of `memory`.
82pub fn setLength(
83 mm: *MemoryMap,
84 io: Io,
85 /// New size of the mapping, in bytes. If this is longer than the file
86 /// size, it will be filled with zeroes. No alignment requirement.
87 new_length: usize,
88) SetLengthError!void {
89 return io.vtable.fileMemoryMapSetLength(io.userdata, mm, new_length);
94///
95/// `options` is needed because the mapping may need to be destroyed and
96/// re-created. All the same options must be provided except for `len` which is
97/// the new length.
98pub fn setLength(mm: *MemoryMap, io: Io, options: CreateOptions) SetLengthError!void {
99 return io.vtable.fileMemoryMapSetLength(io.userdata, mm, options);
90100}
91101
92102/// Synchronizes the contents of `memory` from `file`.
lib/std/Io/Threaded.zig+52-22
......@@ -7998,7 +7998,7 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
79987998 .FAULT => |err| return errnoBug(err),
79997999 .AGAIN => return error.WouldBlock,
80008000 .BADF => |err| {
8001 if (native_os == .wasi) return error.NotOpenForReading; // File operation on directory.
8001 if (native_os == .wasi) return error.IsDir; // File operation on directory.
80028002 return errnoBug(err); // File descriptor used after closed.
80038003 },
80048004 .IO => return error.InputOutput,
......@@ -8089,7 +8089,7 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8
80898089 syscall.finish();
80908090 return nread;
80918091 },
8092 .INTR => {
8092 .INTR, .TIMEDOUT => {
80938093 try syscall.checkCancel();
80948094 continue;
80958095 },
......@@ -8103,7 +8103,6 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8
81038103 .ISDIR => return syscall.fail(error.IsDir),
81048104 .NOBUFS => return syscall.fail(error.SystemResources),
81058105 .NOMEM => return syscall.fail(error.SystemResources),
8106 .TIMEDOUT => return syscall.fail(error.Timeout),
81078106 .NXIO => return syscall.fail(error.Unseekable),
81088107 .SPIPE => return syscall.fail(error.Unseekable),
81098108 .OVERFLOW => return syscall.fail(error.Unseekable),
......@@ -12588,7 +12587,7 @@ fn statFromPosix(st: *const posix.Stat) File.Stat {
1258812587 .atime = timestampFromPosix(&atime),
1258912588 .mtime = timestampFromPosix(&mtime),
1259012589 .ctime = timestampFromPosix(&ctime),
12591 .block_size = st.blksize,
12590 .block_size = @intCast(st.blksize),
1259212591 };
1259312592}
1259412593
......@@ -16292,9 +16291,14 @@ fn createFileMap(
1629216291 .WRITE = protection.write,
1629316292 .EXEC = protection.execute,
1629416293 };
16295 const flags: posix.MAP = .{
16296 .TYPE = if (native_os == .linux) .SHARED_VALIDATE else .SHARED,
16297 .POPULATE = populate,
16294 const flags: posix.MAP = switch (native_os) {
16295 .linux => .{
16296 .TYPE = .SHARED_VALIDATE,
16297 .POPULATE = populate,
16298 },
16299 else => .{
16300 .TYPE = .SHARED,
16301 },
1629816302 };
1629916303
1630016304 const page_align = std.heap.page_size_min;
......@@ -16348,20 +16352,20 @@ fn createFileMap(
1634816352fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void {
1634916353 const t: *Threaded = @ptrCast(@alignCast(userdata));
1635016354 const memory = mm.memory;
16351 if (mm.section) |section| {
16352 if (is_windows) {
16355 if (mm.section) |section| switch (native_os) {
16356 .windows => {
1635316357 const current_process: windows.HANDLE = @ptrFromInt(@as(usize, @bitCast(@as(isize, -1))));
1635416358 _ = windows.ntdll.NtUnmapViewOfSection(current_process, memory.ptr);
1635516359 windows.CloseHandle(section);
16356 } else {
16357 switch (posix.errno(posix.system.munmap(memory.ptr, memory.len))) {
16358 .SUCCESS => {},
16359 else => |e| {
16360 if (builtin.mode == .Debug)
16361 std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, e });
16362 },
16363 }
16364 }
16360 },
16361 .wasi => unreachable,
16362 else => switch (posix.errno(posix.system.munmap(memory.ptr, memory.len))) {
16363 .SUCCESS => {},
16364 else => |e| {
16365 if (builtin.mode == .Debug)
16366 std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, e });
16367 },
16368 },
1636516369 } else {
1636616370 const gpa = t.allocator;
1636716371 gpa.rawFree(memory, .fromByteUnits(std.heap.pageSize()), @returnAddress());
......@@ -16372,15 +16376,17 @@ fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void {
1637216376fn fileMemoryMapSetLength(
1637316377 userdata: ?*anyopaque,
1637416378 mm: *File.MemoryMap,
16375 new_len: usize,
16379 options: File.MemoryMap.CreateOptions,
1637616380) File.MemoryMap.SetLengthError!void {
1637716381 const t: *Threaded = @ptrCast(@alignCast(userdata));
1637816382 const page_size = std.heap.pageSize();
1637916383 const alignment: Alignment = .fromByteUnits(page_size);
1638016384 const page_align = std.heap.page_size_min;
16385 const old_memory = mm.memory;
16386 const new_len = options.len;
1638116387
1638216388 if (mm.section) |section| {
16383 if (alignment.forward(new_len) == alignment.forward(mm.memory.len)) {
16389 if (alignment.forward(new_len) == alignment.forward(old_memory.len)) {
1638416390 mm.memory.len = new_len;
1638516391 return;
1638616392 }
......@@ -16390,12 +16396,12 @@ fn fileMemoryMapSetLength(
1639016396 @panic("TODO");
1639116397 },
1639216398 .wasi => unreachable,
16393 else => {
16399 .linux => {
1639416400 const flags: posix.MREMAP = .{ .MAYMOVE = true };
1639516401 const addr_hint: ?[*]const u8 = null;
1639616402 const new_memory = while (true) {
1639716403 const syscall: Syscall = try .start();
16398 const rc = posix.system.mremap(mm.memory.ptr, mm.memory.len, new_len, flags, addr_hint);
16404 const rc = posix.system.mremap(old_memory.ptr, old_memory.len, new_len, flags, addr_hint);
1639916405 syscall.finish();
1640016406 const err: posix.E = if (builtin.link_libc) e: {
1640116407 if (rc != std.c.MAP_FAILED) break @as([*]align(page_align) u8, @ptrCast(@alignCast(rc)))[0..new_len];
......@@ -16417,6 +16423,30 @@ fn fileMemoryMapSetLength(
1641716423 };
1641816424 mm.memory = new_memory;
1641916425 },
16426 else => {
16427 switch (posix.errno(posix.system.munmap(old_memory.ptr, old_memory.len))) {
16428 .SUCCESS => {},
16429 else => |e| {
16430 if (builtin.mode == .Debug) std.log.err("failed to unmap {d} bytes at {*}: {t}", .{
16431 old_memory.len, old_memory.ptr, e,
16432 });
16433 // munmap must be infallible, or we cannot design reliable software.
16434 return error.Unexpected;
16435 },
16436 }
16437 if (createFileMap(mm.file, options.protection, mm.offset, options.populate, new_len)) |result| {
16438 mm.* = result;
16439 return;
16440 } else |err| switch (err) {
16441 error.OperationUnsupported,
16442 error.Unseekable,
16443 error.SectionOversize,
16444 error.MappingAlreadyExists,
16445 error.FileLockConflict,
16446 => return error.Unexpected, // It worked before on the same open file.
16447 else => |e| return e,
16448 }
16449 },
1642016450 }
1642116451 } else {
1642216452 const gpa = t.allocator;
lib/std/Io/Threaded/test.zig+1-1
......@@ -255,7 +255,7 @@ test "memory mapping fallback" {
255255
256256 try testing.expectEqualStrings("this9is9my", mm.memory);
257257
258 try mm.setLength(io, "this9is9my data123".len);
258 try mm.setLength(io, .{ .len = "this9is9my data123".len });
259259 try mm.read(io);
260260
261261 try testing.expectEqualStrings("this9is9my data123", mm.memory);
lib/std/Io/test.zig+3-1
......@@ -594,6 +594,8 @@ test "randomSecure" {
594594}
595595
596596test "memory mapping" {
597 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; // mmap returned EINVAL
598
597599 const io = testing.io;
598600
599601 var tmp = tmpDir(.{});
......@@ -634,7 +636,7 @@ test "memory mapping" {
634636
635637 try expectEqualStrings("this9is9my", mm.memory);
636638
637 try mm.setLength(io, "this9is9my data123".len);
639 try mm.setLength(io, .{ .len = "this9is9my data123".len });
638640 try mm.read(io);
639641
640642 try expectEqualStrings("this9is9my data123", mm.memory);
lib/std/c.zig+1-1
......@@ -10334,7 +10334,7 @@ pub extern "c" fn getgrgid(gid: gid_t) ?*group;
1033410334pub extern "c" fn getgrgid_r(gid: gid_t, grp: *group, buf: [*]u8, buflen: usize, result: *?*group) c_int;
1033510335pub extern "c" fn getrlimit64(resource: rlimit_resource, rlim: *rlimit) c_int;
1033610336pub extern "c" fn lseek64(fd: fd_t, offset: i64, whence: c_int) i64;
10337pub extern "c" fn mmap64(addr: ?*align(page_size) anyopaque, len: usize, prot: PROT, flags: c_uint, fd: fd_t, offset: i64) *anyopaque;
10337pub extern "c" fn mmap64(addr: ?*align(page_size) anyopaque, len: usize, prot: PROT, flags: MAP, fd: fd_t, offset: i64) *anyopaque;
1033810338pub extern "c" fn open64(path: [*:0]const u8, oflag: O, ...) c_int;
1033910339pub extern "c" fn openat64(fd: c_int, path: [*:0]const u8, oflag: O, ...) c_int;
1034010340pub extern "c" fn pread64(fd: fd_t, buf: [*]u8, nbyte: usize, offset: i64) isize;