From 64ddba955a1f98ab77cfb39844a09f472ebc4609 Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Thu, 15 Jun 2023 14:48:19 -0400 Subject: [PATCH 1/3] freebsd: fix std.c.getdents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix getdents return type usize → isize - usize ultimately forced errors to .SUCCESS in std.c.getError New behavior in freebsd 13.2 is to return ENOENT if the directory being iterated is deleted during iteration. We now detect this and treat it consistent with iteration ending. --- lib/std/c/freebsd.zig | 2 +- lib/std/fs.zig | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig index b3e6c6769a..b351128b03 100644 --- a/lib/std/c/freebsd.zig +++ b/lib/std/c/freebsd.zig @@ -75,7 +75,7 @@ pub const _errno = __error; pub extern "c" var malloc_options: [*:0]const u8; -pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; +pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) isize; pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize; pub extern "c" fn getentropy(buf_ptr: [*]u8, buf_len: usize) c_int; diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 38b94873e6..bb0890be4b 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -478,6 +478,9 @@ pub const IterableDir = struct { .FAULT => unreachable, .NOTDIR => unreachable, .INVAL => unreachable, + // Introduced in freebsd 13.2: directory unlinked but still open. + // To be consistent, iteration ends if the directory being iterated is deleted during iteration. + .NOENT => return null, else => |err| return os.unexpectedErrno(err), } if (rc == 0) return null; From 40fc71bf710ae3704c85c718636a190a5106c0cf Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Thu, 15 Jun 2023 14:48:20 -0400 Subject: [PATCH 2/3] openbsd: fix std.c.getdents and debitrot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix getdents return type usize → c_int - special-case process.zig to use sysctl instead of sysctlbyname - use struct/field pattern for sysctl HW_* constants --- lib/std/Thread.zig | 2 +- lib/std/c/openbsd.zig | 55 +++++++++++++++++++++++-------------------- lib/std/os.zig | 4 ++++ lib/std/process.zig | 19 ++++++++++++++- 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index ed6a9383e3..bb2d849c26 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -624,7 +624,7 @@ const PosixThreadImpl = struct { .openbsd => { var count: c_int = undefined; var count_size: usize = @sizeOf(c_int); - const mib = [_]c_int{ os.CTL.HW, os.system.HW_NCPUONLINE }; + const mib = [_]c_int{ os.CTL.HW, os.system.HW.NCPUONLINE }; os.sysctl(&mib, &count, &count_size, null, 0) catch |err| switch (err) { error.NameTooLong, error.UnknownName => unreachable, else => |e| return e, diff --git a/lib/std/c/openbsd.zig b/lib/std/c/openbsd.zig index dc5f8a14c9..93681b77e1 100644 --- a/lib/std/c/openbsd.zig +++ b/lib/std/c/openbsd.zig @@ -16,7 +16,7 @@ pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void; pub extern "c" fn getthrid() pid_t; pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; -pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; +pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) c_int; pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; pub const pthread_mutex_t = extern struct { @@ -1606,31 +1606,34 @@ pub const KERN = struct { pub const PROC_NENV = 4; }; -pub const HW_MACHINE = 1; -pub const HW_MODEL = 2; -pub const HW_NCPU = 3; -pub const HW_BYTEORDER = 4; -pub const HW_PHYSMEM = 5; -pub const HW_USERMEM = 6; -pub const HW_PAGESIZE = 7; -pub const HW_DISKNAMES = 8; -pub const HW_DISKSTATS = 9; -pub const HW_DISKCOUNT = 10; -pub const HW_SENSORS = 11; -pub const HW_CPUSPEED = 12; -pub const HW_SETPERF = 13; -pub const HW_VENDOR = 14; -pub const HW_PRODUCT = 15; -pub const HW_VERSION = 16; -pub const HW_SERIALNO = 17; -pub const HW_UUID = 18; -pub const HW_PHYSMEM64 = 19; -pub const HW_USERMEM64 = 20; -pub const HW_NCPUFOUND = 21; -pub const HW_ALLOWPOWERDOWN = 22; -pub const HW_PERFPOLICY = 23; -pub const HW_SMT = 24; -pub const HW_NCPUONLINE = 25; +pub const HW = struct { + pub const MACHINE = 1; + pub const MODEL = 2; + pub const NCPU = 3; + pub const BYTEORDER = 4; + pub const PHYSMEM = 5; + pub const USERMEM = 6; + pub const PAGESIZE = 7; + pub const DISKNAMES = 8; + pub const DISKSTATS = 9; + pub const DISKCOUNT = 10; + pub const SENSORS = 11; + pub const CPUSPEED = 12; + pub const SETPERF = 13; + pub const VENDOR = 14; + pub const PRODUCT = 15; + pub const VERSION = 16; + pub const SERIALNO = 17; + pub const UUID = 18; + pub const PHYSMEM64 = 19; + pub const USERMEM64 = 20; + pub const NCPUFOUND = 21; + pub const ALLOWPOWERDOWN = 22; + pub const PERFPOLICY = 23; + pub const SMT = 24; + pub const NCPUONLINE = 25; + pub const POWER = 26; +}; /// TODO refines if necessary pub const PTHREAD_STACK_MIN = switch (builtin.cpu.arch) { diff --git a/lib/std/os.zig b/lib/std/os.zig index ee28c158db..72ac205144 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -87,6 +87,10 @@ pub const F = system.F; pub const FD_CLOEXEC = system.FD_CLOEXEC; pub const Flock = system.Flock; pub const HOST_NAME_MAX = system.HOST_NAME_MAX; +pub const HW = switch (builtin.os.tag) { + .openbsd => system.HW, + else => .{}, +}; pub const IFNAMESIZE = system.IFNAMESIZE; pub const IOV_MAX = system.IOV_MAX; pub const IPPROTO = system.IPPROTO; diff --git a/lib/std/process.zig b/lib/std/process.zig index 6ad0df868e..f27b7e835b 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -1163,7 +1163,7 @@ pub fn totalSystemMemory() TotalSystemMemoryError!usize { .linux => { return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory; }, - .freebsd, .netbsd, .openbsd, .dragonfly, .macos => { + .freebsd, .netbsd, .dragonfly, .macos => { var physmem: c_ulong = undefined; var len: usize = @sizeOf(c_ulong); const name = switch (builtin.os.tag) { @@ -1177,6 +1177,23 @@ pub fn totalSystemMemory() TotalSystemMemoryError!usize { }; return @intCast(usize, physmem); }, + .openbsd => { + const mib: [2]c_int = [_]c_int{ + std.os.CTL.HW, + std.os.HW.PHYSMEM64, + }; + var physmem: i64 = undefined; + var len: usize = @sizeOf(@TypeOf(physmem)); + std.os.sysctl(&mib, &physmem, &len, null, 0) catch |err| switch (err) { + error.NameTooLong => unreachable, // constant, known good value + error.PermissionDenied => unreachable, // only when setting values, + error.SystemResources => unreachable, // memory already on the stack + error.UnknownName => unreachable, // constant, known good value + else => return error.UnknownTotalSystemMemory, + }; + assert(physmem >= 0); + return @bitCast(usize, physmem); + }, .windows => { var sbi: std.os.windows.SYSTEM_BASIC_INFORMATION = undefined; const rc = std.os.windows.ntdll.NtQuerySystemInformation( From 4054d001445098cdb72a02243e13180f1fba6d79 Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Thu, 15 Jun 2023 14:48:20 -0400 Subject: [PATCH 3/3] dragonfly: fix std.c.getdents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix getdents return type usize → c_int --- lib/std/c/dragonfly.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/c/dragonfly.zig b/lib/std/c/dragonfly.zig index 64a79710a4..824fc2757e 100644 --- a/lib/std/c/dragonfly.zig +++ b/lib/std/c/dragonfly.zig @@ -9,7 +9,7 @@ pub fn _errno() *c_int { return &errno; } -pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; +pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) c_int; pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize; pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;