From 3e624e17a40fd65b68dbec45030280008c6b4018 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 19 Dec 2025 14:14:21 -0800 Subject: [PATCH] std: fix compilation errors on FreeBSD --- lib/std/Io/File/Writer.zig | 2 ++ lib/std/Io/Threaded.zig | 45 ++++++++++++++++++++++++++++---------- lib/std/c.zig | 1 + lib/std/process.zig | 5 ++++- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/lib/std/Io/File/Writer.zig b/lib/std/Io/File/Writer.zig index 3487416719a59d1f87fb90a48043ca52804201f9..226b60993f954b7bce70d41c501d35795daacbcf 100644 --- a/lib/std/Io/File/Writer.zig +++ b/lib/std/Io/File/Writer.zig @@ -49,6 +49,8 @@ pub const Error = error{ pub const WriteFileError = Error || error{ /// Descriptor is not valid or locked, or an mmap(2)-like operation is not available for in_fd. Unimplemented, + /// Can happen on FreeBSD when using copy_file_range. + CorruptedData, EndOfStream, ReadFailed, }; diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index 37136879a380453f2b2639bb92a294691a6a9dbb..7dd9ef51009f8bfd998cf62afb09edf68d659d76 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -366,12 +366,12 @@ const Thread = struct { fn futexWake(ptr: *const u32, max_waiters: u32) void { @branchHint(.cold); + assert(max_waiters != 0); if (builtin.single_threaded) return; // nothing to wake up if (builtin.cpu.arch.isWasm()) { comptime assert(builtin.cpu.has(.wasm, .atomics)); - assert(max_waiters != 0); const woken_count = asm volatile ( \\local.get %[ptr] \\local.get %[waiters] @@ -416,7 +416,6 @@ const Thread = struct { } }, .windows => { - assert(max_waiters != 0); switch (max_waiters) { 1 => windows.ntdll.RtlWakeAddressSingle(ptr), else => windows.ntdll.RtlWakeAddressAll(ptr), @@ -953,7 +952,8 @@ const have_fchown = switch (native_os) { }; const have_fchmod = switch (native_os) { - .wasi, .windows => false, + .windows => false, + .wasi => builtin.link_libc, else => true, }; @@ -6772,7 +6772,7 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi var result: u64 = undefined; try current_thread.beginSyscall(); while (true) { - switch (posix.errno(posix.system.llseek(fd, offset, &result, posix.SEEK.CUR))) { + switch (posix.errno(posix.system.llseek(fd, @bitCast(offset), &result, posix.SEEK.CUR))) { .SUCCESS => { current_thread.endSyscall(); return; @@ -7000,7 +7000,7 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex if (rc != 0) return error.NameTooLong; var real_path_buf: [posix.PATH_MAX]u8 = undefined; - const n = Io.Dir.realPathAbsolute(ioBasic(t), &symlink_path_buf, &real_path_buf) catch |err| switch (err) { + const n = Io.Dir.realPathFileAbsolute(ioBasic(t), &symlink_path_buf, &real_path_buf) catch |err| switch (err) { error.NetworkNotFound => unreachable, // Windows-only else => |e| return e, }; @@ -7020,11 +7020,32 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex }, .freebsd, .dragonfly => { const current_thread = Thread.getCurrent(t); - try current_thread.checkCancel(); var mib: [4]c_int = .{ posix.CTL.KERN, posix.KERN.PROC, posix.KERN.PROC_PATHNAME, -1 }; var out_len: usize = out_buffer.len; - try posix.sysctl(&mib, out_buffer.ptr, &out_len, null, 0); - return out_len; + try current_thread.beginSyscall(); + while (true) { + switch (posix.errno(posix.system.sysctl(&mib, mib.len, out_buffer.ptr, &out_len, null, 0))) { + .SUCCESS => { + current_thread.endSyscall(); + return out_len; + }, + .INTR => { + try current_thread.checkCancel(); + continue; + }, + .CANCELED => return current_thread.endSyscallCanceled(), + else => |e| { + current_thread.endSyscall(); + switch (e) { + .FAULT => |err| return errnoBug(err), + .PERM => return error.PermissionDenied, + .NOMEM => return error.SystemResources, + .NOENT => |err| return errnoBug(err), + else => |err| return posix.unexpectedErrno(err), + } + }, + } + } }, .netbsd => { const current_thread = Thread.getCurrent(t); @@ -7043,7 +7064,7 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex if (std.mem.indexOf(u8, argv0, "/") != null) { // argv[0] is a path (relative or absolute): use realpath(3) directly var real_path_buf: [posix.PATH_MAX]u8 = undefined; - const real_path = Io.Dir.realPathAbsolute(ioBasic(t), std.os.argv[0], &real_path_buf) catch |err| switch (err) { + const real_path = Io.Dir.realPathFileAbsolute(ioBasic(t), std.os.argv[0], &real_path_buf) catch |err| switch (err) { error.NetworkNotFound => unreachable, // Windows-only else => |e| return e, }; @@ -7063,7 +7084,7 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex }, 0) catch continue; var real_path_buf: [posix.PATH_MAX]u8 = undefined; - if (Io.Dir.realPathAbsolute(ioBasic(t), resolved_path, &real_path_buf)) |real_path| { + if (Io.Dir.realPathFileAbsolute(ioBasic(t), resolved_path, &real_path_buf)) |real_path| { // found a file, and hope it is the right file if (real_path.len > out_buffer.len) return error.NameTooLong; @@ -7730,8 +7751,8 @@ fn fileWriteFileStreaming( .FBIG => return error.FileTooBig, .IO => return error.InputOutput, .INTEGRITY => return error.CorruptedData, - .ISDIR => return error.IsDir, .NOSPC => return error.NoSpaceLeft, + .ISDIR => |err| errnoBug(err), .BADF => |err| errnoBug(err), else => |err| posix.unexpectedErrno(err), }); @@ -7908,11 +7929,11 @@ fn fileWriteFilePositional( .FBIG => return error.FileTooBig, .IO => return error.InputOutput, .INTEGRITY => return error.CorruptedData, - .ISDIR => return error.IsDir, .NOSPC => return error.NoSpaceLeft, .OVERFLOW => return error.Unseekable, .NXIO => return error.Unseekable, .SPIPE => return error.Unseekable, + .ISDIR => |err| errnoBug(err), .BADF => |err| errnoBug(err), else => |err| posix.unexpectedErrno(err), }); diff --git a/lib/std/c.zig b/lib/std/c.zig index 703dda810e81ffc9baaef257c24c3974de7c2a86..25e52bac0c09e09dbfdd8069a294933742a6b420 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -163,6 +163,7 @@ pub const nlink_t = switch (native_os) { .freebsd, .serenity => u64, .openbsd, .netbsd, .illumos => u32, .haiku => i32, + .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => u16, else => u0, }; diff --git a/lib/std/process.zig b/lib/std/process.zig index 07d2b7117fc7f6d075fed1230e0d16b863a52913..cf751f7a282a763561c3369700bb6a48d877e587 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -2287,7 +2287,10 @@ pub fn exit(status: u8) noreturn { } else switch (native_os) { .windows => windows.ntdll.RtlExitUserProcess(status), .wasi => std.os.wasi.proc_exit(status), - .linux => if (!builtin.single_threaded) std.os.linux.exit_group(status), + .linux => { + if (!builtin.single_threaded) std.os.linux.exit_group(status); + posix.system.exit(status); + }, .uefi => { const uefi = std.os.uefi; // exit() is only available if exitBootServices() has not been called yet. -- 2.54.0