authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-03 00:57:25-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-09 15:14:21-07:00
logbe6a81d3a70818ed143d004727d352f552384af5
tree770e67c943875aa11f6ee8b08d587735c7c70889
parent5572a8312314f138a84798ab71382983f00c2fbe

Merge pull request #13699 from mikdusan/bsd

give BSDs some attention

15 files changed, 159 insertions(+), 61 deletions(-)

build.zig+32-18
...@@ -593,24 +593,38 @@ fn addCmakeCfgOptionsToExe(...@@ -593,24 +593,38 @@ fn addCmakeCfgOptionsToExe(
593593
594 // System -lc++ must be used because in this code path we are attempting to link594 // System -lc++ must be used because in this code path we are attempting to link
595 // against system-provided LLVM, Clang, LLD.595 // against system-provided LLVM, Clang, LLD.
596 if (exe.target.getOsTag() == .linux) {596 switch (exe.target.getOsTag()) {
597 // First we try to link against gcc libstdc++. If that doesn't work, we fall597 .linux => {
598 // back to -lc++ and cross our fingers.598 // First we try to link against gcc libstdc++. If that doesn't work, we fall
599 addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), "", need_cpp_includes) catch |err| switch (err) {599 // back to -lc++ and cross our fingers.
600 error.RequiredLibraryNotFound => {600 addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), "", need_cpp_includes) catch |err| switch (err) {
601 exe.linkSystemLibrary("c++");601 error.RequiredLibraryNotFound => {
602 },602 exe.linkSystemLibrary("c++");
603 else => |e| return e,603 },
604 };604 else => |e| return e,
605 exe.linkSystemLibrary("unwind");605 };
606 } else if (exe.target.isFreeBSD()) {606 exe.linkSystemLibrary("unwind");
607 try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes);607 },
608 exe.linkSystemLibrary("pthread");608 .ios, .macos, .watchos, .tvos => {
609 } else if (exe.target.getOsTag() == .openbsd) {609 exe.linkSystemLibrary("c++");
610 try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes);610 },
611 try addCxxKnownPath(b, cfg, exe, b.fmt("libc++abi.{s}", .{lib_suffix}), null, need_cpp_includes);611 .freebsd => {
612 } else if (exe.target.isDarwin()) {612 try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes);
613 exe.linkSystemLibrary("c++");613 try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
614 },
615 .openbsd => {
616 try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes);
617 try addCxxKnownPath(b, cfg, exe, b.fmt("libc++abi.{s}", .{lib_suffix}), null, need_cpp_includes);
618 },
619 .netbsd => {
620 try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes);
621 try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
622 },
623 .dragonfly => {
624 try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes);
625 try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
626 },
627 else => {},
614 }628 }
615 }629 }
616630
lib/libcxx/include/__config+6-5
...@@ -148,7 +148,7 @@...@@ -148,7 +148,7 @@
148# endif148# endif
149// Feature macros for disabling pre ABI v1 features. All of these options149// Feature macros for disabling pre ABI v1 features. All of these options
150// are deprecated.150// are deprecated.
151# if defined(__FreeBSD__)151# if defined(__FreeBSD__) || defined(__DragonFly__)
152# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR152# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
153# endif153# endif
154# endif154# endif
...@@ -726,11 +726,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD...@@ -726,11 +726,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
726# endif // _LIBCPP_CXX03_LANG726# endif // _LIBCPP_CXX03_LANG
727727
728# if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__sun__) || \728# if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__sun__) || \
729 defined(__NetBSD__)729 defined(__NetBSD__) || defined(__DragonFly__)
730# define _LIBCPP_LOCALE__L_EXTENSIONS 1730# define _LIBCPP_LOCALE__L_EXTENSIONS 1
731# endif731# endif
732732
733# ifdef __FreeBSD__733# if defined(__FreeBSD__) || defined(__DragonFly__)
734# define _DECLARE_C99_LDBL_MATH 1734# define _DECLARE_C99_LDBL_MATH 1
735# endif735# endif
736736
...@@ -750,11 +750,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD...@@ -750,11 +750,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
750# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION750# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
751# endif751# endif
752752
753# if defined(__APPLE__) || defined(__FreeBSD__)753# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
754# define _LIBCPP_HAS_DEFAULTRUNELOCALE754# define _LIBCPP_HAS_DEFAULTRUNELOCALE
755# endif755# endif
756756
757# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)757# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__) || defined(__DragonFly__)
758# define _LIBCPP_WCTYPE_IS_MASK758# define _LIBCPP_WCTYPE_IS_MASK
759# endif759# endif
760760
...@@ -901,6 +901,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD...@@ -901,6 +901,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
901901
902# if defined(__FreeBSD__) || \902# if defined(__FreeBSD__) || \
903 defined(__wasi__) || \903 defined(__wasi__) || \
904 defined(__DragonFly__) || \
904 defined(__NetBSD__) || \905 defined(__NetBSD__) || \
905 defined(__OpenBSD__) || \906 defined(__OpenBSD__) || \
906 defined(__NuttX__) || \907 defined(__NuttX__) || \
lib/libcxx/include/__locale+3-3
...@@ -33,7 +33,7 @@...@@ -33,7 +33,7 @@
33# include <__support/newlib/xlocale.h>33# include <__support/newlib/xlocale.h>
34#elif defined(__OpenBSD__)34#elif defined(__OpenBSD__)
35# include <__support/openbsd/xlocale.h>35# include <__support/openbsd/xlocale.h>
36#elif (defined(__APPLE__) || defined(__FreeBSD__))36#elif (defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__))
37# include <xlocale.h>37# include <xlocale.h>
38#elif defined(__Fuchsia__)38#elif defined(__Fuchsia__)
39# include <__support/fuchsia/xlocale.h>39# include <__support/fuchsia/xlocale.h>
...@@ -453,10 +453,10 @@ public:...@@ -453,10 +453,10 @@ public:
453 static const mask __regex_word = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used453 static const mask __regex_word = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used
454# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT454# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
455# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA455# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
456#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)456#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__DragonFly__)
457# ifdef __APPLE__457# ifdef __APPLE__
458 typedef __uint32_t mask;458 typedef __uint32_t mask;
459# elif defined(__FreeBSD__)459# elif defined(__FreeBSD__) || defined(__DragonFly__)
460 typedef unsigned long mask;460 typedef unsigned long mask;
461# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)461# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
462 typedef unsigned short mask;462 typedef unsigned short mask;
lib/libcxx/include/locale+1-1
...@@ -239,7 +239,7 @@ _LIBCPP_PUSH_MACROS...@@ -239,7 +239,7 @@ _LIBCPP_PUSH_MACROS
239239
240_LIBCPP_BEGIN_NAMESPACE_STD240_LIBCPP_BEGIN_NAMESPACE_STD
241241
242#if defined(__APPLE__) || defined(__FreeBSD__)242#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
243# define _LIBCPP_GET_C_LOCALE 0243# define _LIBCPP_GET_C_LOCALE 0
244#elif defined(__NetBSD__)244#elif defined(__NetBSD__)
245# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE245# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
lib/libcxx/src/locale.cpp+1-1
...@@ -1190,7 +1190,7 @@ ctype<char>::classic_table() noexcept...@@ -1190,7 +1190,7 @@ ctype<char>::classic_table() noexcept
1190const ctype<char>::mask*1190const ctype<char>::mask*
1191ctype<char>::classic_table() noexcept1191ctype<char>::classic_table() noexcept
1192{1192{
1193#if defined(__APPLE__) || defined(__FreeBSD__)1193#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
1194 return _DefaultRuneLocale.__runetype;1194 return _DefaultRuneLocale.__runetype;
1195#elif defined(__NetBSD__)1195#elif defined(__NetBSD__)
1196 return _C_ctype_tab_ + 1;1196 return _C_ctype_tab_ + 1;
lib/std/c/dragonfly.zig+2
...@@ -12,6 +12,7 @@ pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;...@@ -12,6 +12,7 @@ pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
12pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;12pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
13pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;13pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
14pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;14pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
15pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
1516
16pub const dl_iterate_phdr_callback = std.meta.FnPtr(fn (info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.C) c_int);17pub const dl_iterate_phdr_callback = std.meta.FnPtr(fn (info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.C) c_int);
17pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*anyopaque) c_int;18pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*anyopaque) c_int;
...@@ -419,6 +420,7 @@ pub const F = struct {...@@ -419,6 +420,7 @@ pub const F = struct {
419 pub const DUP2FD = 10;420 pub const DUP2FD = 10;
420 pub const DUPFD_CLOEXEC = 17;421 pub const DUPFD_CLOEXEC = 17;
421 pub const DUP2FD_CLOEXEC = 18;422 pub const DUP2FD_CLOEXEC = 18;
423 pub const GETPATH = 19;
422};424};
423425
424pub const FD_CLOEXEC = 1;426pub const FD_CLOEXEC = 1;
lib/std/c/freebsd.zig+3
...@@ -15,12 +15,15 @@ pub extern "c" fn pthread_getthreadid_np() c_int;...@@ -15,12 +15,15 @@ pub extern "c" fn pthread_getthreadid_np() c_int;
15pub extern "c" fn pthread_set_name_np(thread: std.c.pthread_t, name: [*:0]const u8) void;15pub extern "c" fn pthread_set_name_np(thread: std.c.pthread_t, name: [*:0]const u8) void;
16pub extern "c" fn pthread_get_name_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) void;16pub extern "c" fn pthread_get_name_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) void;
17pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;17pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
18pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
1819
19pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;20pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;
20pub extern "c" fn malloc_usable_size(?*const anyopaque) usize;21pub extern "c" fn malloc_usable_size(?*const anyopaque) usize;
2122
22pub extern "c" fn getpid() pid_t;23pub extern "c" fn getpid() pid_t;
2324
25pub extern "c" fn kinfo_getfile(pid: pid_t, cntp: *c_int) ?[*]kinfo_file;
26
24pub const sf_hdtr = extern struct {27pub const sf_hdtr = extern struct {
25 headers: [*]const iovec_const,28 headers: [*]const iovec_const,
26 hdr_cnt: c_int,29 hdr_cnt: c_int,
lib/std/c/netbsd.zig+7-2
...@@ -537,6 +537,7 @@ pub const KERN = struct {...@@ -537,6 +537,7 @@ pub const KERN = struct {
537};537};
538538
539pub const PATH_MAX = 1024;539pub const PATH_MAX = 1024;
540pub const NAME_MAX = 255;
540pub const IOV_MAX = KERN.IOV_MAX;541pub const IOV_MAX = KERN.IOV_MAX;
541542
542pub const STDIN_FILENO = 0;543pub const STDIN_FILENO = 0;
...@@ -689,13 +690,17 @@ pub const F = struct {...@@ -689,13 +690,17 @@ pub const F = struct {
689 pub const SETFD = 2;690 pub const SETFD = 2;
690 pub const GETFL = 3;691 pub const GETFL = 3;
691 pub const SETFL = 4;692 pub const SETFL = 4;
692
693 pub const GETOWN = 5;693 pub const GETOWN = 5;
694 pub const SETOWN = 6;694 pub const SETOWN = 6;
695
696 pub const GETLK = 7;695 pub const GETLK = 7;
697 pub const SETLK = 8;696 pub const SETLK = 8;
698 pub const SETLKW = 9;697 pub const SETLKW = 9;
698 pub const CLOSEM = 10;
699 pub const MAXFD = 11;
700 pub const DUPFD_CLOEXEC = 12;
701 pub const GETNOSIGPIPE = 13;
702 pub const SETNOSIGPIPE = 14;
703 pub const GETPATH = 15;
699704
700 pub const RDLCK = 1;705 pub const RDLCK = 1;
701 pub const WRLCK = 3;706 pub const WRLCK = 3;
lib/std/c/openbsd.zig+1
...@@ -417,6 +417,7 @@ pub const AI = struct {...@@ -417,6 +417,7 @@ pub const AI = struct {
417};417};
418418
419pub const PATH_MAX = 1024;419pub const PATH_MAX = 1024;
420pub const NAME_MAX = 255;
420pub const IOV_MAX = 1024;421pub const IOV_MAX = 1024;
421422
422pub const STDIN_FILENO = 0;423pub const STDIN_FILENO = 0;
lib/std/fs.zig+3-3
...@@ -34,7 +34,7 @@ pub const Watch = @import("fs/watch.zig").Watch;...@@ -34,7 +34,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
34/// fit into a UTF-8 encoded array of this length.34/// fit into a UTF-8 encoded array of this length.
35/// The byte count includes room for a null sentinel byte.35/// The byte count includes room for a null sentinel byte.
36pub const MAX_PATH_BYTES = switch (builtin.os.tag) {36pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
37 .linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku, .solaris => os.PATH_MAX,37 .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris => os.PATH_MAX,
38 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.38 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
39 // If it would require 4 UTF-8 bytes, then there would be a surrogate39 // If it would require 4 UTF-8 bytes, then there would be a surrogate
40 // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.40 // 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) {...@@ -54,10 +54,10 @@ pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
54/// (depending on the platform) this assumption may not hold for every configuration.54/// (depending on the platform) this assumption may not hold for every configuration.
55/// The byte count does not include a null sentinel byte.55/// The byte count does not include a null sentinel byte.
56pub const MAX_NAME_BYTES = switch (builtin.os.tag) {56pub const MAX_NAME_BYTES = switch (builtin.os.tag) {
57 .linux, .macos, .ios, .freebsd, .dragonfly => os.NAME_MAX,57 .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly => os.NAME_MAX,
58 // Haiku's NAME_MAX includes the null terminator, so subtract one.58 // Haiku's NAME_MAX includes the null terminator, so subtract one.
59 .haiku => os.NAME_MAX - 1,59 .haiku => os.NAME_MAX - 1,
60 .netbsd, .openbsd, .solaris => os.MAXNAMLEN,60 .solaris => os.system.MAXNAMLEN,
61 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.61 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
62 // If it would require 4 UTF-8 bytes, then there would be a surrogate62 // If it would require 4 UTF-8 bytes, then there would be a surrogate
63 // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.63 // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
lib/std/fs/test.zig+2-2
...@@ -451,8 +451,8 @@ test "file operations on directories" {...@@ -451,8 +451,8 @@ test "file operations on directories" {
451 try testing.expectError(error.IsDir, tmp_dir.dir.createFile(test_dir_name, .{}));451 try testing.expectError(error.IsDir, tmp_dir.dir.createFile(test_dir_name, .{}));
452 try testing.expectError(error.IsDir, tmp_dir.dir.deleteFile(test_dir_name));452 try testing.expectError(error.IsDir, tmp_dir.dir.deleteFile(test_dir_name));
453 switch (builtin.os.tag) {453 switch (builtin.os.tag) {
454 // NetBSD does not error when reading a directory.454 // no error when reading a directory.
455 .netbsd => {},455 .dragonfly, .netbsd => {},
456 // Currently, WASI will return error.Unexpected (via ENOTCAPABLE) when attempting fd_read on a directory handle.456 // Currently, WASI will return error.Unexpected (via ENOTCAPABLE) when attempting fd_read on a directory handle.
457 // TODO: Re-enable on WASI once https://github.com/bytecodealliance/wasmtime/issues/1935 is resolved.457 // TODO: Re-enable on WASI once https://github.com/bytecodealliance/wasmtime/issues/1935 is resolved.
458 .wasi => {},458 .wasi => {},
lib/std/os.zig+80-9
...@@ -2818,6 +2818,8 @@ pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirErr...@@ -2818,6 +2818,8 @@ pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirErr
2818 .NOSPC => return error.NoSpaceLeft,2818 .NOSPC => return error.NoSpaceLeft,
2819 .NOTDIR => return error.NotDir,2819 .NOTDIR => return error.NotDir,
2820 .ROFS => return error.ReadOnlyFileSystem,2820 .ROFS => return error.ReadOnlyFileSystem,
2821 // dragonfly: when dir_fd is unlinked from filesystem
2822 .NOTCONN => return error.FileNotFound,
2821 else => |err| return unexpectedErrno(err),2823 else => |err| return unexpectedErrno(err),
2822 }2824 }
2823}2825}
...@@ -5258,6 +5260,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {...@@ -5258,6 +5260,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
5258 switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) {5260 switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) {
5259 .SUCCESS => {},5261 .SUCCESS => {},
5260 .BADF => return error.FileNotFound,5262 .BADF => return error.FileNotFound,
5263 .NOSPC => return error.NameTooLong,
5261 // TODO man pages for fcntl on macOS don't really tell you what5264 // TODO man pages for fcntl on macOS don't really tell you what
5262 // errno values to expect when command is F.GETPATH...5265 // errno values to expect when command is F.GETPATH...
5263 else => |err| return unexpectedErrno(err),5266 else => |err| return unexpectedErrno(err),
...@@ -5290,19 +5293,85 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {...@@ -5290,19 +5293,85 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
5290 return target;5293 return target;
5291 },5294 },
5292 .freebsd => {5295 .freebsd => {
5293 comptime if (builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .lt)5296 if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .gt) {
5294 @compileError("querying for canonical path of a handle is unsupported on FreeBSD 12 and below");5297 var kfile: system.kinfo_file = undefined;
52955298 kfile.structsize = system.KINFO_FILE_SIZE;
5296 var kfile: system.kinfo_file = undefined;5299 switch (errno(system.fcntl(fd, system.F.KINFO, @ptrToInt(&kfile)))) {
5297 kfile.structsize = system.KINFO_FILE_SIZE;5300 .SUCCESS => {},
5298 switch (errno(system.fcntl(fd, system.F.KINFO, @ptrToInt(&kfile)))) {5301 .BADF => return error.FileNotFound,
5302 else => |err| return unexpectedErrno(err),
5303 }
5304 const len = mem.indexOfScalar(u8, &kfile.path, 0) orelse MAX_PATH_BYTES;
5305 if (len == 0) return error.NameTooLong;
5306 mem.copy(u8, out_buffer, kfile.path[0..len]);
5307 return out_buffer[0..len];
5308 } else {
5309 // This fallback implementation reimplements libutil's `kinfo_getfile()`.
5310 // The motivation is to avoid linking -lutil when building zig or general
5311 // user executables.
5312 var mib = [4]c_int{ CTL.KERN, KERN.PROC, KERN.PROC_FILEDESC, system.getpid() };
5313 var len: usize = undefined;
5314 sysctl(&mib, null, &len, null, 0) catch |err| switch (err) {
5315 error.PermissionDenied => unreachable,
5316 error.SystemResources => return error.SystemResources,
5317 error.NameTooLong => unreachable,
5318 error.UnknownName => unreachable,
5319 else => return error.Unexpected,
5320 };
5321 len = len * 4 / 3;
5322 const buf = std.heap.c_allocator.alloc(u8, len) catch return error.SystemResources;
5323 defer std.heap.c_allocator.free(buf);
5324 len = buf.len;
5325 sysctl(&mib, &buf[0], &len, null, 0) catch |err| switch (err) {
5326 error.PermissionDenied => unreachable,
5327 error.SystemResources => return error.SystemResources,
5328 error.NameTooLong => unreachable,
5329 error.UnknownName => unreachable,
5330 else => return error.Unexpected,
5331 };
5332 var i: usize = 0;
5333 while (i < len) {
5334 const kf: *align(1) system.kinfo_file = @ptrCast(*align(1) system.kinfo_file, &buf[i]);
5335 if (kf.fd == fd) {
5336 len = mem.indexOfScalar(u8, &kf.path, 0) orelse MAX_PATH_BYTES;
5337 if (len == 0) return error.NameTooLong;
5338 mem.copy(u8, out_buffer, kf.path[0..len]);
5339 return out_buffer[0..len];
5340 }
5341 i += @intCast(usize, kf.structsize);
5342 }
5343 return error.InvalidHandle;
5344 }
5345 },
5346 .dragonfly => {
5347 if (comptime builtin.os.version_range.semver.max.order(.{ .major = 6, .minor = 0 }) == .lt) {
5348 @compileError("querying for canonical path of a handle is unsupported on this host");
5349 }
5350 @memset(out_buffer, 0, MAX_PATH_BYTES);
5351 switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) {
5299 .SUCCESS => {},5352 .SUCCESS => {},
5300 .BADF => return error.FileNotFound,5353 .BADF => return error.FileNotFound,
5354 .RANGE => return error.NameTooLong,
5301 else => |err| return unexpectedErrno(err),5355 else => |err| return unexpectedErrno(err),
5302 }5356 }
53035357 const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES;
5304 const len = mem.indexOfScalar(u8, &kfile.path, 0) orelse MAX_PATH_BYTES;5358 return out_buffer[0..len];
5305 mem.copy(u8, out_buffer, kfile.path[0..len]);5359 },
5360 .netbsd => {
5361 if (comptime builtin.os.version_range.semver.max.order(.{ .major = 10, .minor = 0 }) == .lt) {
5362 @compileError("querying for canonical path of a handle is unsupported on this host");
5363 }
5364 @memset(out_buffer, 0, MAX_PATH_BYTES);
5365 switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) {
5366 .SUCCESS => {},
5367 .ACCES => return error.AccessDenied,
5368 .BADF => return error.FileNotFound,
5369 .NOENT => return error.FileNotFound,
5370 .NOMEM => return error.SystemResources,
5371 .RANGE => return error.NameTooLong,
5372 else => |err| return unexpectedErrno(err),
5373 }
5374 const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES;
5306 return out_buffer[0..len];5375 return out_buffer[0..len];
5307 },5376 },
5308 else => @compileError("querying for canonical path of a handle is unsupported on this host"),5377 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 {...@@ -6675,6 +6744,8 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
6675 }6744 }
6676 },6745 },
6677 .freebsd => {6746 .freebsd => {
6747 if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .lt)
6748 @compileError("memfd_create is unavailable on FreeBSD < 13.0");
6678 const rc = system.memfd_create(name, flags);6749 const rc = system.memfd_create(name, flags);
6679 switch (errno(rc)) {6750 switch (errno(rc)) {
6680 .SUCCESS => return rc,6751 .SUCCESS => return rc,
lib/std/os/test.zig+8-1
...@@ -523,7 +523,14 @@ test "argsAlloc" {...@@ -523,7 +523,14 @@ test "argsAlloc" {
523523
524test "memfd_create" {524test "memfd_create" {
525 // memfd_create is only supported by linux and freebsd.525 // memfd_create is only supported by linux and freebsd.
526 if (native_os != .linux and native_os != .freebsd) return error.SkipZigTest;526 switch (native_os) {
527 .linux => {},
528 .freebsd => {
529 if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .lt)
530 return error.SkipZigTest;
531 },
532 else => return error.SkipZigTest,
533 }
527534
528 const fd = std.os.memfd_create("test", 0) catch |err| switch (err) {535 const fd = std.os.memfd_create("test", 0) catch |err| switch (err) {
529 // Related: https://github.com/ziglang/zig/issues/4019536 // Related: https://github.com/ziglang/zig/issues/4019
lib/std/target.zig+4-4
...@@ -271,7 +271,7 @@ pub const Target = struct {...@@ -271,7 +271,7 @@ pub const Target = struct {
271 .freebsd => return .{271 .freebsd => return .{
272 .semver = Version.Range{272 .semver = Version.Range{
273 .min = .{ .major = 12, .minor = 0 },273 .min = .{ .major = 12, .minor = 0 },
274 .max = .{ .major = 13, .minor = 0 },274 .max = .{ .major = 13, .minor = 1 },
275 },275 },
276 },276 },
277 .macos => return switch (arch) {277 .macos => return switch (arch) {
...@@ -310,19 +310,19 @@ pub const Target = struct {...@@ -310,19 +310,19 @@ pub const Target = struct {
310 .netbsd => return .{310 .netbsd => return .{
311 .semver = .{311 .semver = .{
312 .min = .{ .major = 8, .minor = 0 },312 .min = .{ .major = 8, .minor = 0 },
313 .max = .{ .major = 9, .minor = 1 },313 .max = .{ .major = 10, .minor = 0 },
314 },314 },
315 },315 },
316 .openbsd => return .{316 .openbsd => return .{
317 .semver = .{317 .semver = .{
318 .min = .{ .major = 6, .minor = 8 },318 .min = .{ .major = 6, .minor = 8 },
319 .max = .{ .major = 6, .minor = 9 },319 .max = .{ .major = 7, .minor = 2 },
320 },320 },
321 },321 },
322 .dragonfly => return .{322 .dragonfly => return .{
323 .semver = .{323 .semver = .{
324 .min = .{ .major = 5, .minor = 8 },324 .min = .{ .major = 5, .minor = 8 },
325 .max = .{ .major = 6, .minor = 0 },325 .max = .{ .major = 6, .minor = 4 },
326 },326 },
327 },327 },
328 .solaris => return .{328 .solaris => return .{
src/link/Elf.zig+6-12
...@@ -3074,27 +3074,22 @@ const CsuObjects = struct {...@@ -3074,27 +3074,22 @@ const CsuObjects = struct {
30743074
3075 var result: CsuObjects = .{};3075 var result: CsuObjects = .{};
30763076
3077 // TODO: https://github.com/ziglang/zig/issues/46293077 // Flatten crt cases.
3078 // - use inline enum type3078 const mode: enum {
3079 // - reduce to enum-literals for values
3080 const Mode = enum {
3081 dynamic_lib,3079 dynamic_lib,
3082 dynamic_exe,3080 dynamic_exe,
3083 dynamic_pie,3081 dynamic_pie,
3084 static_exe,3082 static_exe,
3085 static_pie,3083 static_pie,
3086 };3084 } = switch (link_options.output_mode) {
3087
3088 // Flatten crt case types.
3089 const mode: Mode = switch (link_options.output_mode) {
3090 .Obj => return CsuObjects{},3085 .Obj => return CsuObjects{},
3091 .Lib => switch (link_options.link_mode) {3086 .Lib => switch (link_options.link_mode) {
3092 .Dynamic => Mode.dynamic_lib,3087 .Dynamic => .dynamic_lib,
3093 .Static => return CsuObjects{},3088 .Static => return CsuObjects{},
3094 },3089 },
3095 .Exe => switch (link_options.link_mode) {3090 .Exe => switch (link_options.link_mode) {
3096 .Dynamic => if (link_options.pie) Mode.dynamic_pie else Mode.dynamic_exe,3091 .Dynamic => if (link_options.pie) .dynamic_pie else .dynamic_exe,
3097 .Static => if (link_options.pie) Mode.static_pie else Mode.static_exe,3092 .Static => if (link_options.pie) .static_pie else .static_exe,
3098 },3093 },
3099 };3094 };
31003095
...@@ -3124,7 +3119,6 @@ const CsuObjects = struct {...@@ -3124,7 +3119,6 @@ const CsuObjects = struct {
3124 // hosted-glibc provides crtbegin/end objects in platform/compiler-specific dirs3119 // hosted-glibc provides crtbegin/end objects in platform/compiler-specific dirs
3125 // and they are not known at comptime. For now null-out crtbegin/end objects;3120 // and they are not known at comptime. For now null-out crtbegin/end objects;
3126 // there is no feature loss, zig has never linked those objects in before.3121 // there is no feature loss, zig has never linked those objects in before.
3127 // TODO: probe for paths, ie. `cc -print-file-name`
3128 result.crtbegin = null;3122 result.crtbegin = null;
3129 result.crtend = null;3123 result.crtend = null;
3130 } else {3124 } else {