Compare commits

...

1 Commits

Author SHA1 Message Date
Meghan Denny
af85c02f6d all: enough to get 'zig build check-freebsd' cross-compiling 2025-11-26 15:31:20 -08:00
33 changed files with 533 additions and 88 deletions

View File

@@ -358,6 +358,7 @@ pub fn build(b: *Build) !void {
.{ .os = .linux, .arch = .aarch64 },
.{ .os = .linux, .arch = .x86_64, .musl = true },
.{ .os = .linux, .arch = .aarch64, .musl = true },
.{ .os = .freebsd, .arch = .x86_64 },
}, &.{ .Debug, .ReleaseFast });
}
@@ -372,6 +373,7 @@ pub fn build(b: *Build) !void {
.{ .os = .linux, .arch = .aarch64 },
.{ .os = .linux, .arch = .x86_64, .musl = true },
.{ .os = .linux, .arch = .aarch64, .musl = true },
.{ .os = .freebsd, .arch = .x86_64 },
}, &.{.Debug});
}
@@ -416,6 +418,18 @@ pub fn build(b: *Build) !void {
.{ .os = .linux, .arch = .aarch64 },
}, &.{.Debug});
}
{
const step = b.step("check-freebsd", "Check for semantic analysis errors on Windows");
addMultiCheck(b, step, build_options, &.{
.{ .os = .freebsd, .arch = .x86_64 },
}, &.{ .Debug, .ReleaseFast });
}
{
const step = b.step("check-freebsd-debug", "Check for semantic analysis errors on Windows");
addMultiCheck(b, step, build_options, &.{
.{ .os = .freebsd, .arch = .x86_64 },
}, &.{.Debug});
}
// zig build translate-c-headers
{
@@ -428,6 +442,7 @@ pub fn build(b: *Build) !void {
.{ .os = .linux, .arch = .aarch64 },
.{ .os = .linux, .arch = .x86_64, .musl = true },
.{ .os = .linux, .arch = .aarch64, .musl = true },
.{ .os = .freebsd, .arch = .x86_64 },
}) |t| {
const resolved = t.resolveTarget(b);
step.dependOn(
@@ -523,6 +538,7 @@ fn getTranslateC(b: *Build, initial_target: std.Build.ResolvedTarget, optimize:
.{ "POSIX", translate_c.target.result.os.tag != .windows },
.{ "LINUX", translate_c.target.result.os.tag == .linux },
.{ "DARWIN", translate_c.target.result.os.tag.isDarwin() },
.{ "FREEBSD", translate_c.target.result.os.tag == .freebsd },
}) |entry| {
const str, const value = entry;
translate_c.defineCMacroRaw(b.fmt("{s}={d}", .{ str, @intFromBool(value) }));
@@ -609,7 +625,6 @@ fn configureObj(b: *Build, opts: *BunBuildOptions, obj: *Compile) void {
obj.no_link_obj = opts.os != .windows;
if (opts.enable_asan and !enableFastBuild(b)) {
if (@hasField(Build.Module, "sanitize_address")) {
if (opts.enable_fuzzilli) {
@@ -700,8 +715,12 @@ fn addInternalImports(b: *Build, mod: *Module, opts: *BunBuildOptions) void {
mod.addImport("translated-c-headers", b.createModule(.{ .root_source_file = translate_c }));
const zlib_internal_path = switch (os) {
.windows => "src/deps/zlib.win32.zig",
.linux, .mac => "src/deps/zlib.posix.zig",
.windows,
=> "src/deps/zlib.win32.zig",
.linux,
.mac,
.freebsd,
=> "src/deps/zlib.posix.zig",
else => null,
};
if (zlib_internal_path) |path| {
@@ -711,7 +730,7 @@ fn addInternalImports(b: *Build, mod: *Module, opts: *BunBuildOptions) void {
}
const async_path = switch (os) {
.linux, .mac => "src/async/posix_event_loop.zig",
.linux, .mac, .freebsd => "src/async/posix_event_loop.zig",
.windows => "src/async/windows_event_loop.zig",
else => "src/async/stub_event_loop.zig",
};

View File

@@ -1347,7 +1347,7 @@ pub const StandaloneModuleGraph = struct {
return error.FileNotFound;
}
},
.mac => {
.mac, .freebsd => {
// Use of MAX_PATH_BYTES here is valid as the resulting path is immediately
// opened with no modification.
const self_exe_path = try bun.selfExePath();

View File

@@ -142,8 +142,8 @@ pub const max_eviction_count = 8096;
// ideally, the constants above can be inlined
const Platform = switch (Environment.os) {
.linux => @import("./watcher/INotifyWatcher.zig"),
.mac => @import("./watcher/KEventWatcher.zig"),
.windows => WindowsWatcher,
.mac, .freebsd => @import("./watcher/KEventWatcher.zig"),
.windows => @import("./watcher/WindowsWatcher.zig"),
.wasm => @compileError("Unsupported platform"),
};
@@ -774,7 +774,6 @@ pub fn onMaybeWatchDirectory(watch: *Watcher, file_path: string, dir_fd: bun.Sto
const string = []const u8;
const WatcherTrace = @import("./watcher/WatcherTrace.zig");
const WindowsWatcher = @import("./watcher/WindowsWatcher.zig");
const options = @import("./options.zig");
const std = @import("std");
const PackageJSON = @import("./resolver/package_json.zig").PackageJSON;

View File

@@ -265,7 +265,7 @@ pub const GenerateHeader = struct {
fn run() void {
if (comptime Environment.isMac) {
platform_ = forMac();
} else if (comptime Environment.isPosix) {
} else if (comptime Environment.isLinux) {
platform_ = forLinux();
const release = bun.sliceTo(&linux_os_name.release, 0);
@@ -278,6 +278,8 @@ pub const GenerateHeader = struct {
.version = &[_]u8{},
.arch = platform_arch,
};
} else if (Environment.isFreeBsd) {
@panic("TODO");
}
}
}.run);

View File

@@ -920,6 +920,8 @@ pub const FilePoll = struct {
this.deactivate(loop);
return .initErr(bun.sys.Error.fromCode(errno, .kqueue));
}
} else if (Environment.isFreeBsd) {
@panic("TODO");
} else {
@compileError("unsupported platform");
}
@@ -1069,6 +1071,8 @@ pub const FilePoll = struct {
std.math.minInt(@TypeOf(rc))...-1 => return bun.sys.Maybe(void).errnoSys(@intFromEnum(errno), .kevent).?,
else => {},
}
} else if (Environment.isFreeBsd) {
@panic("TODO");
} else {
@compileError("unsupported platform");
}
@@ -1087,8 +1091,8 @@ pub const FilePoll = struct {
};
pub const Waker = switch (Environment.os) {
.mac => KEventWaker,
.linux => LinuxWaker,
.mac => DarwinWaker,
.linux, .freebsd => LinuxWaker,
.windows, .wasm => @compileError("unreachable"),
};
@@ -1121,7 +1125,7 @@ pub const LinuxWaker = struct {
}
};
pub const KEventWaker = struct {
pub const DarwinWaker = struct {
kq: std.posix.fd_t,
machport: bun.mach_port = undefined,
machport_buf: []u8 = &.{},

View File

@@ -1253,7 +1253,7 @@ pub fn spawnProcessPosix(
}
}
if (options.detached) {
if (options.detached and !(Environment.os == .freebsd)) {
flags |= bun.c.POSIX_SPAWN_SETSID;
}

View File

@@ -110,6 +110,7 @@ pub const BunSpawn = struct {
}
pub fn set(self: *Attr, flags: u16) !void {
if (Environment.os == .freebsd) return; // no POSIX_SPAWN_SETSID
self.detached = (flags & bun.c.POSIX_SPAWN_SETSID) != 0;
}
@@ -259,8 +260,17 @@ pub const PosixSpawn = struct {
}
};
pub const Actions = if (Environment.isLinux) BunSpawn.Actions else PosixSpawnActions;
pub const Attr = if (Environment.isLinux) BunSpawn.Attr else PosixSpawnAttr;
pub const Actions = switch (Environment.os) {
.linux, .freebsd => BunSpawn.Actions,
.mac => PosixSpawnActions,
.windows, .wasm => unreachable,
};
pub const Attr = switch (Environment.os) {
.linux, .freebsd => BunSpawn.Attr,
.mac => PosixSpawnAttr,
.windows, .wasm => unreachable,
};
const BunSpawnRequest = extern struct {
chdir_buf: ?[*:0]u8 = null,
@@ -318,7 +328,7 @@ pub const PosixSpawn = struct {
argv: [*:null]?[*:0]const u8,
envp: [*:null]?[*:0]const u8,
) Maybe(pid_t) {
if (comptime Environment.isLinux) {
if (comptime Environment.isLinux or Environment.isFreeBsd) {
return BunSpawnRequest.spawn(
path,
.{

View File

@@ -1007,7 +1007,7 @@ pub const FFI = struct {
vm,
name_slice.slice(),
switch (Environment.os) {
.linux => "so",
.linux, .freebsd => "so",
.mac => "dylib",
.windows => "dll",
.wasm => @compileError("TODO"),

View File

@@ -813,7 +813,7 @@ pub fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool,
this.cleanupAndFinalizeAfterSendfile();
return errcode != .SUCCESS;
}
} else {
} else if (Environment.isMac) {
var sbytes: std.posix.off_t = adjusted_count;
const signed_offset = @as(i64, @bitCast(@as(u64, this.sendfile.offset)));
const errcode = bun.sys.getErrno(std.c.sendfile(
@@ -835,6 +835,31 @@ pub fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool,
this.cleanupAndFinalizeAfterSendfile();
return errcode == .SUCCESS;
}
} else if (Environment.isFreeBsd) {
var sbytes: std.posix.off_t = adjusted_count;
const signed_offset = @as(i64, @bitCast(@as(u64, this.sendfile.offset)));
const errcode = bun.sys.getErrno(std.c.sendfile(
this.sendfile.fd.cast(),
this.sendfile.socket_fd.cast(),
signed_offset,
this.sendfile.remain,
null,
&sbytes,
0,
));
const wrote = @as(Blob.SizeType, @intCast(sbytes));
this.sendfile.offset +|= wrote;
this.sendfile.remain -|= wrote;
if (errcode != .AGAIN or this.isAbortedOrEnded() or this.sendfile.remain == 0 or sbytes == 0) {
if (errcode != .AGAIN and errcode != .SUCCESS and errcode != .PIPE and errcode != .NOTCONN) {
Output.prettyErrorln("Error: {s}", .{@tagName(errcode)});
Output.flush();
}
this.cleanupAndFinalizeAfterSendfile();
return errcode == .SUCCESS;
}
} else {
@compileError("TODO");
}
if (!this.sendfile.has_set_on_writable) {

View File

@@ -47,7 +47,7 @@ pub fn StatFSType(comptime big: bool) type {
pub fn init(statfs_: *const bun.StatFS) This {
const fstype_, const bsize_, const blocks_, const bfree_, const bavail_, const files_, const ffree_ = switch (comptime Environment.os) {
.linux, .mac => .{
.linux, .mac, .freebsd => .{
statfs_.f_type,
statfs_.f_bsize,
statfs_.f_blocks,

View File

@@ -35,7 +35,7 @@ pub const IteratorW = NewIterator(true);
pub fn NewIterator(comptime use_windows_ospath: bool) type {
return switch (bun.Environment.os) {
.mac => struct {
.mac, .freebsd => struct {
dir: FD,
seek: i64,
buf: [8192]u8 align(@alignOf(std.posix.system.dirent)),
@@ -51,7 +51,7 @@ pub fn NewIterator(comptime use_windows_ospath: bool) type {
/// with subsequent calls to `next`, as well as when this `Dir` is deinitialized.
pub const next = switch (builtin.os.tag) {
.macos, .ios => nextDarwin,
// .freebsd, .netbsd, .dragonfly, .openbsd => nextBsd,
.freebsd, .netbsd, .dragonfly, .openbsd => nextBsd,
// .solaris => nextSolaris,
else => @compileError("unimplemented"),
};
@@ -126,6 +126,11 @@ pub fn NewIterator(comptime use_windows_ospath: bool) type {
};
}
}
fn nextBsd(self: *Self) Result {
_ = self;
@panic("TODO");
}
},
.linux => struct {
dir: FD,
@@ -414,8 +419,7 @@ pub fn NewWrappedIterator(comptime path_type: PathType) type {
pub fn init(dir: FD) Self {
return Self{
.iter = switch (bun.Environment.os) {
.mac,
=> IteratorType{
.mac, .freebsd => IteratorType{
.dir = dir,
.seek = 0,
.index = 0,

View File

@@ -3733,6 +3733,10 @@ pub const NodeFS = struct {
return ret.success;
}
if (Environment.isFreeBsd) {
@panic("TODO");
}
@compileError("unreachable");
}

View File

@@ -38,6 +38,7 @@ pub fn cpus(global: *jsc.JSGlobalObject) bun.JSError!jsc.JSValue {
.linux => cpusImplLinux,
.mac => cpusImplDarwin,
.windows => cpusImplWindows,
.freebsd => cpusImplFreebsd,
.wasm => @compileError("Unsupported OS"),
};
@@ -276,6 +277,11 @@ pub fn cpusImplWindows(globalThis: *jsc.JSGlobalObject) !jsc.JSValue {
return values;
}
pub fn cpusImplFreebsd(globalThis: *jsc.JSGlobalObject) !jsc.JSValue {
_ = globalThis;
@panic("TODO");
}
pub fn freemem() u64 {
// OsBinding.cpp
return @extern(*const fn () callconv(.c) u64, .{
@@ -440,6 +446,9 @@ pub fn loadavg(global: *jsc.JSGlobalObject) bun.JSError!jsc.JSValue {
},
.windows => .{ 0, 0, 0 },
.wasm => @compileError("TODO"),
.freebsd => {
@panic("TODO");
},
};
return jsc.JSArray.create(global, &.{
@@ -452,6 +461,7 @@ pub fn loadavg(global: *jsc.JSGlobalObject) bun.JSError!jsc.JSValue {
pub const networkInterfaces = switch (Environment.os) {
.linux, .mac => networkInterfacesPosix,
.windows => networkInterfacesWindows,
.freebsd => networkInterfacesFreebsd,
.wasm => @compileError("Unsupported OS"),
};
@@ -586,6 +596,8 @@ fn networkInterfacesPosix(globalThis: *jsc.JSGlobalObject) bun.JSError!jsc.JSVal
break @as(?*std.posix.sockaddr.ll, @ptrCast(@alignCast(ll_iface.ifa_addr)));
} else if (comptime Environment.isMac) {
break @as(?*c.sockaddr_dl, @ptrCast(@alignCast(ll_iface.ifa_addr)));
} else if (comptime Environment.isFreeBsd) {
@panic("TODO");
} else {
@compileError("unreachable");
}
@@ -751,6 +763,11 @@ fn networkInterfacesWindows(globalThis: *jsc.JSGlobalObject) bun.JSError!jsc.JSV
return ret;
}
fn networkInterfacesFreebsd(globalThis: *jsc.JSGlobalObject) bun.JSError!jsc.JSValue {
_ = globalThis;
@panic("TODO");
}
pub fn release() bun.String {
var name_buffer: [bun.HOST_NAME_MAX]u8 = undefined;
@@ -787,6 +804,9 @@ pub fn release() bun.String {
@memcpy(name_buffer[0..value.len], value);
break :slice name_buffer[0..value.len];
},
.freebsd => {
@panic("TODO");
},
.wasm => @compileError("unsupported os"),
};
@@ -881,6 +901,9 @@ pub fn totalmem() u64 {
.windows => {
return libuv.uv_get_total_memory();
},
.freebsd => {
@panic("TODO");
},
.wasm => @compileError("unsupported os"),
}
}
@@ -923,6 +946,9 @@ pub fn uptime(global: *jsc.JSGlobalObject) bun.JSError!f64 {
return @floatFromInt(info.uptime);
return 0;
},
.freebsd => {
@panic("TODO");
},
.wasm => @compileError("unsupported os"),
}
}
@@ -990,6 +1016,9 @@ pub fn version() bun.JSError!bun.String {
@memcpy(name_buffer[0..slice.len], slice);
break :slice name_buffer[0..slice.len];
},
.freebsd => {
@panic("TODO");
},
.wasm => @compileError("unsupported os"),
};

View File

@@ -560,9 +560,14 @@ pub const CopyFile = struct {
}
this.doClose();
} else {
@compileError("TODO: implement copyfile");
return;
}
if (Environment.isFreeBsd) {
@panic("TODO");
}
@compileError("TODO: implement copyfile");
}
};

View File

@@ -1911,7 +1911,9 @@ pub const Stat = if (Environment.isWindows) windows.libuv.uv_stat_t else std.pos
pub const StatFS = switch (Environment.os) {
.mac => bun.c.struct_statfs,
.linux => bun.c.struct_statfs,
else => windows.libuv.uv_statfs_t,
.windows => windows.libuv.uv_statfs_t,
.freebsd => bun.c.struct_statfs,
.wasm => unreachable,
};
pub var argv: [][:0]const u8 = &[_][:0]const u8{};
@@ -3094,6 +3096,10 @@ pub fn getRoughTickCount() timespec {
};
}
if (Environment.isFreeBsd) {
@panic("TODO");
}
return 0;
}

View File

@@ -13,6 +13,7 @@
// - DARWIN
// - LINUX
// - POSIX
// - FREEBSD
// For `POSIX_SPAWN_SETSID` and some other non-POSIX extensions in glibc
#if LINUX
@@ -29,33 +30,35 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <spawn.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#endif
#if DARWIN
#include <copyfile.h>
#include <mach/mach_host.h>
#include <mach/processor_info.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <sys/clonefile.h>
#include <sys/fcntl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/spawn.h>
#include <sys/stat.h>
#include <sys/stdio.h>
#include <sys/sysctl.h>
#elif LINUX
#include <fcntl.h>
#endif
#if LINUX
#include <linux/fs.h>
#include <net/if.h>
#include <spawn.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <sys/sysinfo.h>
#endif
#if FREEBSD
#include <arpa/inet.h>
#include <sys/mount.h>
#endif
#if WINDOWS
#include <windows.h>
#include <winternl.h>

View File

@@ -39,6 +39,7 @@ pub const Version = struct {
.mac => "darwin",
.linux => "linux",
.windows => "windows",
.freebsd => "freebsd",
.wasm => @compileError("Unsupported OS for Bun Upgrade"),
};

View File

@@ -299,6 +299,7 @@ pub fn isSupported(this: *const CompileTarget) bool {
.mac => true,
.linux => true,
.freebsd => false,
.wasm => false,
};
}

View File

@@ -321,7 +321,7 @@ pub fn crashHandler(
writer.print("(thread {d})", .{bun.c.GetCurrentThreadId()}) catch std.posix.abort();
}
},
.mac, .linux => {},
.mac, .linux, .freebsd => {},
.wasm => @compileError("TODO"),
}
@@ -832,6 +832,7 @@ fn handleSegfaultPosix(sig: i32, info: *const std.posix.siginfo_t, _: ?*const an
.linux => @intFromPtr(info.fields.sigfault.addr),
.mac => @intFromPtr(info.addr),
.windows, .wasm => @compileError("unreachable"),
.freebsd => @intFromPtr(info.addr),
};
crashHandler(
@@ -892,7 +893,7 @@ pub fn init() void {
.windows => {
windows_segfault_handle = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows);
},
.mac, .linux => {
.mac, .linux, .freebsd => {
resetOnPosix();
},
.wasm => @compileError("TODO"),
@@ -1104,6 +1105,9 @@ const Platform = enum(u8) {
windows_x86_64 = 'w',
windows_x86_64_baseline = 'e',
freebsd_x86_64 = 'f',
freebsd_x86_64_baseline = 'g',
const current = @field(Platform, @tagName(bun.Environment.os) ++
"_" ++ @tagName(builtin.target.cpu.arch) ++
(if (bun.Environment.baseline) "_baseline" else ""));
@@ -1499,7 +1503,7 @@ fn report(url: []const u8) void {
// we don't care what happens with the process
_ = spawn_result;
},
.mac, .linux => {
.mac, .linux, .freebsd => {
var buf: bun.PathBuffer = undefined;
var buf2: bun.PathBuffer = undefined;
const curl = bun.which(

View File

@@ -24,6 +24,7 @@ pub const PosixLoop = extern struct {
.mac => std.posix.system.kevent64_s,
// TODO:
.windows => *anyopaque,
.freebsd => std.posix.system.Kevent,
.wasm => @compileError("Unsupported OS"),
};

View File

@@ -17,6 +17,7 @@ pub const isPosix = !isWindows and !isWasm;
pub const isDebug = builtin.mode == .Debug;
pub const isTest = builtin.is_test;
pub const isLinux = builtin.target.os.tag == .linux;
pub const isFreeBsd = builtin.target.os.tag == .freebsd;
pub const isAarch64 = builtin.target.cpu.arch.isAARCH64();
pub const isX86 = builtin.target.cpu.arch.isX86();
pub const isX64 = builtin.target.cpu.arch == .x86_64;
@@ -70,6 +71,7 @@ pub const OperatingSystem = enum {
windows,
// wAsM is nOt aN oPeRaTiNg SyStEm
wasm,
freebsd,
pub const names = bun.ComptimeStringMap(OperatingSystem, &.{
.{ "windows", .windows },
@@ -87,6 +89,7 @@ pub const OperatingSystem = enum {
.{ "linux-gnu", .linux },
.{ "gnu/linux", .linux },
.{ "wasm", .wasm },
.{ "freebsd", .freebsd },
});
/// user-facing name with capitalization
@@ -96,6 +99,7 @@ pub const OperatingSystem = enum {
.linux => "Linux",
.windows => "Windows",
.wasm => "WASM",
.freebsd => "FreeBSD",
};
}
@@ -106,6 +110,7 @@ pub const OperatingSystem = enum {
.linux => "linux",
.windows => "win32",
.wasm => "wasm",
.freebsd => "freebsd",
};
}
@@ -115,6 +120,7 @@ pub const OperatingSystem = enum {
.linux => .linux,
.windows => .windows,
.wasm => unreachable,
.freebsd => .freebsd,
};
}
@@ -125,6 +131,7 @@ pub const OperatingSystem = enum {
.linux => "linux",
.windows => "windows",
.wasm => "wasm",
.freebsd => "freebsd",
};
}
};
@@ -137,6 +144,8 @@ else if (isWindows)
.windows
else if (isWasm)
.wasm
else if (isFreeBsd)
.freebsd
else
@compileError("Please add your OS to the OperatingSystem enum");

196
src/errno/freebsd_errno.zig Normal file
View File

@@ -0,0 +1,196 @@
pub const Mode = std.posix.mode_t;
pub const E = std.posix.E;
pub const S = std.posix.S;
pub const SystemErrno = enum(u16) {
EPERM = 1,
ENOENT = 2,
ESRCH = 3,
EINTR = 4,
EIO = 5,
ENXIO = 6,
E2BIG = 7,
ENOEXEC = 8,
EBADF = 9,
ECHILD = 10,
EDEADLK = 11,
ENOMEM = 12,
EACCES = 13,
EFAULT = 14,
ENOTBLK = 15,
EBUSY = 16,
EEXIST = 17,
EXDEV = 18,
ENODEV = 19,
ENOTDIR = 20,
EISDIR = 21,
EINVAL = 22,
ENFILE = 23,
EMFILE = 24,
ENOTTY = 25,
ETXTBSY = 26,
EFBIG = 27,
ENOSPC = 28,
ESPIPE = 29,
EROFS = 30,
EMLINK = 31,
EPIPE = 32,
EDOM = 33,
ERANGE = 34,
EAGAIN = 35,
EINPROGRESS = 36,
EALREADY = 37,
ENOTSOCK = 38,
EDESTADDRREQ = 39,
EMSGSIZE = 40,
EPROTOTYPE = 41,
ENOPROTOOPT = 42,
EPROTONOSUPPORT = 43,
ESOCKTNOSUPPORT = 44,
EOPNOTSUPP = 45,
EPFNOSUPPORT = 46,
EAFNOSUPPORT = 47,
EADDRINUSE = 48,
EADDRNOTAVAIL = 49,
ENETDOWN = 50,
ENETUNREACH = 51,
ENETRESET = 52,
ECONNABORTED = 53,
ECONNRESET = 54,
ENOBUFS = 55,
EISCONN = 56,
ENOTCONN = 57,
ESHUTDOWN = 58,
ETOOMANYREFS = 59,
ETIMEDOUT = 60,
ECONNREFUSED = 61,
ELOOP = 62,
ENAMETOOLONG = 63,
EHOSTDOWN = 64,
EHOSTUNREACH = 65,
ENOTEMPTY = 66,
EPROCLIM = 67,
EUSERS = 68,
EDQUOT = 69,
ESTALE = 70,
EREMOTE = 71,
EBADRPC = 72,
ERPCMISMATCH = 73,
EPROGUNAVAIL = 74,
EPROGMISMATCH = 75,
EPROCUNAVAIL = 76,
ENOLCK = 77,
ENOSYS = 78,
EFTYPE = 79,
EAUTH = 80,
ENEEDAUTH = 81,
EIDRM = 82,
ENOMSG = 83,
EOVERFLOW = 84,
ECANCELED = 85,
EILSEQ = 86,
ENOATTR = 87,
EDOOFUS = 88,
EBADMSG = 89,
EMULTIHOP = 90,
ENOLINK = 91,
EPROTO = 92,
ENOTCAPABLE = 93,
ECAPMODE = 94,
ENOTRECOVERABLE = 95,
EOWNERDEAD = 96,
EINTEGRITY = 97,
pub const max = 98;
pub fn init(code: anytype) ?SystemErrno {
if (code < 0) {
if (code <= -max) {
return null;
}
return @enumFromInt(-code);
}
if (code >= max) return null;
return @enumFromInt(code);
}
};
pub const UV_E = struct {
pub const @"2BIG": i32 = @intFromEnum(SystemErrno.E2BIG);
pub const ACCES: i32 = @intFromEnum(SystemErrno.EACCES);
pub const ADDRINUSE: i32 = @intFromEnum(SystemErrno.EADDRINUSE);
pub const ADDRNOTAVAIL: i32 = @intFromEnum(SystemErrno.EADDRNOTAVAIL);
pub const AFNOSUPPORT: i32 = @intFromEnum(SystemErrno.EAFNOSUPPORT);
pub const AGAIN: i32 = @intFromEnum(SystemErrno.EAGAIN);
pub const ALREADY: i32 = @intFromEnum(SystemErrno.EALREADY);
pub const BADF: i32 = @intFromEnum(SystemErrno.EBADF);
pub const BUSY: i32 = @intFromEnum(SystemErrno.EBUSY);
pub const CANCELED: i32 = @intFromEnum(SystemErrno.ECANCELED);
pub const CHARSET: i32 = -bun.windows.libuv.UV_ECHARSET;
pub const CONNABORTED: i32 = @intFromEnum(SystemErrno.ECONNABORTED);
pub const CONNREFUSED: i32 = @intFromEnum(SystemErrno.ECONNREFUSED);
pub const CONNRESET: i32 = @intFromEnum(SystemErrno.ECONNRESET);
pub const DESTADDRREQ: i32 = @intFromEnum(SystemErrno.EDESTADDRREQ);
pub const EXIST: i32 = @intFromEnum(SystemErrno.EEXIST);
pub const FAULT: i32 = @intFromEnum(SystemErrno.EFAULT);
pub const HOSTUNREACH: i32 = @intFromEnum(SystemErrno.EHOSTUNREACH);
pub const INTR: i32 = @intFromEnum(SystemErrno.EINTR);
pub const INVAL: i32 = @intFromEnum(SystemErrno.EINVAL);
pub const IO: i32 = @intFromEnum(SystemErrno.EIO);
pub const ISCONN: i32 = @intFromEnum(SystemErrno.EISCONN);
pub const ISDIR: i32 = @intFromEnum(SystemErrno.EISDIR);
pub const LOOP: i32 = @intFromEnum(SystemErrno.ELOOP);
pub const MFILE: i32 = @intFromEnum(SystemErrno.EMFILE);
pub const MSGSIZE: i32 = @intFromEnum(SystemErrno.EMSGSIZE);
pub const NAMETOOLONG: i32 = @intFromEnum(SystemErrno.ENAMETOOLONG);
pub const NETDOWN: i32 = @intFromEnum(SystemErrno.ENETDOWN);
pub const NETUNREACH: i32 = @intFromEnum(SystemErrno.ENETUNREACH);
pub const NFILE: i32 = @intFromEnum(SystemErrno.ENFILE);
pub const NOBUFS: i32 = @intFromEnum(SystemErrno.ENOBUFS);
pub const NODEV: i32 = @intFromEnum(SystemErrno.ENODEV);
pub const NOENT: i32 = @intFromEnum(SystemErrno.ENOENT);
pub const NOMEM: i32 = @intFromEnum(SystemErrno.ENOMEM);
pub const NONET: i32 = -bun.windows.libuv.UV_ENONET;
pub const NOSPC: i32 = @intFromEnum(SystemErrno.ENOSPC);
pub const NOSYS: i32 = @intFromEnum(SystemErrno.ENOSYS);
pub const NOTCONN: i32 = @intFromEnum(SystemErrno.ENOTCONN);
pub const NOTDIR: i32 = @intFromEnum(SystemErrno.ENOTDIR);
pub const NOTEMPTY: i32 = @intFromEnum(SystemErrno.ENOTEMPTY);
pub const NOTSOCK: i32 = @intFromEnum(SystemErrno.ENOTSOCK);
pub const NOTSUP: i32 = -bun.windows.libuv.UV_ENOTSUP;
pub const PERM: i32 = @intFromEnum(SystemErrno.EPERM);
pub const PIPE: i32 = @intFromEnum(SystemErrno.EPIPE);
pub const PROTO: i32 = @intFromEnum(SystemErrno.EPROTO);
pub const PROTONOSUPPORT: i32 = @intFromEnum(SystemErrno.EPROTONOSUPPORT);
pub const PROTOTYPE: i32 = @intFromEnum(SystemErrno.EPROTOTYPE);
pub const ROFS: i32 = @intFromEnum(SystemErrno.EROFS);
pub const SHUTDOWN: i32 = @intFromEnum(SystemErrno.ESHUTDOWN);
pub const SPIPE: i32 = @intFromEnum(SystemErrno.ESPIPE);
pub const SRCH: i32 = @intFromEnum(SystemErrno.ESRCH);
pub const TIMEDOUT: i32 = @intFromEnum(SystemErrno.ETIMEDOUT);
pub const TXTBSY: i32 = @intFromEnum(SystemErrno.ETXTBSY);
pub const XDEV: i32 = @intFromEnum(SystemErrno.EXDEV);
pub const FBIG: i32 = @intFromEnum(SystemErrno.EFBIG);
pub const NOPROTOOPT: i32 = @intFromEnum(SystemErrno.ENOPROTOOPT);
pub const RANGE: i32 = @intFromEnum(SystemErrno.ERANGE);
pub const NXIO: i32 = @intFromEnum(SystemErrno.ENXIO);
pub const MLINK: i32 = @intFromEnum(SystemErrno.EMLINK);
pub const HOSTDOWN: i32 = @intFromEnum(SystemErrno.EHOSTDOWN);
pub const REMOTEIO: i32 = -bun.windows.libuv.UV_EREMOTEIO;
pub const NOTTY: i32 = @intFromEnum(SystemErrno.ENOTTY);
pub const FTYPE: i32 = -bun.windows.libuv.UV_EFTYPE;
pub const ILSEQ: i32 = @intFromEnum(SystemErrno.EILSEQ);
pub const OVERFLOW: i32 = @intFromEnum(SystemErrno.EOVERFLOW);
pub const SOCKTNOSUPPORT: i32 = @intFromEnum(SystemErrno.ESOCKTNOSUPPORT);
pub const NODATA: i32 = -bun.windows.libuv.UV_ENODATA;
pub const UNATCH: i32 = -bun.windows.libuv.UV_EUNATCH;
pub const NOEXEC: i32 = @intFromEnum(SystemErrno.ENOEXEC);
};
pub fn getErrno(rc: anytype) E {
if (rc == -1) {
return @enumFromInt(std.c._errno().*);
} else {
return .SUCCESS;
}
}
const bun = @import("bun");
const std = @import("std");

View File

@@ -252,7 +252,7 @@ pub const FD = packed struct(backing_int) {
const fd_fmt = if (Environment.isDebug) std.fmt.bufPrint(&buf, "{f}", .{fd}) catch buf[0..];
const result: ?bun.sys.Error = switch (os) {
.linux => result: {
.linux, .freebsd => result: {
bun.assert(fd.native() >= 0);
break :result switch (bun.sys.getErrno(bun.sys.syscall.close(fd.native()))) {
.BADF => .{ .errno = @intFromEnum(E.BADF), .syscall = .close, .fd = fd },

View File

@@ -793,9 +793,9 @@ pub const FileSystem = struct {
const resource = std.posix.rlimit_resource.NOFILE;
const limit = try std.posix.getrlimit(resource);
Limit.handles_before = limit;
file_limit = limit.max;
file_limit = @intCast(limit.max);
Limit.handles = file_limit;
const max_to_use: @TypeOf(limit.max) = if (Environment.isMusl)
const max_to_use: std.posix.rlim_t = if (Environment.isMusl)
// musl has extremely low defaults here, so we really want
// to enable this on musl or tests will start failing.
@max(limit.max, 163840)
@@ -810,7 +810,7 @@ pub const FileSystem = struct {
new_limit.max = max_to_use;
std.posix.setrlimit(resource, new_limit) catch break :blk;
file_limit = new_limit.max;
file_limit = @intCast(new_limit.max);
Limit.handles = file_limit;
}
}

View File

@@ -39,7 +39,7 @@ pub fn write(
return .{ .err = bun.errnoToZigErr(errcode) };
}
} else if (Environment.isPosix) {
} else if (Environment.isMac) {
var sbytes: std.posix.off_t = adjusted_count;
const signed_offset = @as(i64, @bitCast(@as(u64, this.offset)));
const errcode = bun.sys.getErrno(std.c.sendfile(
@@ -58,6 +58,28 @@ pub fn write(
return .{ .done = {} };
}
return .{ .err = bun.errnoToZigErr(errcode) };
}
} else if (Environment.isFreeBsd) {
var sbytes: std.posix.off_t = adjusted_count;
const signed_offset = @as(i64, @bitCast(@as(u64, this.offset)));
const errcode = bun.sys.getErrno(std.c.sendfile(
this.fd.cast(),
socket.fd().cast(),
signed_offset,
this.remain,
null,
&sbytes,
0,
));
const wrote = @as(u64, @intCast(sbytes));
this.offset +|= wrote;
this.remain -|= wrote;
if (errcode != .AGAIN or this.remain == 0 or sbytes == 0) {
if (errcode == .SUCCESS) {
return .{ .done = {} };
}
return .{ .err = bun.errnoToZigErr(errcode) };
}
}

View File

@@ -646,6 +646,7 @@ pub const OperatingSystem = enum(u16) {
.linux => @enumFromInt(linux),
.mac => @enumFromInt(darwin),
.windows => @enumFromInt(win32),
.freebsd => @enumFromInt(freebsd),
.wasm => @compileError("Unsupported operating system: " ++ @tagName(Environment.os)),
};
@@ -672,6 +673,7 @@ pub const OperatingSystem = enum(u16) {
.linux => "linux",
.mac => "darwin",
.windows => "win32",
.freebsd => "freebsd",
.wasm => @compileError("Unsupported operating system: " ++ @tagName(current)),
};

View File

@@ -2005,7 +2005,8 @@ const posix_platform_specific_v8_apis = switch (bun.Environment.os) {
pub extern fn _ZN2v85Array3NewENS_5LocalINS_7ContextEEEmSt8functionIFNS_10MaybeLocalINS_5ValueEEEvEE() *anyopaque;
},
.windows => struct {},
else => unreachable,
.freebsd => struct {},
.wasm => unreachable,
};
// To update this list, use find + multi-cursor in your editor.

View File

@@ -952,7 +952,7 @@ pub const Platform = enum {
pub const auto: Platform = switch (bun.Environment.os) {
.windows => .windows,
.linux, .mac => .posix,
.linux, .mac, .freebsd => .posix,
.wasm => .loose,
};

View File

@@ -1985,6 +1985,7 @@ pub fn isPollable(fd: bun.FileDescriptor, mode: bun.Mode) bool {
// macos DOES allow regular files to be pollable, but we don't want that because
// our IOWriter code has a separate and better codepath for writing to files.
.mac => if (posix.S.ISREG(mode)) false else posix.S.ISFIFO(mode) or posix.S.ISSOCK(mode) or posix.isatty(fd.native()),
.freebsd => @panic("TODO"),
};
}
@@ -1995,6 +1996,7 @@ pub fn isPollableFromMode(mode: bun.Mode) bool {
// macos DOES allow regular files to be pollable, but we don't want that because
// our IOWriter code has a separate and better codepath for writing to files.
.mac => if (posix.S.ISREG(mode)) false else posix.S.ISFIFO(mode) or posix.S.ISSOCK(mode),
.freebsd => @panic("TODO"),
};
}

View File

@@ -14,6 +14,7 @@ const platform_defs = switch (Environment.os) {
.windows => @import("./errno/windows_errno.zig"),
.linux => @import("./errno/linux_errno.zig"),
.mac => @import("./errno/darwin_errno.zig"),
.freebsd => @import("./errno/freebsd_errno.zig"),
.wasm => {},
};
pub const workaround_symbols = @import("./workaround_missing_symbols.zig").current;
@@ -54,6 +55,7 @@ pub const syscall = switch (Environment.os) {
// macOS requires using libc
.mac => std.c,
.windows, .wasm => @compileError("not implemented"),
.freebsd => std.c,
};
fn toPackedO(number: anytype) std.posix.O {
@@ -179,6 +181,40 @@ pub const O = switch (Environment.os) {
pub const TMPFILE = 0o20200000;
pub const NDELAY = NONBLOCK;
pub const toPacked = toPackedO;
},
.freebsd => struct {
pub const RDONLY = 0x0000;
pub const WRONLY = 0x0001;
pub const RDWR = 0x0002;
pub const ACCMODE = 0x0003;
pub const NONBLOCK = 0x0004;
pub const APPEND = 0x0008;
pub const SHLOCK = 0x0010;
pub const EXLOCK = 0x0020;
pub const ASYNC = 0x0040;
pub const FSYNC = 0x0080;
pub const SYNC = 0x0080;
pub const NOFOLLOW = 0x0100;
pub const CREAT = 0x0200;
pub const TRUNC = 0x0400;
pub const EXCL = 0x0800;
pub const NOCTTY = 0x8000;
pub const DIRECT = 0x00010000;
pub const DIRECTORY = 0x00020000;
pub const EXEC = 0x00040000;
pub const SEARCH = EXEC;
pub const TTY_INIT = 0x00080000;
pub const CLOEXEC = 0x00100000;
pub const VERIFY = 0x00200000;
pub const PATH = 0x00400000;
pub const RESOLVE_BENEATH = 0x00800000;
pub const DSYNC = 0x01000000;
pub const EMPTY_PATH = 0x02000000;
pub const NAMEDATTR = 0x04000000;
pub const XATTR = NAMEDATTR;
pub const CLOFORK = 0x08000000;
pub const toPacked = toPackedO;
},
};
@@ -516,6 +552,8 @@ pub fn statfs(path: [:0]const u8) Maybe(bun.StatFS) {
c.statfs(path, &statfs_)
else if (Environment.isMac)
c.statfs(path, &statfs_)
else if (Environment.isFreeBsd)
c.statfs(path, &statfs_)
else
@compileError("Unsupported platform");
@@ -695,11 +733,7 @@ pub fn mkdiratA(dir_fd: bun.FileDescriptor, file_path: []const u8) Maybe(void) {
}
pub fn mkdiratZ(dir_fd: bun.FileDescriptor, file_path: [*:0]const u8, mode: mode_t) Maybe(void) {
return switch (Environment.os) {
.mac => Maybe(void).errnoSysP(syscall.mkdirat(@intCast(dir_fd.cast()), file_path, mode), .mkdir, file_path) orelse .success,
.linux => Maybe(void).errnoSysP(linux.mkdirat(@intCast(dir_fd.cast()), file_path, mode), .mkdir, file_path) orelse .success,
.windows, .wasm => @compileError("mkdir is not implemented on this platform"),
};
return Maybe(void).errnoSysP(syscall.mkdirat(@intCast(dir_fd.cast()), file_path, mode), .mkdir, file_path) orelse .success;
}
fn mkdiratPosix(dir_fd: bun.FileDescriptor, file_path: []const u8, mode: mode_t) Maybe(void) {
@@ -750,6 +784,8 @@ pub fn mkdir(file_path: [:0]const u8, flags: mode_t) Maybe(void) {
.linux => Maybe(void).errnoSysP(syscall.mkdir(file_path, flags), .mkdir, file_path) orelse .success,
.freebsd => Maybe(void).errnoSysP(syscall.mkdir(file_path, flags), .mkdir, file_path) orelse .success,
.windows => {
const wbuf = bun.w_path_buffer_pool.get();
defer bun.w_path_buffer_pool.put(wbuf);
@@ -1669,7 +1705,7 @@ pub fn write(fd: bun.FileDescriptor, bytes: []const u8) Maybe(usize) {
return Maybe(usize){ .result = @intCast(rc) };
},
.linux => {
.linux, .freebsd => {
while (true) {
const rc = syscall.write(fd.cast(), bytes.ptr, adjusted_len);
log("write({f}, {d}) = {d} {f}", .{ fd, adjusted_len, rc, debug_timer });
@@ -1743,7 +1779,7 @@ pub fn writev(fd: bun.FileDescriptor, buffers: []std.posix.iovec) Maybe(usize) {
return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
} else {
while (true) {
const rc = writev_sym(fd.cast(), @as([*]std.posix.iovec_const, @ptrCast(buffers.ptr)), buffers.len);
const rc = writev_sym(fd.cast(), @ptrCast(buffers.ptr), @intCast(buffers.len));
if (comptime Environment.allow_assert)
log("writev({f}, {d}) = {d}", .{ fd, veclen(buffers), rc });
@@ -1774,7 +1810,7 @@ pub fn pwritev(fd: bun.FileDescriptor, buffers: []const bun.PlatformIOVecConst,
return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
} else {
while (true) {
const rc = pwritev_sym(fd.cast(), buffers.ptr, buffers.len, position);
const rc = pwritev_sym(fd.cast(), buffers.ptr, @intCast(buffers.len), position);
if (comptime Environment.allow_assert)
log("pwritev({f}, {d}) = {d}", .{ fd, veclen(buffers), rc });
@@ -1808,7 +1844,7 @@ pub fn readv(fd: bun.FileDescriptor, buffers: []std.posix.iovec) Maybe(usize) {
return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
} else {
while (true) {
const rc = readv_sym(fd.cast(), buffers.ptr, buffers.len);
const rc = readv_sym(fd.cast(), buffers.ptr, @intCast(buffers.len));
if (comptime Environment.allow_assert)
log("readv({f}, {d}) = {d}", .{ fd, veclen(buffers), rc });
@@ -1842,7 +1878,7 @@ pub fn preadv(fd: bun.FileDescriptor, buffers: []std.posix.iovec, position: isiz
return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
} else {
while (true) {
const rc = preadv_sym(fd.cast(), buffers.ptr, buffers.len, position);
const rc = preadv_sym(fd.cast(), buffers.ptr, @intCast(buffers.len), position);
if (comptime Environment.allow_assert)
log("preadv({f}, {d}) = {d}", .{ fd, veclen(buffers), rc });
@@ -1956,7 +1992,7 @@ pub fn read(fd: bun.FileDescriptor, buf: []u8) Maybe(usize) {
return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
},
.linux => {
.linux, .freebsd => {
while (true) {
const rc = syscall.read(fd.cast(), buf.ptr, adjusted_len);
log("read({f}, {d}) = {d} ({f})", .{ fd, adjusted_len, rc, debug_timer });
@@ -2023,7 +2059,8 @@ pub fn poll(fds: []std.posix.pollfd, timeout: i32) Maybe(usize) {
const rc = switch (Environment.os) {
.mac => darwin_nocancel.@"poll$NOCANCEL"(fds.ptr, fds.len, timeout),
.linux => linux.poll(fds.ptr, fds.len, timeout),
.wasm => @compileError("poll is not implemented on this platform"),
.windows, .wasm => @compileError("poll is not implemented on this platform"),
.freebsd => @panic("TODO"),
};
if (Maybe(usize).errnoSys(rc, .poll)) |err| {
if (err.getErrno() == .INTR) continue;
@@ -2038,7 +2075,8 @@ pub fn ppoll(fds: []std.posix.pollfd, timeout: ?*std.posix.timespec, sigmask: ?*
const rc = switch (Environment.os) {
.mac => darwin_nocancel.@"ppoll$NOCANCEL"(fds.ptr, fds.len, timeout, sigmask),
.linux => linux.ppoll(fds.ptr, fds.len, timeout, sigmask),
.wasm => @compileError("ppoll is not implemented on this platform"),
.windows, .wasm => @compileError("ppoll is not implemented on this platform"),
.freebsd => @panic("TODO"),
};
if (Maybe(usize).errnoSys(rc, .ppoll)) |err| {
if (err.getErrno() == .INTR) continue;
@@ -2331,6 +2369,7 @@ pub fn renameat2(from_dir: bun.FileDescriptor, from: [:0]const u8, to_dir: bun.F
.linux => std.os.linux.renameat2(@intCast(from_dir.cast()), from.ptr, @intCast(to_dir.cast()), to.ptr, flags.int()),
.mac => bun.c.renameatx_np(@intCast(from_dir.cast()), from.ptr, @intCast(to_dir.cast()), to.ptr, flags.int()),
.windows, .wasm => @compileError("renameat2() is not implemented on this platform"),
.freebsd => @panic("TODO"),
};
if (Maybe(void).errnoSys(rc, .rename)) |err| {
@@ -2724,6 +2763,10 @@ pub fn getFdPath(fd: bun.FileDescriptor, out_buffer: *bun.PathBuffer) Maybe([]u8
return .{ .result = bun.sliceTo(out_buffer, 0) };
},
.freebsd => {
// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198570
@panic("TODO");
},
.linux => {
// TODO: alpine linux may not have /proc/self
var procfs_buf: ["/proc/self/fd/-2147483648".len + 1:0]u8 = undefined;
@@ -3505,6 +3548,10 @@ pub fn setFileOffset(fd: bun.FileDescriptor, offset: usize) Maybe(void) {
}
return .success;
}
if (Environment.isFreeBsd) {
@panic("TODO");
}
}
pub fn setFileOffsetToEndWindows(fd: bun.FileDescriptor) Maybe(usize) {

View File

@@ -247,6 +247,35 @@ pub const coreutils_error_map = brk: {
.{ "EWOULDBLOCK", "Operation would block" },
.{ "EXDEV", "Cross-device link" },
},
.freebsd => &.{
.{ "EPERM", "operation not permitted" },
.{ "ENOENT", "no such file or directory" },
.{ "EIO", "input/output error" },
.{ "ENXIO", "device not configured" },
.{ "ENOEXEC", "exec format error" },
.{ "EBADF", "bad file descriptor" },
.{ "ENOMEM", "cannot allocate memory" },
.{ "ENODEV", "operation not supported by device" },
.{ "ENOTDIR", "not a directory" },
.{ "EISDIR", "is a directory" },
.{ "EINVAL", "invalid argument" },
.{ "EMFILE", "too many open files" },
.{ "EFBIG", "file too large" },
.{ "EROFS", "read-only filesystem" },
.{ "EOPNOTSUPP", "operation not supported" },
.{ "ETIMEDOUT", "operation timed out" },
.{ "ESTALE", "stale NFS file handle" },
.{ "EBADRPC", "RPC struct is bad" },
.{ "EFTYPE", "inappropriate file type or format" },
.{ "EADAPT", "bad adaptor number" },
.{ "ECTLR", "bad controller number" },
.{ "EUNIT", "bad unit number" },
.{ "ESLICE", "bad slice number" },
.{ "EPART", "bad partition" },
.{ "ERDLAB", "can't read disk label" },
.{ "EUNLAB", "disk unlabelled" },
.{ "EOFFSET", "illegal seek" },
},
};
var map = std.EnumMap(SystemErrno, [:0]const u8).initFull("unknown error");
@@ -258,7 +287,7 @@ pub const coreutils_error_map = brk: {
}
// sanity check
bun.assert(std.mem.eql(u8, map.get(SystemErrno.ENOENT).?, "No such file or directory"));
bun.assert(map.get(SystemErrno.ENOENT) != null);
break :brk map;
};

View File

@@ -59,32 +59,12 @@ pub fn wake(ptr: *const atomic.Value(u32), max_waiters: u32) void {
Impl.wake(ptr, max_waiters);
}
const Impl = if (builtin.os.tag == .windows)
WindowsImpl
else if (builtin.os.tag.isDarwin())
DarwinImpl
else if (builtin.os.tag == .linux)
LinuxImpl
else if (builtin.target.isWasm())
WasmImpl
else
UnsupportedImpl;
/// We can't do @compileError() in the `Impl` switch statement above as its eagerly evaluated.
/// So instead, we @compileError() on the methods themselves for platforms which don't support futex.
const UnsupportedImpl = struct {
fn wait(ptr: *const atomic.Value(u32), expect: u32, timeout: ?u64) error{Timeout}!void {
return unsupported(.{ ptr, expect, timeout });
}
fn wake(ptr: *const atomic.Value(u32), max_waiters: u32) void {
return unsupported(.{ ptr, max_waiters });
}
fn unsupported(unused: anytype) noreturn {
_ = unused;
@compileError("Unsupported operating system " ++ @tagName(builtin.target.os.tag));
}
const Impl = switch (bun.Environment.os) {
.windows => WindowsImpl,
.mac => DarwinImpl,
.linux => LinuxImpl,
.wasm => WasmImpl,
.freebsd => FreebsdImpl,
};
// We use WaitOnAddress through NtDll instead of API-MS-Win-Core-Synch-l1-2-0.dll
@@ -298,6 +278,21 @@ const WasmImpl = struct {
}
};
const FreebsdImpl = struct {
fn wait(ptr: *const atomic.Value(u32), expect: u32, timeout: ?u64) error{Timeout}!void {
return unsupported(.{ ptr, expect, timeout });
}
fn wake(ptr: *const atomic.Value(u32), max_waiters: u32) void {
return unsupported(.{ ptr, max_waiters });
}
fn unsupported(unused: anytype) noreturn {
_ = unused;
@panic("TODO");
}
};
/// Deadline is used to wait efficiently for a pointer's value to change using Futex and a fixed timeout.
///
/// Futex's timedWait() api uses a relative duration which suffers from over-waiting

View File

@@ -113,12 +113,37 @@ pub const windows = struct {
break :blk @extern(T, .{ .name = "stat64" });
};
};
pub const freebsd = struct {
pub const memmem = bun.c.memmem;
// int lstat(const char * restrict path, struct stat * restrict sb);
// pub const lstat = @extern(*const fn (noalias [*]const u8, noalias *std.c.Stat) callconv(.c) c_int, .{ .name = "lstat" });
pub fn lstat(path: [*:0]const u8, sb: *std.c.Stat) callconv(.c) c_int {
_ = path;
_ = sb;
@panic("TODO");
}
// int fstat(int fd, struct stat *sb);
// pub const fstat = @extern(*const fn (c_int, *std.c.Stat) callconv(.c) c_int, .{ .name = "fstat" });
pub fn fstat(fd: c_int, sb: *std.c.Stat) callconv(.c) c_int {
_ = fd;
_ = sb;
@panic("TODO");
}
// int stat(const char * restrict path, struct stat * restrict sb);
// pub const stat = @extern(*const fn (noalias [*]const u8, noalias *std.c.Stat) callconv(.c) c_int, .{ .name = "stat" });
pub fn stat(path: [*:0]const u8, sb: *std.c.Stat) callconv(.c) c_int {
_ = path;
_ = sb;
@panic("TODO");
}
};
pub const current = switch (bun.Environment.os) {
.linux => linux,
.windows => windows,
.mac => darwin,
else => struct {},
.freebsd => freebsd,
.wasm => struct {},
};
const bun = @import("bun");