Merge pull request #13699 from mikdusan/bsd

give BSDs some attention
This commit is contained in:
Andrew Kelley 2023-01-03 00:57:25 -05:00
parent 5572a83123
commit be6a81d3a7
15 changed files with 159 additions and 61 deletions

View File

@ -593,7 +593,8 @@ fn addCmakeCfgOptionsToExe(
// System -lc++ must be used because in this code path we are attempting to link // System -lc++ must be used because in this code path we are attempting to link
// against system-provided LLVM, Clang, LLD. // against system-provided LLVM, Clang, LLD.
if (exe.target.getOsTag() == .linux) { switch (exe.target.getOsTag()) {
.linux => {
// First we try to link against gcc libstdc++. If that doesn't work, we fall // First we try to link against gcc libstdc++. If that doesn't work, we fall
// back to -lc++ and cross our fingers. // back to -lc++ and cross our fingers.
addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), "", need_cpp_includes) catch |err| switch (err) { addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), "", need_cpp_includes) catch |err| switch (err) {
@ -603,14 +604,27 @@ fn addCmakeCfgOptionsToExe(
else => |e| return e, else => |e| return e,
}; };
exe.linkSystemLibrary("unwind"); exe.linkSystemLibrary("unwind");
} else if (exe.target.isFreeBSD()) { },
.ios, .macos, .watchos, .tvos => {
exe.linkSystemLibrary("c++");
},
.freebsd => {
try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes); try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes);
exe.linkSystemLibrary("pthread"); try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
} else if (exe.target.getOsTag() == .openbsd) { },
.openbsd => {
try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes); try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes);
try addCxxKnownPath(b, cfg, exe, b.fmt("libc++abi.{s}", .{lib_suffix}), null, need_cpp_includes); try addCxxKnownPath(b, cfg, exe, b.fmt("libc++abi.{s}", .{lib_suffix}), null, need_cpp_includes);
} else if (exe.target.isDarwin()) { },
exe.linkSystemLibrary("c++"); .netbsd => {
try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes);
try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
},
.dragonfly => {
try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes);
try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
},
else => {},
} }
} }

View File

@ -148,7 +148,7 @@
# endif # endif
// Feature macros for disabling pre ABI v1 features. All of these options // Feature macros for disabling pre ABI v1 features. All of these options
// are deprecated. // are deprecated.
# if defined(__FreeBSD__) # if defined(__FreeBSD__) || defined(__DragonFly__)
# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR # define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
# endif # endif
# endif # endif
@ -726,11 +726,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# endif // _LIBCPP_CXX03_LANG # endif // _LIBCPP_CXX03_LANG
# if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__sun__) || \ # if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__sun__) || \
defined(__NetBSD__) defined(__NetBSD__) || defined(__DragonFly__)
# define _LIBCPP_LOCALE__L_EXTENSIONS 1 # define _LIBCPP_LOCALE__L_EXTENSIONS 1
# endif # endif
# ifdef __FreeBSD__ # if defined(__FreeBSD__) || defined(__DragonFly__)
# define _DECLARE_C99_LDBL_MATH 1 # define _DECLARE_C99_LDBL_MATH 1
# endif # endif
@ -750,11 +750,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION # define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
# endif # endif
# if defined(__APPLE__) || defined(__FreeBSD__) # if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
# define _LIBCPP_HAS_DEFAULTRUNELOCALE # define _LIBCPP_HAS_DEFAULTRUNELOCALE
# endif # endif
# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__) # if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__) || defined(__DragonFly__)
# define _LIBCPP_WCTYPE_IS_MASK # define _LIBCPP_WCTYPE_IS_MASK
# endif # endif
@ -901,6 +901,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# if defined(__FreeBSD__) || \ # if defined(__FreeBSD__) || \
defined(__wasi__) || \ defined(__wasi__) || \
defined(__DragonFly__) || \
defined(__NetBSD__) || \ defined(__NetBSD__) || \
defined(__OpenBSD__) || \ defined(__OpenBSD__) || \
defined(__NuttX__) || \ defined(__NuttX__) || \

View File

@ -33,7 +33,7 @@
# include <__support/newlib/xlocale.h> # include <__support/newlib/xlocale.h>
#elif defined(__OpenBSD__) #elif defined(__OpenBSD__)
# include <__support/openbsd/xlocale.h> # include <__support/openbsd/xlocale.h>
#elif (defined(__APPLE__) || defined(__FreeBSD__)) #elif (defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__))
# include <xlocale.h> # include <xlocale.h>
#elif defined(__Fuchsia__) #elif defined(__Fuchsia__)
# include <__support/fuchsia/xlocale.h> # include <__support/fuchsia/xlocale.h>
@ -453,10 +453,10 @@ public:
static const mask __regex_word = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used static const mask __regex_word = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used
# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__DragonFly__)
# ifdef __APPLE__ # ifdef __APPLE__
typedef __uint32_t mask; typedef __uint32_t mask;
# elif defined(__FreeBSD__) # elif defined(__FreeBSD__) || defined(__DragonFly__)
typedef unsigned long mask; typedef unsigned long mask;
# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__) # elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
typedef unsigned short mask; typedef unsigned short mask;

View File

@ -239,7 +239,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
#if defined(__APPLE__) || defined(__FreeBSD__) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
# define _LIBCPP_GET_C_LOCALE 0 # define _LIBCPP_GET_C_LOCALE 0
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE # define _LIBCPP_GET_C_LOCALE LC_C_LOCALE

View File

@ -1190,7 +1190,7 @@ ctype<char>::classic_table() noexcept
const ctype<char>::mask* const ctype<char>::mask*
ctype<char>::classic_table() noexcept ctype<char>::classic_table() noexcept
{ {
#if defined(__APPLE__) || defined(__FreeBSD__) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
return _DefaultRuneLocale.__runetype; return _DefaultRuneLocale.__runetype;
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
return _C_ctype_tab_ + 1; return _C_ctype_tab_ + 1;

View File

@ -12,6 +12,7 @@ pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) 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 getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
pub const dl_iterate_phdr_callback = std.meta.FnPtr(fn (info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.C) c_int); pub const dl_iterate_phdr_callback = std.meta.FnPtr(fn (info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.C) c_int);
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*anyopaque) c_int; pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*anyopaque) c_int;
@ -419,6 +420,7 @@ pub const F = struct {
pub const DUP2FD = 10; pub const DUP2FD = 10;
pub const DUPFD_CLOEXEC = 17; pub const DUPFD_CLOEXEC = 17;
pub const DUP2FD_CLOEXEC = 18; pub const DUP2FD_CLOEXEC = 18;
pub const GETPATH = 19;
}; };
pub const FD_CLOEXEC = 1; pub const FD_CLOEXEC = 1;

View File

@ -15,12 +15,15 @@ pub extern "c" fn pthread_getthreadid_np() c_int;
pub extern "c" fn pthread_set_name_np(thread: std.c.pthread_t, name: [*:0]const u8) void; pub extern "c" fn pthread_set_name_np(thread: std.c.pthread_t, name: [*:0]const u8) void;
pub extern "c" fn pthread_get_name_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) void; pub extern "c" fn pthread_get_name_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) void;
pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int; pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;
pub extern "c" fn malloc_usable_size(?*const anyopaque) usize; pub extern "c" fn malloc_usable_size(?*const anyopaque) usize;
pub extern "c" fn getpid() pid_t; pub extern "c" fn getpid() pid_t;
pub extern "c" fn kinfo_getfile(pid: pid_t, cntp: *c_int) ?[*]kinfo_file;
pub const sf_hdtr = extern struct { pub const sf_hdtr = extern struct {
headers: [*]const iovec_const, headers: [*]const iovec_const,
hdr_cnt: c_int, hdr_cnt: c_int,

View File

@ -537,6 +537,7 @@ pub const KERN = struct {
}; };
pub const PATH_MAX = 1024; pub const PATH_MAX = 1024;
pub const NAME_MAX = 255;
pub const IOV_MAX = KERN.IOV_MAX; pub const IOV_MAX = KERN.IOV_MAX;
pub const STDIN_FILENO = 0; pub const STDIN_FILENO = 0;
@ -689,13 +690,17 @@ pub const F = struct {
pub const SETFD = 2; pub const SETFD = 2;
pub const GETFL = 3; pub const GETFL = 3;
pub const SETFL = 4; pub const SETFL = 4;
pub const GETOWN = 5; pub const GETOWN = 5;
pub const SETOWN = 6; pub const SETOWN = 6;
pub const GETLK = 7; pub const GETLK = 7;
pub const SETLK = 8; pub const SETLK = 8;
pub const SETLKW = 9; pub const SETLKW = 9;
pub const CLOSEM = 10;
pub const MAXFD = 11;
pub const DUPFD_CLOEXEC = 12;
pub const GETNOSIGPIPE = 13;
pub const SETNOSIGPIPE = 14;
pub const GETPATH = 15;
pub const RDLCK = 1; pub const RDLCK = 1;
pub const WRLCK = 3; pub const WRLCK = 3;

View File

@ -417,6 +417,7 @@ pub const AI = struct {
}; };
pub const PATH_MAX = 1024; pub const PATH_MAX = 1024;
pub const NAME_MAX = 255;
pub const IOV_MAX = 1024; pub const IOV_MAX = 1024;
pub const STDIN_FILENO = 0; pub const STDIN_FILENO = 0;

View File

@ -34,7 +34,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
/// fit into a UTF-8 encoded array of this length. /// fit into a UTF-8 encoded array of this length.
/// The byte count includes room for a null sentinel byte. /// The byte count includes room for a null sentinel byte.
pub const MAX_PATH_BYTES = switch (builtin.os.tag) { pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
.linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku, .solaris => os.PATH_MAX, .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris => os.PATH_MAX,
// Each UTF-16LE character may be expanded to 3 UTF-8 bytes. // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
// If it would require 4 UTF-8 bytes, then there would be a surrogate // If it would require 4 UTF-8 bytes, then there would be a surrogate
// pair in the UTF-16LE, and we (over)account 3 bytes for it that way. // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
@ -54,10 +54,10 @@ pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
/// (depending on the platform) this assumption may not hold for every configuration. /// (depending on the platform) this assumption may not hold for every configuration.
/// The byte count does not include a null sentinel byte. /// The byte count does not include a null sentinel byte.
pub const MAX_NAME_BYTES = switch (builtin.os.tag) { pub const MAX_NAME_BYTES = switch (builtin.os.tag) {
.linux, .macos, .ios, .freebsd, .dragonfly => os.NAME_MAX, .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly => os.NAME_MAX,
// Haiku's NAME_MAX includes the null terminator, so subtract one. // Haiku's NAME_MAX includes the null terminator, so subtract one.
.haiku => os.NAME_MAX - 1, .haiku => os.NAME_MAX - 1,
.netbsd, .openbsd, .solaris => os.MAXNAMLEN, .solaris => os.system.MAXNAMLEN,
// Each UTF-16LE character may be expanded to 3 UTF-8 bytes. // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
// If it would require 4 UTF-8 bytes, then there would be a surrogate // If it would require 4 UTF-8 bytes, then there would be a surrogate
// pair in the UTF-16LE, and we (over)account 3 bytes for it that way. // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.

View File

@ -451,8 +451,8 @@ test "file operations on directories" {
try testing.expectError(error.IsDir, tmp_dir.dir.createFile(test_dir_name, .{})); try testing.expectError(error.IsDir, tmp_dir.dir.createFile(test_dir_name, .{}));
try testing.expectError(error.IsDir, tmp_dir.dir.deleteFile(test_dir_name)); try testing.expectError(error.IsDir, tmp_dir.dir.deleteFile(test_dir_name));
switch (builtin.os.tag) { switch (builtin.os.tag) {
// NetBSD does not error when reading a directory. // no error when reading a directory.
.netbsd => {}, .dragonfly, .netbsd => {},
// Currently, WASI will return error.Unexpected (via ENOTCAPABLE) when attempting fd_read on a directory handle. // Currently, WASI will return error.Unexpected (via ENOTCAPABLE) when attempting fd_read on a directory handle.
// TODO: Re-enable on WASI once https://github.com/bytecodealliance/wasmtime/issues/1935 is resolved. // TODO: Re-enable on WASI once https://github.com/bytecodealliance/wasmtime/issues/1935 is resolved.
.wasi => {}, .wasi => {},

View File

@ -2818,6 +2818,8 @@ pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirErr
.NOSPC => return error.NoSpaceLeft, .NOSPC => return error.NoSpaceLeft,
.NOTDIR => return error.NotDir, .NOTDIR => return error.NotDir,
.ROFS => return error.ReadOnlyFileSystem, .ROFS => return error.ReadOnlyFileSystem,
// dragonfly: when dir_fd is unlinked from filesystem
.NOTCONN => return error.FileNotFound,
else => |err| return unexpectedErrno(err), else => |err| return unexpectedErrno(err),
} }
} }
@ -5258,6 +5260,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) { switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) {
.SUCCESS => {}, .SUCCESS => {},
.BADF => return error.FileNotFound, .BADF => return error.FileNotFound,
.NOSPC => return error.NameTooLong,
// TODO man pages for fcntl on macOS don't really tell you what // TODO man pages for fcntl on macOS don't really tell you what
// errno values to expect when command is F.GETPATH... // errno values to expect when command is F.GETPATH...
else => |err| return unexpectedErrno(err), else => |err| return unexpectedErrno(err),
@ -5290,9 +5293,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
return target; return target;
}, },
.freebsd => { .freebsd => {
comptime if (builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .lt) if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .gt) {
@compileError("querying for canonical path of a handle is unsupported on FreeBSD 12 and below");
var kfile: system.kinfo_file = undefined; var kfile: system.kinfo_file = undefined;
kfile.structsize = system.KINFO_FILE_SIZE; kfile.structsize = system.KINFO_FILE_SIZE;
switch (errno(system.fcntl(fd, system.F.KINFO, @ptrToInt(&kfile)))) { switch (errno(system.fcntl(fd, system.F.KINFO, @ptrToInt(&kfile)))) {
@ -5300,10 +5301,78 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
.BADF => return error.FileNotFound, .BADF => return error.FileNotFound,
else => |err| return unexpectedErrno(err), else => |err| return unexpectedErrno(err),
} }
const len = mem.indexOfScalar(u8, &kfile.path, 0) orelse MAX_PATH_BYTES; const len = mem.indexOfScalar(u8, &kfile.path, 0) orelse MAX_PATH_BYTES;
if (len == 0) return error.NameTooLong;
mem.copy(u8, out_buffer, kfile.path[0..len]); mem.copy(u8, out_buffer, kfile.path[0..len]);
return out_buffer[0..len]; return out_buffer[0..len];
} else {
// This fallback implementation reimplements libutil's `kinfo_getfile()`.
// The motivation is to avoid linking -lutil when building zig or general
// user executables.
var mib = [4]c_int{ CTL.KERN, KERN.PROC, KERN.PROC_FILEDESC, system.getpid() };
var len: usize = undefined;
sysctl(&mib, null, &len, null, 0) catch |err| switch (err) {
error.PermissionDenied => unreachable,
error.SystemResources => return error.SystemResources,
error.NameTooLong => unreachable,
error.UnknownName => unreachable,
else => return error.Unexpected,
};
len = len * 4 / 3;
const buf = std.heap.c_allocator.alloc(u8, len) catch return error.SystemResources;
defer std.heap.c_allocator.free(buf);
len = buf.len;
sysctl(&mib, &buf[0], &len, null, 0) catch |err| switch (err) {
error.PermissionDenied => unreachable,
error.SystemResources => return error.SystemResources,
error.NameTooLong => unreachable,
error.UnknownName => unreachable,
else => return error.Unexpected,
};
var i: usize = 0;
while (i < len) {
const kf: *align(1) system.kinfo_file = @ptrCast(*align(1) system.kinfo_file, &buf[i]);
if (kf.fd == fd) {
len = mem.indexOfScalar(u8, &kf.path, 0) orelse MAX_PATH_BYTES;
if (len == 0) return error.NameTooLong;
mem.copy(u8, out_buffer, kf.path[0..len]);
return out_buffer[0..len];
}
i += @intCast(usize, kf.structsize);
}
return error.InvalidHandle;
}
},
.dragonfly => {
if (comptime builtin.os.version_range.semver.max.order(.{ .major = 6, .minor = 0 }) == .lt) {
@compileError("querying for canonical path of a handle is unsupported on this host");
}
@memset(out_buffer, 0, MAX_PATH_BYTES);
switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) {
.SUCCESS => {},
.BADF => return error.FileNotFound,
.RANGE => return error.NameTooLong,
else => |err| return unexpectedErrno(err),
}
const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES;
return out_buffer[0..len];
},
.netbsd => {
if (comptime builtin.os.version_range.semver.max.order(.{ .major = 10, .minor = 0 }) == .lt) {
@compileError("querying for canonical path of a handle is unsupported on this host");
}
@memset(out_buffer, 0, MAX_PATH_BYTES);
switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) {
.SUCCESS => {},
.ACCES => return error.AccessDenied,
.BADF => return error.FileNotFound,
.NOENT => return error.FileNotFound,
.NOMEM => return error.SystemResources,
.RANGE => return error.NameTooLong,
else => |err| return unexpectedErrno(err),
}
const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES;
return out_buffer[0..len];
}, },
else => @compileError("querying for canonical path of a handle is unsupported on this host"), else => @compileError("querying for canonical path of a handle is unsupported on this host"),
} }
@ -6675,6 +6744,8 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
} }
}, },
.freebsd => { .freebsd => {
if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .lt)
@compileError("memfd_create is unavailable on FreeBSD < 13.0");
const rc = system.memfd_create(name, flags); const rc = system.memfd_create(name, flags);
switch (errno(rc)) { switch (errno(rc)) {
.SUCCESS => return rc, .SUCCESS => return rc,

View File

@ -523,7 +523,14 @@ test "argsAlloc" {
test "memfd_create" { test "memfd_create" {
// memfd_create is only supported by linux and freebsd. // memfd_create is only supported by linux and freebsd.
if (native_os != .linux and native_os != .freebsd) return error.SkipZigTest; switch (native_os) {
.linux => {},
.freebsd => {
if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .lt)
return error.SkipZigTest;
},
else => return error.SkipZigTest,
}
const fd = std.os.memfd_create("test", 0) catch |err| switch (err) { const fd = std.os.memfd_create("test", 0) catch |err| switch (err) {
// Related: https://github.com/ziglang/zig/issues/4019 // Related: https://github.com/ziglang/zig/issues/4019

View File

@ -271,7 +271,7 @@ pub const Target = struct {
.freebsd => return .{ .freebsd => return .{
.semver = Version.Range{ .semver = Version.Range{
.min = .{ .major = 12, .minor = 0 }, .min = .{ .major = 12, .minor = 0 },
.max = .{ .major = 13, .minor = 0 }, .max = .{ .major = 13, .minor = 1 },
}, },
}, },
.macos => return switch (arch) { .macos => return switch (arch) {
@ -310,19 +310,19 @@ pub const Target = struct {
.netbsd => return .{ .netbsd => return .{
.semver = .{ .semver = .{
.min = .{ .major = 8, .minor = 0 }, .min = .{ .major = 8, .minor = 0 },
.max = .{ .major = 9, .minor = 1 }, .max = .{ .major = 10, .minor = 0 },
}, },
}, },
.openbsd => return .{ .openbsd => return .{
.semver = .{ .semver = .{
.min = .{ .major = 6, .minor = 8 }, .min = .{ .major = 6, .minor = 8 },
.max = .{ .major = 6, .minor = 9 }, .max = .{ .major = 7, .minor = 2 },
}, },
}, },
.dragonfly => return .{ .dragonfly => return .{
.semver = .{ .semver = .{
.min = .{ .major = 5, .minor = 8 }, .min = .{ .major = 5, .minor = 8 },
.max = .{ .major = 6, .minor = 0 }, .max = .{ .major = 6, .minor = 4 },
}, },
}, },
.solaris => return .{ .solaris => return .{

View File

@ -3074,27 +3074,22 @@ const CsuObjects = struct {
var result: CsuObjects = .{}; var result: CsuObjects = .{};
// TODO: https://github.com/ziglang/zig/issues/4629 // Flatten crt cases.
// - use inline enum type const mode: enum {
// - reduce to enum-literals for values
const Mode = enum {
dynamic_lib, dynamic_lib,
dynamic_exe, dynamic_exe,
dynamic_pie, dynamic_pie,
static_exe, static_exe,
static_pie, static_pie,
}; } = switch (link_options.output_mode) {
// Flatten crt case types.
const mode: Mode = switch (link_options.output_mode) {
.Obj => return CsuObjects{}, .Obj => return CsuObjects{},
.Lib => switch (link_options.link_mode) { .Lib => switch (link_options.link_mode) {
.Dynamic => Mode.dynamic_lib, .Dynamic => .dynamic_lib,
.Static => return CsuObjects{}, .Static => return CsuObjects{},
}, },
.Exe => switch (link_options.link_mode) { .Exe => switch (link_options.link_mode) {
.Dynamic => if (link_options.pie) Mode.dynamic_pie else Mode.dynamic_exe, .Dynamic => if (link_options.pie) .dynamic_pie else .dynamic_exe,
.Static => if (link_options.pie) Mode.static_pie else Mode.static_exe, .Static => if (link_options.pie) .static_pie else .static_exe,
}, },
}; };
@ -3124,7 +3119,6 @@ const CsuObjects = struct {
// hosted-glibc provides crtbegin/end objects in platform/compiler-specific dirs // hosted-glibc provides crtbegin/end objects in platform/compiler-specific dirs
// and they are not known at comptime. For now null-out crtbegin/end objects; // and they are not known at comptime. For now null-out crtbegin/end objects;
// there is no feature loss, zig has never linked those objects in before. // there is no feature loss, zig has never linked those objects in before.
// TODO: probe for paths, ie. `cc -print-file-name`
result.crtbegin = null; result.crtbegin = null;
result.crtend = null; result.crtend = null;
} else { } else {