aboutsummaryrefslogtreecommitdiff
path: root/src/io/io_darwin.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-03-21 02:21:51 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-03-21 02:21:51 -0700
commitfa343fa8adb25a7e307e91a3cd3c2c3f24e0152b (patch)
tree63a7ed4a7d787dd2b61330f5c1e69b2af0737e39 /src/io/io_darwin.zig
parent1f93de264f55e7a392bd34dbb9bda0b2365d7c88 (diff)
downloadbun-fa343fa8adb25a7e307e91a3cd3c2c3f24e0152b.tar.gz
bun-fa343fa8adb25a7e307e91a3cd3c2c3f24e0152b.tar.zst
bun-fa343fa8adb25a7e307e91a3cd3c2c3f24e0152b.zip
[bun.js] 1/? Implement `Response.file`
Diffstat (limited to 'src/io/io_darwin.zig')
-rw-r--r--src/io/io_darwin.zig127
1 files changed, 116 insertions, 11 deletions
diff --git a/src/io/io_darwin.zig b/src/io/io_darwin.zig
index 086a8a116..c3175a0ed 100644
--- a/src/io/io_darwin.zig
+++ b/src/io/io_darwin.zig
@@ -127,7 +127,7 @@ pub const Errno = error{
Unexpected,
};
-const errno_map: [108]Errno = brk: {
+pub const errno_map: [108]Errno = brk: {
var errors: [108]Errno = undefined;
errors[1] = error.EPERM;
errors[2] = error.ENOENT;
@@ -244,7 +244,12 @@ const socklen_t = darwin.socklen_t;
const system = darwin;
pub fn asError(err: anytype) Errno {
- return switch (@enumToInt(err)) {
+ const int = if (@typeInfo(@TypeOf(err)) == .Enum)
+ @enumToInt(err)
+ else
+ err;
+
+ return switch (int) {
1...errno_map.len => |val| errno_map[@intCast(u8, val)],
else => error.Unexpected,
};
@@ -257,22 +262,72 @@ const c = std.c;
const darwin = struct {
pub usingnamespace os.darwin;
pub extern "c" fn @"recvfrom$NOCANCEL"(sockfd: c.fd_t, noalias buf: *anyopaque, len: usize, flags: u32, noalias src_addr: ?*c.sockaddr, noalias addrlen: ?*c.socklen_t) isize;
- pub extern "c" fn @"sendto$NOCANCEL"(
- sockfd: c.fd_t,
- buf: *const anyopaque,
- len: usize,
- flags: u32,
- dest_addr: ?*const c.sockaddr,
- addrlen: c.socklen_t,
- ) isize;
+ pub extern "c" fn @"sendto$NOCANCEL"(sockfd: c.fd_t, buf: *const anyopaque, len: usize, flags: u32, dest_addr: ?*const c.sockaddr, addrlen: c.socklen_t) isize;
pub extern "c" fn @"fcntl$NOCANCEL"(fd: c.fd_t, cmd: c_int, ...) c_int;
pub extern "c" fn @"sendmsg$NOCANCEL"(sockfd: c.fd_t, msg: *const std.x.os.Socket.Message, flags: c_int) isize;
pub extern "c" fn @"recvmsg$NOCANCEL"(sockfd: c.fd_t, msg: *std.x.os.Socket.Message, flags: c_int) isize;
pub extern "c" fn @"connect$NOCANCEL"(sockfd: c.fd_t, sock_addr: *const c.sockaddr, addrlen: c.socklen_t) c_int;
pub extern "c" fn @"accept$NOCANCEL"(sockfd: c.fd_t, noalias addr: ?*c.sockaddr, noalias addrlen: ?*c.socklen_t) c_int;
pub extern "c" fn @"accept4$NOCANCEL"(sockfd: c.fd_t, noalias addr: ?*c.sockaddr, noalias addrlen: ?*c.socklen_t, flags: c_uint) c_int;
+ pub extern "c" fn @"open$NOCANCEL"(path: [*:0]const u8, oflag: c_uint, ...) c_int;
};
+pub const OpenError = error{
+ /// In WASI, this error may occur when the file descriptor does
+ /// not hold the required rights to open a new resource relative to it.
+ AccessDenied,
+ SymLinkLoop,
+ ProcessFdQuotaExceeded,
+ SystemFdQuotaExceeded,
+ NoDevice,
+ FileNotFound,
+
+ /// The path exceeded `MAX_PATH_BYTES` bytes.
+ NameTooLong,
+
+ /// Insufficient kernel memory was available, or
+ /// the named file is a FIFO and per-user hard limit on
+ /// memory allocation for pipes has been reached.
+ SystemResources,
+
+ /// The file is too large to be opened. This error is unreachable
+ /// for 64-bit targets, as well as when opening directories.
+ FileTooBig,
+
+ /// The path refers to directory but the `O.DIRECTORY` flag was not provided.
+ IsDir,
+
+ /// A new path cannot be created because the device has no room for the new file.
+ /// This error is only reachable when the `O.CREAT` flag is provided.
+ NoSpaceLeft,
+
+ /// A component used as a directory in the path was not, in fact, a directory, or
+ /// `O.DIRECTORY` was specified and the path was not a directory.
+ NotDir,
+
+ /// The path already exists and the `O.CREAT` and `O.EXCL` flags were provided.
+ PathAlreadyExists,
+ DeviceBusy,
+
+ /// The underlying filesystem does not support file locks
+ FileLocksNotSupported,
+
+ BadPathName,
+ InvalidUtf8,
+
+ /// One of these three things:
+ /// * pathname refers to an executable image which is currently being
+ /// executed and write access was requested.
+ /// * pathname refers to a file that is currently in use as a swap
+ /// file, and the O_TRUNC flag was specified.
+ /// * pathname refers to a file that is currently being read by the
+ /// kernel (e.g., for module/firmware loading), and write access was
+ /// requested.
+ FileBusy,
+
+ WouldBlock,
+} || Errno;
+
pub const Syscall = struct {
pub fn close(fd: std.os.fd_t) CloseError!void {
return switch (darwin.getErrno(darwin.@"close$NOCANCEL"(fd))) {
@@ -283,6 +338,30 @@ pub const Syscall = struct {
};
}
+ pub fn open(path: [*:0]const u8, oflag: c_uint) OpenError!fd_t {
+ const fd = darwin.@"open$NOCANCEL"(path, oflag);
+ return switch (darwin.getErrno(fd)) {
+ .SUCCESS => fd,
+ .ACCES => error.AccessDenied,
+ .FBIG => error.FileTooBig,
+ .OVERFLOW => error.FileTooBig,
+ .ISDIR => error.IsDir,
+ .LOOP => error.SymLinkLoop,
+ .MFILE => error.ProcessFdQuotaExceeded,
+ .NAMETOOLONG => error.NameTooLong,
+ .NFILE => error.SystemFdQuotaExceeded,
+ .NODEV => error.NoDevice,
+ .NOENT => error.FileNotFound,
+ .NOMEM => error.SystemResources,
+ .NOSPC => error.NoSpaceLeft,
+ .NOTDIR => error.NotDir,
+ .PERM => error.AccessDenied,
+ .EXIST => error.PathAlreadyExists,
+ .BUSY => error.DeviceBusy,
+ else => |err| asError(err),
+ };
+ }
+
pub const SocketError = error{
/// Permission to create a socket of the specified type and/or
/// pro‐tocol is denied.
@@ -407,7 +486,7 @@ io_pending: FIFO(Completion) = .{},
last_event_fd: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(32),
pub fn hasNoWork(this: *IO) bool {
- return this.io_inflight == 0 and this.io_pending.peek() == null and this.completed.peek() == null and this.timeouts.peek() == null;
+ return this.io_inflight == 0 and this.io_pending.peek() == null and this.completed.peek() == null and this.timeouts.peek() == null;
}
pub fn init(_: u12, _: u32) !IO {
@@ -1014,6 +1093,32 @@ pub fn fsync(
);
}
+/// macOS does not support reading for readiness for open()
+/// so we just run this blocking
+pub fn open(
+ _: *IO,
+ comptime Context: type,
+ context: Context,
+ comptime callback: fn (
+ context: Context,
+ completion: *Completion,
+ result: OpenError!fd_t,
+ ) void,
+ completion: *Completion,
+ file_path: [:0]const u8,
+ flags: os.mode_t,
+ _: os.mode_t,
+) void {
+ callback(context, completion, openSync(file_path, flags));
+}
+
+pub fn openSync(
+ file_path: [:0]const u8,
+ flags: os.mode_t,
+) OpenError!fd_t {
+ return Syscall.open(file_path, @intCast(c_uint, flags));
+}
+
pub const ReadError = error{
WouldBlock,
NotOpenForReading,