mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
std: fix macos compilation errors
This commit is contained in:
parent
f7d47aed47
commit
031044b399
@ -1469,7 +1469,7 @@ fn pwrite(userdata: ?*anyopaque, file: Io.File, buffer: []const u8, offset: std.
|
|||||||
.OVERFLOW => return error.Unseekable,
|
.OVERFLOW => return error.Unseekable,
|
||||||
.BUSY => return error.DeviceBusy,
|
.BUSY => return error.DeviceBusy,
|
||||||
.CONNRESET => return error.ConnectionResetByPeer,
|
.CONNRESET => return error.ConnectionResetByPeer,
|
||||||
.MSGSIZE => return error.MessageTooBig,
|
.MSGSIZE => return error.MessageOversize,
|
||||||
else => |err| return std.posix.unexpectedErrno(err),
|
else => |err| return std.posix.unexpectedErrno(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -966,7 +966,7 @@ fn dirStatPathPosix(
|
|||||||
try t.checkCancel();
|
try t.checkCancel();
|
||||||
var stat = std.mem.zeroes(posix.Stat);
|
var stat = std.mem.zeroes(posix.Stat);
|
||||||
switch (posix.errno(fstatat_sym(dir.handle, sub_path_posix, &stat, flags))) {
|
switch (posix.errno(fstatat_sym(dir.handle, sub_path_posix, &stat, flags))) {
|
||||||
.SUCCESS => return statFromPosix(stat),
|
.SUCCESS => return statFromPosix(&stat),
|
||||||
.INTR => continue,
|
.INTR => continue,
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.BADF => |err| return errnoBug(err), // Always a race condition.
|
.BADF => |err| return errnoBug(err), // Always a race condition.
|
||||||
@ -1166,8 +1166,9 @@ fn dirCreateFilePosix(
|
|||||||
if (has_flock_open_flags and flags.lock_nonblocking) {
|
if (has_flock_open_flags and flags.lock_nonblocking) {
|
||||||
var fl_flags: usize = while (true) {
|
var fl_flags: usize = while (true) {
|
||||||
try t.checkCancel();
|
try t.checkCancel();
|
||||||
switch (posix.errno(posix.system.fcntl(fd, posix.F.GETFL, 0))) {
|
const rc = posix.system.fcntl(fd, posix.F.GETFL, @as(usize, 0));
|
||||||
.SUCCESS => break,
|
switch (posix.errno(rc)) {
|
||||||
|
.SUCCESS => break @intCast(rc),
|
||||||
.INTR => continue,
|
.INTR => continue,
|
||||||
else => |err| return posix.unexpectedErrno(err),
|
else => |err| return posix.unexpectedErrno(err),
|
||||||
}
|
}
|
||||||
@ -1295,8 +1296,9 @@ fn dirOpenFile(
|
|||||||
if (has_flock_open_flags and flags.lock_nonblocking) {
|
if (has_flock_open_flags and flags.lock_nonblocking) {
|
||||||
var fl_flags: usize = while (true) {
|
var fl_flags: usize = while (true) {
|
||||||
try t.checkCancel();
|
try t.checkCancel();
|
||||||
switch (posix.errno(posix.system.fcntl(fd, posix.F.GETFL, 0))) {
|
const rc = posix.system.fcntl(fd, posix.F.GETFL, @as(usize, 0));
|
||||||
.SUCCESS => break,
|
switch (posix.errno(rc)) {
|
||||||
|
.SUCCESS => break @intCast(rc),
|
||||||
.INTR => continue,
|
.INTR => continue,
|
||||||
else => |err| return posix.unexpectedErrno(err),
|
else => |err| return posix.unexpectedErrno(err),
|
||||||
}
|
}
|
||||||
@ -1755,7 +1757,7 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
|
|||||||
.sec = std.math.maxInt(sec_type),
|
.sec = std.math.maxInt(sec_type),
|
||||||
.nsec = std.math.maxInt(nsec_type),
|
.nsec = std.math.maxInt(nsec_type),
|
||||||
};
|
};
|
||||||
break :t timestampToPosix(d.duration.nanoseconds);
|
break :t timestampToPosix(d.raw.toNanoseconds());
|
||||||
};
|
};
|
||||||
while (true) {
|
while (true) {
|
||||||
try t.checkCancel();
|
try t.checkCancel();
|
||||||
@ -1850,6 +1852,7 @@ fn netListenUnix(
|
|||||||
error.ProtocolUnsupportedBySystem => return error.AddressFamilyUnsupported,
|
error.ProtocolUnsupportedBySystem => return error.AddressFamilyUnsupported,
|
||||||
error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
|
error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
|
||||||
error.SocketModeUnsupported => return error.AddressFamilyUnsupported,
|
error.SocketModeUnsupported => return error.AddressFamilyUnsupported,
|
||||||
|
error.OptionUnsupported => return error.Unexpected,
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
errdefer posix.close(socket_fd);
|
errdefer posix.close(socket_fd);
|
||||||
@ -2037,7 +2040,10 @@ fn netConnectUnix(
|
|||||||
) net.UnixAddress.ConnectError!net.Socket.Handle {
|
) net.UnixAddress.ConnectError!net.Socket.Handle {
|
||||||
if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
|
if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
|
||||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||||
const socket_fd = try openSocketPosix(t, posix.AF.UNIX, .{ .mode = .stream });
|
const socket_fd = openSocketPosix(t, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
|
||||||
|
error.OptionUnsupported => return error.Unexpected,
|
||||||
|
else => |e| return e,
|
||||||
|
};
|
||||||
errdefer posix.close(socket_fd);
|
errdefer posix.close(socket_fd);
|
||||||
var storage: UnixAddress = undefined;
|
var storage: UnixAddress = undefined;
|
||||||
const addr_len = addressUnixToPosix(address, &storage);
|
const addr_len = addressUnixToPosix(address, &storage);
|
||||||
@ -2064,7 +2070,22 @@ fn netBindIpPosix(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn openSocketPosix(t: *Threaded, family: posix.sa_family_t, options: IpAddress.BindOptions) !posix.socket_t {
|
fn openSocketPosix(
|
||||||
|
t: *Threaded,
|
||||||
|
family: posix.sa_family_t,
|
||||||
|
options: IpAddress.BindOptions,
|
||||||
|
) error{
|
||||||
|
AddressFamilyUnsupported,
|
||||||
|
ProtocolUnsupportedBySystem,
|
||||||
|
ProcessFdQuotaExceeded,
|
||||||
|
SystemFdQuotaExceeded,
|
||||||
|
SystemResources,
|
||||||
|
ProtocolUnsupportedByAddressFamily,
|
||||||
|
SocketModeUnsupported,
|
||||||
|
OptionUnsupported,
|
||||||
|
Unexpected,
|
||||||
|
Canceled,
|
||||||
|
}!posix.socket_t {
|
||||||
const mode = posixSocketMode(options.mode);
|
const mode = posixSocketMode(options.mode);
|
||||||
const protocol = posixProtocol(options.protocol);
|
const protocol = posixProtocol(options.protocol);
|
||||||
const socket_fd = while (true) {
|
const socket_fd = while (true) {
|
||||||
@ -2209,7 +2230,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
|
|||||||
.NOTCONN => return error.SocketUnconnected,
|
.NOTCONN => return error.SocketUnconnected,
|
||||||
.CONNRESET => return error.ConnectionResetByPeer,
|
.CONNRESET => return error.ConnectionResetByPeer,
|
||||||
.TIMEDOUT => return error.Timeout,
|
.TIMEDOUT => return error.Timeout,
|
||||||
.PIPE => return error.BrokenPipe,
|
.PIPE => return error.SocketUnconnected,
|
||||||
.NETDOWN => return error.NetworkDown,
|
.NETDOWN => return error.NetworkDown,
|
||||||
else => |err| return posix.unexpectedErrno(err),
|
else => |err| return posix.unexpectedErrno(err),
|
||||||
}
|
}
|
||||||
@ -2253,29 +2274,29 @@ fn netSendOne(
|
|||||||
flags: u32,
|
flags: u32,
|
||||||
) net.Socket.SendError!void {
|
) net.Socket.SendError!void {
|
||||||
var addr: PosixAddress = undefined;
|
var addr: PosixAddress = undefined;
|
||||||
var iovec: posix.iovec = .{ .base = @constCast(message.data_ptr), .len = message.data_len };
|
var iovec: posix.iovec_const = .{ .base = @constCast(message.data_ptr), .len = message.data_len };
|
||||||
const msg: posix.msghdr = .{
|
const msg: posix.msghdr_const = .{
|
||||||
.name = &addr.any,
|
.name = &addr.any,
|
||||||
.namelen = addressToPosix(message.address, &addr),
|
.namelen = addressToPosix(message.address, &addr),
|
||||||
.iov = iovec[0..1],
|
.iov = (&iovec)[0..1],
|
||||||
.iovlen = 1,
|
.iovlen = 1,
|
||||||
.control = @constCast(message.control.ptr),
|
.control = @constCast(message.control.ptr),
|
||||||
.controllen = message.control.len,
|
.controllen = @intCast(message.control.len),
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
};
|
};
|
||||||
while (true) {
|
while (true) {
|
||||||
try t.checkCancel();
|
try t.checkCancel();
|
||||||
const rc = posix.system.sendmsg(handle, msg, flags);
|
const rc = posix.system.sendmsg(handle, &msg, flags);
|
||||||
if (is_windows) {
|
if (is_windows) {
|
||||||
if (rc == windows.ws2_32.SOCKET_ERROR) {
|
if (rc == windows.ws2_32.SOCKET_ERROR) {
|
||||||
switch (windows.ws2_32.WSAGetLastError()) {
|
switch (windows.ws2_32.WSAGetLastError()) {
|
||||||
.WSAEACCES => return error.AccessDenied,
|
.WSAEACCES => return error.AccessDenied,
|
||||||
.WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
|
.WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
|
||||||
.WSAECONNRESET => return error.ConnectionResetByPeer,
|
.WSAECONNRESET => return error.ConnectionResetByPeer,
|
||||||
.WSAEMSGSIZE => return error.MessageTooBig,
|
.WSAEMSGSIZE => return error.MessageOversize,
|
||||||
.WSAENOBUFS => return error.SystemResources,
|
.WSAENOBUFS => return error.SystemResources,
|
||||||
.WSAENOTSOCK => return error.FileDescriptorNotASocket,
|
.WSAENOTSOCK => return error.FileDescriptorNotASocket,
|
||||||
.WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.WSAEAFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.WSAEDESTADDRREQ => unreachable, // A destination address is required.
|
.WSAEDESTADDRREQ => unreachable, // A destination address is required.
|
||||||
.WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
|
.WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
|
||||||
.WSAEHOSTUNREACH => return error.NetworkUnreachable,
|
.WSAEHOSTUNREACH => return error.NetworkUnreachable,
|
||||||
@ -2285,7 +2306,6 @@ fn netSendOne(
|
|||||||
.WSAENETUNREACH => return error.NetworkUnreachable,
|
.WSAENETUNREACH => return error.NetworkUnreachable,
|
||||||
.WSAENOTCONN => return error.SocketUnconnected,
|
.WSAENOTCONN => return error.SocketUnconnected,
|
||||||
.WSAESHUTDOWN => unreachable, // The socket has been shut down; it is not possible to WSASendTo on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
|
.WSAESHUTDOWN => unreachable, // The socket has been shut down; it is not possible to WSASendTo on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
|
||||||
.WSAEWOULDBLOCK => return error.WouldBlock,
|
|
||||||
.WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function.
|
.WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function.
|
||||||
else => |err| return windows.unexpectedWSAError(err),
|
else => |err| return windows.unexpectedWSAError(err),
|
||||||
}
|
}
|
||||||
@ -2299,28 +2319,24 @@ fn netSendOne(
|
|||||||
message.data_len = @intCast(rc);
|
message.data_len = @intCast(rc);
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
.INTR => continue,
|
||||||
|
|
||||||
.ACCES => return error.AccessDenied,
|
.ACCES => return error.AccessDenied,
|
||||||
.AGAIN => return error.WouldBlock,
|
|
||||||
.ALREADY => return error.FastOpenAlreadyInProgress,
|
.ALREADY => return error.FastOpenAlreadyInProgress,
|
||||||
.BADF => |err| return errnoBug(err),
|
.BADF => |err| return errnoBug(err),
|
||||||
.CONNRESET => return error.ConnectionResetByPeer,
|
.CONNRESET => return error.ConnectionResetByPeer,
|
||||||
.DESTADDRREQ => |err| return errnoBug(err),
|
.DESTADDRREQ => |err| return errnoBug(err),
|
||||||
.FAULT => |err| return errnoBug(err),
|
.FAULT => |err| return errnoBug(err),
|
||||||
.INTR => continue,
|
|
||||||
.INVAL => |err| return errnoBug(err),
|
.INVAL => |err| return errnoBug(err),
|
||||||
.ISCONN => |err| return errnoBug(err),
|
.ISCONN => |err| return errnoBug(err),
|
||||||
.MSGSIZE => return error.MessageTooBig,
|
.MSGSIZE => return error.MessageOversize,
|
||||||
.NOBUFS => return error.SystemResources,
|
.NOBUFS => return error.SystemResources,
|
||||||
.NOMEM => return error.SystemResources,
|
.NOMEM => return error.SystemResources,
|
||||||
.NOTSOCK => |err| return errnoBug(err),
|
.NOTSOCK => |err| return errnoBug(err),
|
||||||
.OPNOTSUPP => |err| return errnoBug(err),
|
.OPNOTSUPP => |err| return errnoBug(err),
|
||||||
.PIPE => return error.BrokenPipe,
|
.PIPE => return error.SocketUnconnected,
|
||||||
.AFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.LOOP => return error.SymLinkLoop,
|
.HOSTUNREACH => return error.HostUnreachable,
|
||||||
.NAMETOOLONG => return error.NameTooLong,
|
|
||||||
.NOENT => return error.FileNotFound,
|
|
||||||
.NOTDIR => return error.NotDir,
|
|
||||||
.HOSTUNREACH => return error.NetworkUnreachable,
|
|
||||||
.NETUNREACH => return error.NetworkUnreachable,
|
.NETUNREACH => return error.NetworkUnreachable,
|
||||||
.NOTCONN => return error.SocketUnconnected,
|
.NOTCONN => return error.SocketUnconnected,
|
||||||
.NETDOWN => return error.NetworkDown,
|
.NETDOWN => return error.NetworkDown,
|
||||||
@ -2447,7 +2463,7 @@ fn netReceive(
|
|||||||
.iov = (&iov)[0..1],
|
.iov = (&iov)[0..1],
|
||||||
.iovlen = 1,
|
.iovlen = 1,
|
||||||
.control = message.control.ptr,
|
.control = message.control.ptr,
|
||||||
.controllen = message.control.len,
|
.controllen = @intCast(message.control.len),
|
||||||
.flags = undefined,
|
.flags = undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2465,7 +2481,7 @@ fn netReceive(
|
|||||||
.trunc = (msg.flags & posix.MSG.TRUNC) != 0,
|
.trunc = (msg.flags & posix.MSG.TRUNC) != 0,
|
||||||
.ctrunc = (msg.flags & posix.MSG.CTRUNC) != 0,
|
.ctrunc = (msg.flags & posix.MSG.CTRUNC) != 0,
|
||||||
.oob = (msg.flags & posix.MSG.OOB) != 0,
|
.oob = (msg.flags & posix.MSG.OOB) != 0,
|
||||||
.errqueue = (msg.flags & posix.MSG.ERRQUEUE) != 0,
|
.errqueue = if (@hasDecl(posix.MSG, "ERRQUEUE")) (msg.flags & posix.MSG.ERRQUEUE) != 0 else false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
message_i += 1;
|
message_i += 1;
|
||||||
@ -2605,6 +2621,7 @@ fn netInterfaceNameResolve(
|
|||||||
error.ProtocolUnsupportedBySystem => return error.Unexpected,
|
error.ProtocolUnsupportedBySystem => return error.Unexpected,
|
||||||
error.ProtocolUnsupportedByAddressFamily => return error.Unexpected,
|
error.ProtocolUnsupportedByAddressFamily => return error.Unexpected,
|
||||||
error.SocketModeUnsupported => return error.Unexpected,
|
error.SocketModeUnsupported => return error.Unexpected,
|
||||||
|
error.OptionUnsupported => return error.Unexpected,
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
defer posix.close(sock_fd);
|
defer posix.close(sock_fd);
|
||||||
@ -3079,9 +3096,10 @@ fn lookupDns(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var ip4_mapped: [HostName.ResolvConf.max_nameservers]IpAddress = undefined;
|
var ip4_mapped_buffer: [HostName.ResolvConf.max_nameservers]IpAddress = undefined;
|
||||||
|
const ip4_mapped = ip4_mapped_buffer[0..rc.nameservers_len];
|
||||||
var any_ip6 = false;
|
var any_ip6 = false;
|
||||||
for (rc.nameservers(), &ip4_mapped) |*ns, *m| {
|
for (rc.nameservers(), ip4_mapped) |*ns, *m| {
|
||||||
m.* = .{ .ip6 = .fromAny(ns.*) };
|
m.* = .{ .ip6 = .fromAny(ns.*) };
|
||||||
any_ip6 = any_ip6 or ns.* == .ip6;
|
any_ip6 = any_ip6 or ns.* == .ip6;
|
||||||
}
|
}
|
||||||
@ -3101,7 +3119,7 @@ fn lookupDns(
|
|||||||
};
|
};
|
||||||
defer socket.close(t_io);
|
defer socket.close(t_io);
|
||||||
|
|
||||||
const mapped_nameservers = if (any_ip6) ip4_mapped[0..rc.nameservers_len] else rc.nameservers();
|
const mapped_nameservers = if (any_ip6) ip4_mapped else rc.nameservers();
|
||||||
const queries = queries_buffer[0..nq];
|
const queries = queries_buffer[0..nq];
|
||||||
const answers = answers_buffer[0..queries.len];
|
const answers = answers_buffer[0..queries.len];
|
||||||
var answers_remaining = answers.len;
|
var answers_remaining = answers.len;
|
||||||
|
|||||||
@ -209,6 +209,9 @@ pub const IpAddress = union(enum) {
|
|||||||
ProtocolUnsupportedBySystem,
|
ProtocolUnsupportedBySystem,
|
||||||
ProtocolUnsupportedByAddressFamily,
|
ProtocolUnsupportedByAddressFamily,
|
||||||
SocketModeUnsupported,
|
SocketModeUnsupported,
|
||||||
|
/// One of the `ListenOptions` is not supported by the Io
|
||||||
|
/// implementation.
|
||||||
|
OptionUnsupported,
|
||||||
} || Io.UnexpectedError || Io.Cancelable;
|
} || Io.UnexpectedError || Io.Cancelable;
|
||||||
|
|
||||||
pub const ListenOptions = struct {
|
pub const ListenOptions = struct {
|
||||||
@ -1057,6 +1060,9 @@ pub const Socket = struct {
|
|||||||
/// Local end has been shut down on a connection-oriented socket, or
|
/// Local end has been shut down on a connection-oriented socket, or
|
||||||
/// the socket was never connected.
|
/// the socket was never connected.
|
||||||
SocketUnconnected,
|
SocketUnconnected,
|
||||||
|
/// An attempt was made to send to a network/broadcast address as
|
||||||
|
/// though it was a unicast address.
|
||||||
|
AccessDenied,
|
||||||
} || Io.UnexpectedError || Io.Cancelable;
|
} || Io.UnexpectedError || Io.Cancelable;
|
||||||
|
|
||||||
/// Transfers `data` to `dest`, connectionless, in one packet.
|
/// Transfers `data` to `dest`, connectionless, in one packet.
|
||||||
@ -1167,7 +1173,6 @@ pub const Stream = struct {
|
|||||||
|
|
||||||
pub const Error = error{
|
pub const Error = error{
|
||||||
SystemResources,
|
SystemResources,
|
||||||
BrokenPipe,
|
|
||||||
ConnectionResetByPeer,
|
ConnectionResetByPeer,
|
||||||
Timeout,
|
Timeout,
|
||||||
SocketUnconnected,
|
SocketUnconnected,
|
||||||
@ -1233,7 +1238,7 @@ pub const Stream = struct {
|
|||||||
pub const Error = std.posix.SendMsgError || error{
|
pub const Error = std.posix.SendMsgError || error{
|
||||||
ConnectionResetByPeer,
|
ConnectionResetByPeer,
|
||||||
SocketNotBound,
|
SocketNotBound,
|
||||||
MessageTooBig,
|
MessageOversize,
|
||||||
NetworkDown,
|
NetworkDown,
|
||||||
SystemResources,
|
SystemResources,
|
||||||
SocketUnconnected,
|
SocketUnconnected,
|
||||||
|
|||||||
@ -4104,7 +4104,7 @@ pub const msghdr = switch (native_os) {
|
|||||||
.visionos,
|
.visionos,
|
||||||
.watchos,
|
.watchos,
|
||||||
.serenity, // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L74-L82
|
.serenity, // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L74-L82
|
||||||
=> private.posix_msghdr,
|
=> posix_msghdr,
|
||||||
else => void,
|
else => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -70,18 +70,18 @@ pub const RescanError = RescanLinuxError || RescanMacError || RescanWithPathErro
|
|||||||
/// file system standard locations for certificates.
|
/// file system standard locations for certificates.
|
||||||
/// For operating systems that do not have standard CA installations to be
|
/// For operating systems that do not have standard CA installations to be
|
||||||
/// found, this function clears the set of certificates.
|
/// found, this function clears the set of certificates.
|
||||||
pub fn rescan(cb: *Bundle, gpa: Allocator, io: Io) RescanError!void {
|
pub fn rescan(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanError!void {
|
||||||
switch (builtin.os.tag) {
|
switch (builtin.os.tag) {
|
||||||
.linux => return rescanLinux(cb, gpa, io),
|
.linux => return rescanLinux(cb, gpa, io, now),
|
||||||
.macos => return rescanMac(cb, gpa),
|
.macos => return rescanMac(cb, gpa, io, now),
|
||||||
.freebsd, .openbsd => return rescanWithPath(cb, gpa, io, "/etc/ssl/cert.pem"),
|
.freebsd, .openbsd => return rescanWithPath(cb, gpa, io, now, "/etc/ssl/cert.pem"),
|
||||||
.netbsd => return rescanWithPath(cb, gpa, io, "/etc/openssl/certs/ca-certificates.crt"),
|
.netbsd => return rescanWithPath(cb, gpa, io, now, "/etc/openssl/certs/ca-certificates.crt"),
|
||||||
.dragonfly => return rescanWithPath(cb, gpa, io, "/usr/local/etc/ssl/cert.pem"),
|
.dragonfly => return rescanWithPath(cb, gpa, io, now, "/usr/local/etc/ssl/cert.pem"),
|
||||||
.illumos => return rescanWithPath(cb, gpa, io, "/etc/ssl/cacert.pem"),
|
.illumos => return rescanWithPath(cb, gpa, io, now, "/etc/ssl/cacert.pem"),
|
||||||
.haiku => return rescanWithPath(cb, gpa, io, "/boot/system/data/ssl/CARootCertificates.pem"),
|
.haiku => return rescanWithPath(cb, gpa, io, now, "/boot/system/data/ssl/CARootCertificates.pem"),
|
||||||
// https://github.com/SerenityOS/serenity/blob/222acc9d389bc6b490d4c39539761b043a4bfcb0/Ports/ca-certificates/package.sh#L19
|
// https://github.com/SerenityOS/serenity/blob/222acc9d389bc6b490d4c39539761b043a4bfcb0/Ports/ca-certificates/package.sh#L19
|
||||||
.serenity => return rescanWithPath(cb, gpa, io, "/etc/ssl/certs/ca-certificates.crt"),
|
.serenity => return rescanWithPath(cb, gpa, io, now, "/etc/ssl/certs/ca-certificates.crt"),
|
||||||
.windows => return rescanWindows(cb, gpa),
|
.windows => return rescanWindows(cb, gpa, io, now),
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ const RescanMacError = @import("Bundle/macos.zig").RescanMacError;
|
|||||||
|
|
||||||
const RescanLinuxError = AddCertsFromFilePathError || AddCertsFromDirPathError;
|
const RescanLinuxError = AddCertsFromFilePathError || AddCertsFromDirPathError;
|
||||||
|
|
||||||
fn rescanLinux(cb: *Bundle, gpa: Allocator, io: Io) RescanLinuxError!void {
|
fn rescanLinux(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanLinuxError!void {
|
||||||
// Possible certificate files; stop after finding one.
|
// Possible certificate files; stop after finding one.
|
||||||
const cert_file_paths = [_][]const u8{
|
const cert_file_paths = [_][]const u8{
|
||||||
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
|
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
|
||||||
@ -114,7 +114,7 @@ fn rescanLinux(cb: *Bundle, gpa: Allocator, io: Io) RescanLinuxError!void {
|
|||||||
|
|
||||||
scan: {
|
scan: {
|
||||||
for (cert_file_paths) |cert_file_path| {
|
for (cert_file_paths) |cert_file_path| {
|
||||||
if (addCertsFromFilePathAbsolute(cb, gpa, io, cert_file_path)) |_| {
|
if (addCertsFromFilePathAbsolute(cb, gpa, io, now, cert_file_path)) |_| {
|
||||||
break :scan;
|
break :scan;
|
||||||
} else |err| switch (err) {
|
} else |err| switch (err) {
|
||||||
error.FileNotFound => continue,
|
error.FileNotFound => continue,
|
||||||
@ -123,7 +123,7 @@ fn rescanLinux(cb: *Bundle, gpa: Allocator, io: Io) RescanLinuxError!void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (cert_dir_paths) |cert_dir_path| {
|
for (cert_dir_paths) |cert_dir_path| {
|
||||||
addCertsFromDirPathAbsolute(cb, gpa, io, cert_dir_path) catch |err| switch (err) {
|
addCertsFromDirPathAbsolute(cb, gpa, io, now, cert_dir_path) catch |err| switch (err) {
|
||||||
error.FileNotFound => continue,
|
error.FileNotFound => continue,
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
@ -135,10 +135,10 @@ fn rescanLinux(cb: *Bundle, gpa: Allocator, io: Io) RescanLinuxError!void {
|
|||||||
|
|
||||||
const RescanWithPathError = AddCertsFromFilePathError;
|
const RescanWithPathError = AddCertsFromFilePathError;
|
||||||
|
|
||||||
fn rescanWithPath(cb: *Bundle, gpa: Allocator, io: Io, cert_file_path: []const u8) RescanWithPathError!void {
|
fn rescanWithPath(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp, cert_file_path: []const u8) RescanWithPathError!void {
|
||||||
cb.bytes.clearRetainingCapacity();
|
cb.bytes.clearRetainingCapacity();
|
||||||
cb.map.clearRetainingCapacity();
|
cb.map.clearRetainingCapacity();
|
||||||
try addCertsFromFilePathAbsolute(cb, gpa, io, cert_file_path);
|
try addCertsFromFilePathAbsolute(cb, gpa, io, now, cert_file_path);
|
||||||
cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len);
|
cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,17 +187,18 @@ pub fn addCertsFromDirPathAbsolute(
|
|||||||
cb: *Bundle,
|
cb: *Bundle,
|
||||||
gpa: Allocator,
|
gpa: Allocator,
|
||||||
io: Io,
|
io: Io,
|
||||||
|
now: Io.Timestamp,
|
||||||
abs_dir_path: []const u8,
|
abs_dir_path: []const u8,
|
||||||
) AddCertsFromDirPathError!void {
|
) AddCertsFromDirPathError!void {
|
||||||
assert(fs.path.isAbsolute(abs_dir_path));
|
assert(fs.path.isAbsolute(abs_dir_path));
|
||||||
var iterable_dir = try fs.openDirAbsolute(abs_dir_path, .{ .iterate = true });
|
var iterable_dir = try fs.openDirAbsolute(abs_dir_path, .{ .iterate = true });
|
||||||
defer iterable_dir.close();
|
defer iterable_dir.close();
|
||||||
return addCertsFromDir(cb, gpa, io, iterable_dir);
|
return addCertsFromDir(cb, gpa, io, now, iterable_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const AddCertsFromDirError = AddCertsFromFilePathError;
|
pub const AddCertsFromDirError = AddCertsFromFilePathError;
|
||||||
|
|
||||||
pub fn addCertsFromDir(cb: *Bundle, gpa: Allocator, io: Io, iterable_dir: fs.Dir) AddCertsFromDirError!void {
|
pub fn addCertsFromDir(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp, iterable_dir: fs.Dir) AddCertsFromDirError!void {
|
||||||
var it = iterable_dir.iterate();
|
var it = iterable_dir.iterate();
|
||||||
while (try it.next()) |entry| {
|
while (try it.next()) |entry| {
|
||||||
switch (entry.kind) {
|
switch (entry.kind) {
|
||||||
@ -205,7 +206,7 @@ pub fn addCertsFromDir(cb: *Bundle, gpa: Allocator, io: Io, iterable_dir: fs.Dir
|
|||||||
else => continue,
|
else => continue,
|
||||||
}
|
}
|
||||||
|
|
||||||
try addCertsFromFilePath(cb, gpa, io, iterable_dir.adaptToNewApi(), entry.name);
|
try addCertsFromFilePath(cb, gpa, io, now, iterable_dir.adaptToNewApi(), entry.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,9 +216,9 @@ pub fn addCertsFromFilePathAbsolute(
|
|||||||
cb: *Bundle,
|
cb: *Bundle,
|
||||||
gpa: Allocator,
|
gpa: Allocator,
|
||||||
io: Io,
|
io: Io,
|
||||||
|
now: Io.Timestamp,
|
||||||
abs_file_path: []const u8,
|
abs_file_path: []const u8,
|
||||||
) AddCertsFromFilePathError!void {
|
) AddCertsFromFilePathError!void {
|
||||||
const now = try Io.Clock.real.now(io);
|
|
||||||
var file = try fs.openFileAbsolute(abs_file_path, .{});
|
var file = try fs.openFileAbsolute(abs_file_path, .{});
|
||||||
defer file.close();
|
defer file.close();
|
||||||
var file_reader = file.reader(io, &.{});
|
var file_reader = file.reader(io, &.{});
|
||||||
@ -228,10 +229,10 @@ pub fn addCertsFromFilePath(
|
|||||||
cb: *Bundle,
|
cb: *Bundle,
|
||||||
gpa: Allocator,
|
gpa: Allocator,
|
||||||
io: Io,
|
io: Io,
|
||||||
|
now: Io.Timestamp,
|
||||||
dir: Io.Dir,
|
dir: Io.Dir,
|
||||||
sub_file_path: []const u8,
|
sub_file_path: []const u8,
|
||||||
) AddCertsFromFilePathError!void {
|
) AddCertsFromFilePathError!void {
|
||||||
const now = try Io.Clock.real.now(io);
|
|
||||||
var file = try dir.openFile(io, sub_file_path, .{});
|
var file = try dir.openFile(io, sub_file_path, .{});
|
||||||
defer file.close(io);
|
defer file.close(io);
|
||||||
var file_reader = file.reader(io, &.{});
|
var file_reader = file.reader(io, &.{});
|
||||||
@ -335,5 +336,7 @@ test "scan for OS-provided certificates" {
|
|||||||
var bundle: Bundle = .{};
|
var bundle: Bundle = .{};
|
||||||
defer bundle.deinit(gpa);
|
defer bundle.deinit(gpa);
|
||||||
|
|
||||||
try bundle.rescan(gpa, io);
|
const now = try Io.Clock.real.now(io);
|
||||||
|
|
||||||
|
try bundle.rescan(gpa, io, now);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const Io = std.Io;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const fs = std.fs;
|
const fs = std.fs;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
@ -7,7 +8,7 @@ const Bundle = @import("../Bundle.zig");
|
|||||||
|
|
||||||
pub const RescanMacError = Allocator.Error || fs.File.OpenError || fs.File.ReadError || fs.File.SeekError || Bundle.ParseCertError || error{EndOfStream};
|
pub const RescanMacError = Allocator.Error || fs.File.OpenError || fs.File.ReadError || fs.File.SeekError || Bundle.ParseCertError || error{EndOfStream};
|
||||||
|
|
||||||
pub fn rescanMac(cb: *Bundle, gpa: Allocator) RescanMacError!void {
|
pub fn rescanMac(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanMacError!void {
|
||||||
cb.bytes.clearRetainingCapacity();
|
cb.bytes.clearRetainingCapacity();
|
||||||
cb.map.clearRetainingCapacity();
|
cb.map.clearRetainingCapacity();
|
||||||
|
|
||||||
@ -16,6 +17,7 @@ pub fn rescanMac(cb: *Bundle, gpa: Allocator) RescanMacError!void {
|
|||||||
"/Library/Keychains/System.keychain",
|
"/Library/Keychains/System.keychain",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_ = io; // TODO migrate file system to use std.Io
|
||||||
for (keychain_paths) |keychain_path| {
|
for (keychain_paths) |keychain_path| {
|
||||||
const bytes = std.fs.cwd().readFileAlloc(keychain_path, gpa, .limited(std.math.maxInt(u32))) catch |err| switch (err) {
|
const bytes = std.fs.cwd().readFileAlloc(keychain_path, gpa, .limited(std.math.maxInt(u32))) catch |err| switch (err) {
|
||||||
error.StreamTooLong => return error.FileTooBig,
|
error.StreamTooLong => return error.FileTooBig,
|
||||||
@ -23,8 +25,8 @@ pub fn rescanMac(cb: *Bundle, gpa: Allocator) RescanMacError!void {
|
|||||||
};
|
};
|
||||||
defer gpa.free(bytes);
|
defer gpa.free(bytes);
|
||||||
|
|
||||||
var reader: std.Io.Reader = .fixed(bytes);
|
var reader: Io.Reader = .fixed(bytes);
|
||||||
scanReader(cb, gpa, &reader) catch |err| switch (err) {
|
scanReader(cb, gpa, &reader, now.toSeconds()) catch |err| switch (err) {
|
||||||
error.ReadFailed => unreachable, // prebuffered
|
error.ReadFailed => unreachable, // prebuffered
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
@ -33,7 +35,7 @@ pub fn rescanMac(cb: *Bundle, gpa: Allocator) RescanMacError!void {
|
|||||||
cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len);
|
cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scanReader(cb: *Bundle, gpa: Allocator, reader: *std.Io.Reader) !void {
|
fn scanReader(cb: *Bundle, gpa: Allocator, reader: *Io.Reader, now_sec: i64) !void {
|
||||||
const db_header = try reader.takeStruct(ApplDbHeader, .big);
|
const db_header = try reader.takeStruct(ApplDbHeader, .big);
|
||||||
assert(mem.eql(u8, &db_header.signature, "kych"));
|
assert(mem.eql(u8, &db_header.signature, "kych"));
|
||||||
|
|
||||||
@ -49,8 +51,6 @@ fn scanReader(cb: *Bundle, gpa: Allocator, reader: *std.Io.Reader) !void {
|
|||||||
table_list[table_idx] = try reader.takeInt(u32, .big);
|
table_list[table_idx] = try reader.takeInt(u32, .big);
|
||||||
}
|
}
|
||||||
|
|
||||||
const now_sec = std.time.timestamp();
|
|
||||||
|
|
||||||
for (table_list) |table_offset| {
|
for (table_list) |table_offset| {
|
||||||
reader.seek = db_header.schema_offset + table_offset;
|
reader.seek = db_header.schema_offset + table_offset;
|
||||||
|
|
||||||
|
|||||||
@ -117,11 +117,14 @@ pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) Error
|
|||||||
error.ReadFailed,
|
error.ReadFailed,
|
||||||
error.OutOfMemory,
|
error.OutOfMemory,
|
||||||
error.Unexpected,
|
error.Unexpected,
|
||||||
|
error.Canceled,
|
||||||
=> |e| return e,
|
=> |e| return e,
|
||||||
|
|
||||||
error.UnsupportedRegister,
|
error.UnsupportedRegister,
|
||||||
error.UnsupportedAddrSize,
|
error.UnsupportedAddrSize,
|
||||||
error.UnimplementedUserOpcode,
|
error.UnimplementedUserOpcode,
|
||||||
=> return error.UnsupportedDebugInfo,
|
=> return error.UnsupportedDebugInfo,
|
||||||
|
|
||||||
error.Overflow,
|
error.Overflow,
|
||||||
error.EndOfStream,
|
error.EndOfStream,
|
||||||
error.StreamTooLong,
|
error.StreamTooLong,
|
||||||
|
|||||||
@ -458,6 +458,8 @@ pub const SelfExePathError = error{
|
|||||||
/// On Windows, the volume does not contain a recognized file system. File
|
/// On Windows, the volume does not contain a recognized file system. File
|
||||||
/// system drivers might not be loaded, or the volume may be corrupt.
|
/// system drivers might not be loaded, or the volume may be corrupt.
|
||||||
UnrecognizedVolume,
|
UnrecognizedVolume,
|
||||||
|
|
||||||
|
Canceled,
|
||||||
} || posix.SysCtlError;
|
} || posix.SysCtlError;
|
||||||
|
|
||||||
/// `selfExePath` except allocates the result on the heap.
|
/// `selfExePath` except allocates the result on the heap.
|
||||||
|
|||||||
@ -35,9 +35,11 @@ tls_buffer_size: if (disable_tls) u0 else usize = if (disable_tls) 0 else std.cr
|
|||||||
/// traffic over connections created with this `Client`.
|
/// traffic over connections created with this `Client`.
|
||||||
ssl_key_log: ?*std.crypto.tls.Client.SslKeyLog = null,
|
ssl_key_log: ?*std.crypto.tls.Client.SslKeyLog = null,
|
||||||
|
|
||||||
/// When this is `true`, the next time this client performs an HTTPS request,
|
/// The time used to decide whether certificates are expired.
|
||||||
/// it will first rescan the system for root certificates.
|
///
|
||||||
next_https_rescan_certs: bool = true,
|
/// When this is `null`, the next time this client performs an HTTPS request,
|
||||||
|
/// it will first check the time and rescan the system for root certificates.
|
||||||
|
now: ?Io.Timestamp = null,
|
||||||
|
|
||||||
/// The pool of connections that can be reused (and currently in use).
|
/// The pool of connections that can be reused (and currently in use).
|
||||||
connection_pool: ConnectionPool = .{},
|
connection_pool: ConnectionPool = .{},
|
||||||
@ -295,6 +297,7 @@ pub const Connection = struct {
|
|||||||
client: std.crypto.tls.Client,
|
client: std.crypto.tls.Client,
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
|
|
||||||
|
/// Asserts that `client.now` is non-null.
|
||||||
fn create(
|
fn create(
|
||||||
client: *Client,
|
client: *Client,
|
||||||
remote_host: HostName,
|
remote_host: HostName,
|
||||||
@ -320,7 +323,6 @@ pub const Connection = struct {
|
|||||||
const tls: *Tls = @ptrCast(base);
|
const tls: *Tls = @ptrCast(base);
|
||||||
var random_buffer: [176]u8 = undefined;
|
var random_buffer: [176]u8 = undefined;
|
||||||
std.crypto.random.bytes(&random_buffer);
|
std.crypto.random.bytes(&random_buffer);
|
||||||
const now_ts = if (Io.Clock.real.now(io)) |ts| ts.toSeconds() else |err| return err;
|
|
||||||
tls.* = .{
|
tls.* = .{
|
||||||
.connection = .{
|
.connection = .{
|
||||||
.client = client,
|
.client = client,
|
||||||
@ -333,7 +335,7 @@ pub const Connection = struct {
|
|||||||
.closing = false,
|
.closing = false,
|
||||||
.protocol = .tls,
|
.protocol = .tls,
|
||||||
},
|
},
|
||||||
// TODO data race here on ca_bundle if the user sets next_https_rescan_certs to true
|
// TODO data race here on ca_bundle if the user sets `now` to null
|
||||||
.client = std.crypto.tls.Client.init(
|
.client = std.crypto.tls.Client.init(
|
||||||
&tls.connection.stream_reader.interface,
|
&tls.connection.stream_reader.interface,
|
||||||
&tls.connection.stream_writer.interface,
|
&tls.connection.stream_writer.interface,
|
||||||
@ -344,7 +346,7 @@ pub const Connection = struct {
|
|||||||
.read_buffer = tls_read_buffer,
|
.read_buffer = tls_read_buffer,
|
||||||
.write_buffer = socket_write_buffer,
|
.write_buffer = socket_write_buffer,
|
||||||
.entropy = &random_buffer,
|
.entropy = &random_buffer,
|
||||||
.realtime_now_seconds = now_ts,
|
.realtime_now_seconds = client.now.?.toSeconds(),
|
||||||
// This is appropriate for HTTPS because the HTTP headers contain
|
// This is appropriate for HTTPS because the HTTP headers contain
|
||||||
// the content length which is used to detect truncation attacks.
|
// the content length which is used to detect truncation attacks.
|
||||||
.allow_truncation_attacks = true,
|
.allow_truncation_attacks = true,
|
||||||
@ -1687,14 +1689,15 @@ pub fn request(
|
|||||||
|
|
||||||
if (protocol == .tls) {
|
if (protocol == .tls) {
|
||||||
if (disable_tls) unreachable;
|
if (disable_tls) unreachable;
|
||||||
if (@atomicLoad(bool, &client.next_https_rescan_certs, .acquire)) {
|
{
|
||||||
client.ca_bundle_mutex.lock();
|
client.ca_bundle_mutex.lock();
|
||||||
defer client.ca_bundle_mutex.unlock();
|
defer client.ca_bundle_mutex.unlock();
|
||||||
|
|
||||||
if (client.next_https_rescan_certs) {
|
if (client.now == null) {
|
||||||
client.ca_bundle.rescan(client.allocator, io) catch
|
const now = try Io.Clock.real.now(io);
|
||||||
|
client.now = now;
|
||||||
|
client.ca_bundle.rescan(client.allocator, io, now) catch
|
||||||
return error.CertificateBundleLoadFailure;
|
return error.CertificateBundleLoadFailure;
|
||||||
@atomicStore(bool, &client.next_https_rescan_certs, false, .release);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -688,7 +688,7 @@ pub const WebSocket = struct {
|
|||||||
pub const ReadSmallTextMessageError = error{
|
pub const ReadSmallTextMessageError = error{
|
||||||
ConnectionClose,
|
ConnectionClose,
|
||||||
UnexpectedOpCode,
|
UnexpectedOpCode,
|
||||||
MessageTooBig,
|
MessageOversize,
|
||||||
MissingMaskBit,
|
MissingMaskBit,
|
||||||
ReadFailed,
|
ReadFailed,
|
||||||
EndOfStream,
|
EndOfStream,
|
||||||
@ -717,15 +717,15 @@ pub const WebSocket = struct {
|
|||||||
_ => return error.UnexpectedOpCode,
|
_ => return error.UnexpectedOpCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!h0.fin) return error.MessageTooBig;
|
if (!h0.fin) return error.MessageOversize;
|
||||||
if (!h1.mask) return error.MissingMaskBit;
|
if (!h1.mask) return error.MissingMaskBit;
|
||||||
|
|
||||||
const len: usize = switch (h1.payload_len) {
|
const len: usize = switch (h1.payload_len) {
|
||||||
.len16 => try in.takeInt(u16, .big),
|
.len16 => try in.takeInt(u16, .big),
|
||||||
.len64 => std.math.cast(usize, try in.takeInt(u64, .big)) orelse return error.MessageTooBig,
|
.len64 => std.math.cast(usize, try in.takeInt(u64, .big)) orelse return error.MessageOversize,
|
||||||
else => @intFromEnum(h1.payload_len),
|
else => @intFromEnum(h1.payload_len),
|
||||||
};
|
};
|
||||||
if (len > in.buffer.len) return error.MessageTooBig;
|
if (len > in.buffer.len) return error.MessageOversize;
|
||||||
const mask: u32 = @bitCast((try in.takeArray(4)).*);
|
const mask: u32 = @bitCast((try in.takeArray(4)).*);
|
||||||
const payload = try in.take(len);
|
const payload = try in.take(len);
|
||||||
|
|
||||||
|
|||||||
@ -1653,7 +1653,7 @@ pub fn WSASocketW(
|
|||||||
const rc = ws2_32.WSASocketW(af, socket_type, protocol, protocolInfo, g, dwFlags);
|
const rc = ws2_32.WSASocketW(af, socket_type, protocol, protocolInfo, g, dwFlags);
|
||||||
if (rc == ws2_32.INVALID_SOCKET) {
|
if (rc == ws2_32.INVALID_SOCKET) {
|
||||||
switch (ws2_32.WSAGetLastError()) {
|
switch (ws2_32.WSAGetLastError()) {
|
||||||
.WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.WSAEAFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.WSAEMFILE => return error.ProcessFdQuotaExceeded,
|
.WSAEMFILE => return error.ProcessFdQuotaExceeded,
|
||||||
.WSAENOBUFS => return error.SystemResources,
|
.WSAENOBUFS => return error.SystemResources,
|
||||||
.WSAEPROTONOSUPPORT => return error.ProtocolNotSupported,
|
.WSAEPROTONOSUPPORT => return error.ProtocolNotSupported,
|
||||||
|
|||||||
@ -1205,7 +1205,7 @@ pub const WriteError = error{
|
|||||||
|
|
||||||
/// The socket type requires that message be sent atomically, and the size of the message
|
/// The socket type requires that message be sent atomically, and the size of the message
|
||||||
/// to be sent made this impossible. The message is not transmitted.
|
/// to be sent made this impossible. The message is not transmitted.
|
||||||
MessageTooBig,
|
MessageOversize,
|
||||||
} || UnexpectedError;
|
} || UnexpectedError;
|
||||||
|
|
||||||
/// Write to a file descriptor.
|
/// Write to a file descriptor.
|
||||||
@ -1287,7 +1287,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {
|
|||||||
.CONNRESET => return error.ConnectionResetByPeer,
|
.CONNRESET => return error.ConnectionResetByPeer,
|
||||||
.BUSY => return error.DeviceBusy,
|
.BUSY => return error.DeviceBusy,
|
||||||
.NXIO => return error.NoDevice,
|
.NXIO => return error.NoDevice,
|
||||||
.MSGSIZE => return error.MessageTooBig,
|
.MSGSIZE => return error.MessageOversize,
|
||||||
else => |err| return unexpectedErrno(err),
|
else => |err| return unexpectedErrno(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3487,7 +3487,7 @@ pub const SocketError = error{
|
|||||||
AccessDenied,
|
AccessDenied,
|
||||||
|
|
||||||
/// The implementation does not support the specified address family.
|
/// The implementation does not support the specified address family.
|
||||||
AddressFamilyNotSupported,
|
AddressFamilyUnsupported,
|
||||||
|
|
||||||
/// Unknown protocol, or protocol family not available.
|
/// Unknown protocol, or protocol family not available.
|
||||||
ProtocolFamilyNotAvailable,
|
ProtocolFamilyNotAvailable,
|
||||||
@ -3553,7 +3553,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
|
|||||||
return fd;
|
return fd;
|
||||||
},
|
},
|
||||||
.ACCES => return error.AccessDenied,
|
.ACCES => return error.AccessDenied,
|
||||||
.AFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.INVAL => return error.ProtocolFamilyNotAvailable,
|
.INVAL => return error.ProtocolFamilyNotAvailable,
|
||||||
.MFILE => return error.ProcessFdQuotaExceeded,
|
.MFILE => return error.ProcessFdQuotaExceeded,
|
||||||
.NFILE => return error.SystemFdQuotaExceeded,
|
.NFILE => return error.SystemFdQuotaExceeded,
|
||||||
@ -3593,7 +3593,7 @@ pub fn socketpair(domain: u32, socket_type: u32, protocol: u32) SocketError![2]s
|
|||||||
return socks;
|
return socks;
|
||||||
},
|
},
|
||||||
.ACCES => return error.AccessDenied,
|
.ACCES => return error.AccessDenied,
|
||||||
.AFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.INVAL => return error.ProtocolFamilyNotAvailable,
|
.INVAL => return error.ProtocolFamilyNotAvailable,
|
||||||
.MFILE => return error.ProcessFdQuotaExceeded,
|
.MFILE => return error.ProcessFdQuotaExceeded,
|
||||||
.NFILE => return error.SystemFdQuotaExceeded,
|
.NFILE => return error.SystemFdQuotaExceeded,
|
||||||
@ -3676,7 +3676,7 @@ pub const BindError = error{
|
|||||||
AddressNotAvailable,
|
AddressNotAvailable,
|
||||||
|
|
||||||
/// The address is not valid for the address family of socket.
|
/// The address is not valid for the address family of socket.
|
||||||
AddressFamilyNotSupported,
|
AddressFamilyUnsupported,
|
||||||
|
|
||||||
/// Too many symbolic links were encountered in resolving addr.
|
/// Too many symbolic links were encountered in resolving addr.
|
||||||
SymLinkLoop,
|
SymLinkLoop,
|
||||||
@ -3733,7 +3733,7 @@ pub fn bind(sock: socket_t, addr: *const sockaddr, len: socklen_t) BindError!voi
|
|||||||
.BADF => unreachable, // always a race condition if this error is returned
|
.BADF => unreachable, // always a race condition if this error is returned
|
||||||
.INVAL => unreachable, // invalid parameters
|
.INVAL => unreachable, // invalid parameters
|
||||||
.NOTSOCK => unreachable, // invalid `sockfd`
|
.NOTSOCK => unreachable, // invalid `sockfd`
|
||||||
.AFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.ADDRNOTAVAIL => return error.AddressNotAvailable,
|
.ADDRNOTAVAIL => return error.AddressNotAvailable,
|
||||||
.FAULT => unreachable, // invalid `addr` pointer
|
.FAULT => unreachable, // invalid `addr` pointer
|
||||||
.LOOP => return error.SymLinkLoop,
|
.LOOP => return error.SymLinkLoop,
|
||||||
@ -4192,7 +4192,7 @@ pub const ConnectError = error{
|
|||||||
AddressNotAvailable,
|
AddressNotAvailable,
|
||||||
|
|
||||||
/// The passed address didn't have the correct address family in its sa_family field.
|
/// The passed address didn't have the correct address family in its sa_family field.
|
||||||
AddressFamilyNotSupported,
|
AddressFamilyUnsupported,
|
||||||
|
|
||||||
/// Insufficient entries in the routing cache.
|
/// Insufficient entries in the routing cache.
|
||||||
SystemResources,
|
SystemResources,
|
||||||
@ -4247,7 +4247,7 @@ pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) Conne
|
|||||||
.WSAEWOULDBLOCK => return error.WouldBlock,
|
.WSAEWOULDBLOCK => return error.WouldBlock,
|
||||||
.WSAEACCES => unreachable,
|
.WSAEACCES => unreachable,
|
||||||
.WSAENOBUFS => return error.SystemResources,
|
.WSAENOBUFS => return error.SystemResources,
|
||||||
.WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.WSAEAFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
else => |err| return windows.unexpectedWSAError(err),
|
else => |err| return windows.unexpectedWSAError(err),
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -4260,7 +4260,7 @@ pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) Conne
|
|||||||
.PERM => return error.PermissionDenied,
|
.PERM => return error.PermissionDenied,
|
||||||
.ADDRINUSE => return error.AddressInUse,
|
.ADDRINUSE => return error.AddressInUse,
|
||||||
.ADDRNOTAVAIL => return error.AddressNotAvailable,
|
.ADDRNOTAVAIL => return error.AddressNotAvailable,
|
||||||
.AFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.AGAIN, .INPROGRESS => return error.WouldBlock,
|
.AGAIN, .INPROGRESS => return error.WouldBlock,
|
||||||
.ALREADY => return error.ConnectionPending,
|
.ALREADY => return error.ConnectionPending,
|
||||||
.BADF => unreachable, // sockfd is not a valid open file descriptor.
|
.BADF => unreachable, // sockfd is not a valid open file descriptor.
|
||||||
@ -4322,7 +4322,7 @@ pub fn getsockoptError(sockfd: fd_t) ConnectError!void {
|
|||||||
.PERM => return error.PermissionDenied,
|
.PERM => return error.PermissionDenied,
|
||||||
.ADDRINUSE => return error.AddressInUse,
|
.ADDRINUSE => return error.AddressInUse,
|
||||||
.ADDRNOTAVAIL => return error.AddressNotAvailable,
|
.ADDRNOTAVAIL => return error.AddressNotAvailable,
|
||||||
.AFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.AGAIN => return error.SystemResources,
|
.AGAIN => return error.SystemResources,
|
||||||
.ALREADY => return error.ConnectionPending,
|
.ALREADY => return error.ConnectionPending,
|
||||||
.BADF => unreachable, // sockfd is not a valid open file descriptor.
|
.BADF => unreachable, // sockfd is not a valid open file descriptor.
|
||||||
@ -6039,7 +6039,7 @@ pub const SendError = error{
|
|||||||
|
|
||||||
/// The socket type requires that message be sent atomically, and the size of the message
|
/// The socket type requires that message be sent atomically, and the size of the message
|
||||||
/// to be sent made this impossible. The message is not transmitted.
|
/// to be sent made this impossible. The message is not transmitted.
|
||||||
MessageTooBig,
|
MessageOversize,
|
||||||
|
|
||||||
/// The output queue for a network interface was full. This generally indicates that the
|
/// The output queue for a network interface was full. This generally indicates that the
|
||||||
/// interface has stopped sending, but may be caused by transient congestion. (Normally,
|
/// interface has stopped sending, but may be caused by transient congestion. (Normally,
|
||||||
@ -6066,7 +6066,7 @@ pub const SendError = error{
|
|||||||
|
|
||||||
pub const SendMsgError = SendError || error{
|
pub const SendMsgError = SendError || error{
|
||||||
/// The passed address didn't have the correct address family in its sa_family field.
|
/// The passed address didn't have the correct address family in its sa_family field.
|
||||||
AddressFamilyNotSupported,
|
AddressFamilyUnsupported,
|
||||||
|
|
||||||
/// Returned when socket is AF.UNIX and the given path has a symlink loop.
|
/// Returned when socket is AF.UNIX and the given path has a symlink loop.
|
||||||
SymLinkLoop,
|
SymLinkLoop,
|
||||||
@ -6098,10 +6098,10 @@ pub fn sendmsg(
|
|||||||
.WSAEACCES => return error.AccessDenied,
|
.WSAEACCES => return error.AccessDenied,
|
||||||
.WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
|
.WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
|
||||||
.WSAECONNRESET => return error.ConnectionResetByPeer,
|
.WSAECONNRESET => return error.ConnectionResetByPeer,
|
||||||
.WSAEMSGSIZE => return error.MessageTooBig,
|
.WSAEMSGSIZE => return error.MessageOversize,
|
||||||
.WSAENOBUFS => return error.SystemResources,
|
.WSAENOBUFS => return error.SystemResources,
|
||||||
.WSAENOTSOCK => return error.FileDescriptorNotASocket,
|
.WSAENOTSOCK => return error.FileDescriptorNotASocket,
|
||||||
.WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.WSAEAFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.WSAEDESTADDRREQ => unreachable, // A destination address is required.
|
.WSAEDESTADDRREQ => unreachable, // A destination address is required.
|
||||||
.WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
|
.WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
|
||||||
.WSAEHOSTUNREACH => return error.NetworkUnreachable,
|
.WSAEHOSTUNREACH => return error.NetworkUnreachable,
|
||||||
@ -6133,13 +6133,13 @@ pub fn sendmsg(
|
|||||||
.INTR => continue,
|
.INTR => continue,
|
||||||
.INVAL => unreachable, // Invalid argument passed.
|
.INVAL => unreachable, // Invalid argument passed.
|
||||||
.ISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
|
.ISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
|
||||||
.MSGSIZE => return error.MessageTooBig,
|
.MSGSIZE => return error.MessageOversize,
|
||||||
.NOBUFS => return error.SystemResources,
|
.NOBUFS => return error.SystemResources,
|
||||||
.NOMEM => return error.SystemResources,
|
.NOMEM => return error.SystemResources,
|
||||||
.NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
|
.NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
|
||||||
.OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
|
.OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
|
||||||
.PIPE => return error.BrokenPipe,
|
.PIPE => return error.BrokenPipe,
|
||||||
.AFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.LOOP => return error.SymLinkLoop,
|
.LOOP => return error.SymLinkLoop,
|
||||||
.NAMETOOLONG => return error.NameTooLong,
|
.NAMETOOLONG => return error.NameTooLong,
|
||||||
.NOENT => return error.FileNotFound,
|
.NOENT => return error.FileNotFound,
|
||||||
@ -6178,7 +6178,7 @@ pub const SendToError = SendMsgError || error{
|
|||||||
/// Otherwise, the address of the target is given by `dest_addr` with `addrlen` specifying its size.
|
/// Otherwise, the address of the target is given by `dest_addr` with `addrlen` specifying its size.
|
||||||
///
|
///
|
||||||
/// If the message is too long to pass atomically through the underlying protocol,
|
/// If the message is too long to pass atomically through the underlying protocol,
|
||||||
/// `SendError.MessageTooBig` is returned, and the message is not transmitted.
|
/// `SendError.MessageOversize` is returned, and the message is not transmitted.
|
||||||
///
|
///
|
||||||
/// There is no indication of failure to deliver.
|
/// There is no indication of failure to deliver.
|
||||||
///
|
///
|
||||||
@ -6201,10 +6201,10 @@ pub fn sendto(
|
|||||||
.WSAEACCES => return error.AccessDenied,
|
.WSAEACCES => return error.AccessDenied,
|
||||||
.WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
|
.WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
|
||||||
.WSAECONNRESET => return error.ConnectionResetByPeer,
|
.WSAECONNRESET => return error.ConnectionResetByPeer,
|
||||||
.WSAEMSGSIZE => return error.MessageTooBig,
|
.WSAEMSGSIZE => return error.MessageOversize,
|
||||||
.WSAENOBUFS => return error.SystemResources,
|
.WSAENOBUFS => return error.SystemResources,
|
||||||
.WSAENOTSOCK => return error.FileDescriptorNotASocket,
|
.WSAENOTSOCK => return error.FileDescriptorNotASocket,
|
||||||
.WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.WSAEAFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.WSAEDESTADDRREQ => unreachable, // A destination address is required.
|
.WSAEDESTADDRREQ => unreachable, // A destination address is required.
|
||||||
.WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
|
.WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
|
||||||
.WSAEHOSTUNREACH => return error.NetworkUnreachable,
|
.WSAEHOSTUNREACH => return error.NetworkUnreachable,
|
||||||
@ -6238,13 +6238,13 @@ pub fn sendto(
|
|||||||
.INTR => continue,
|
.INTR => continue,
|
||||||
.INVAL => return error.UnreachableAddress,
|
.INVAL => return error.UnreachableAddress,
|
||||||
.ISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
|
.ISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
|
||||||
.MSGSIZE => return error.MessageTooBig,
|
.MSGSIZE => return error.MessageOversize,
|
||||||
.NOBUFS => return error.SystemResources,
|
.NOBUFS => return error.SystemResources,
|
||||||
.NOMEM => return error.SystemResources,
|
.NOMEM => return error.SystemResources,
|
||||||
.NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
|
.NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
|
||||||
.OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
|
.OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
|
||||||
.PIPE => return error.BrokenPipe,
|
.PIPE => return error.BrokenPipe,
|
||||||
.AFNOSUPPORT => return error.AddressFamilyNotSupported,
|
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.LOOP => return error.SymLinkLoop,
|
.LOOP => return error.SymLinkLoop,
|
||||||
.NAMETOOLONG => return error.NameTooLong,
|
.NAMETOOLONG => return error.NameTooLong,
|
||||||
.NOENT => return error.FileNotFound,
|
.NOENT => return error.FileNotFound,
|
||||||
@ -6284,7 +6284,7 @@ pub fn send(
|
|||||||
flags: u32,
|
flags: u32,
|
||||||
) SendError!usize {
|
) SendError!usize {
|
||||||
return sendto(sockfd, buf, flags, null, 0) catch |err| switch (err) {
|
return sendto(sockfd, buf, flags, null, 0) catch |err| switch (err) {
|
||||||
error.AddressFamilyNotSupported => unreachable,
|
error.AddressFamilyUnsupported => unreachable,
|
||||||
error.SymLinkLoop => unreachable,
|
error.SymLinkLoop => unreachable,
|
||||||
error.NameTooLong => unreachable,
|
error.NameTooLong => unreachable,
|
||||||
error.FileNotFound => unreachable,
|
error.FileNotFound => unreachable,
|
||||||
@ -6471,7 +6471,7 @@ pub const RecvFromError = error{
|
|||||||
SocketNotBound,
|
SocketNotBound,
|
||||||
|
|
||||||
/// The UDP message was too big for the buffer and part of it has been discarded
|
/// The UDP message was too big for the buffer and part of it has been discarded
|
||||||
MessageTooBig,
|
MessageOversize,
|
||||||
|
|
||||||
/// The network subsystem has failed.
|
/// The network subsystem has failed.
|
||||||
NetworkDown,
|
NetworkDown,
|
||||||
@ -6504,7 +6504,7 @@ pub fn recvfrom(
|
|||||||
.WSANOTINITIALISED => unreachable,
|
.WSANOTINITIALISED => unreachable,
|
||||||
.WSAECONNRESET => return error.ConnectionResetByPeer,
|
.WSAECONNRESET => return error.ConnectionResetByPeer,
|
||||||
.WSAEINVAL => return error.SocketNotBound,
|
.WSAEINVAL => return error.SocketNotBound,
|
||||||
.WSAEMSGSIZE => return error.MessageTooBig,
|
.WSAEMSGSIZE => return error.MessageOversize,
|
||||||
.WSAENETDOWN => return error.NetworkDown,
|
.WSAENETDOWN => return error.NetworkDown,
|
||||||
.WSAENOTCONN => return error.SocketUnconnected,
|
.WSAENOTCONN => return error.SocketUnconnected,
|
||||||
.WSAEWOULDBLOCK => return error.WouldBlock,
|
.WSAEWOULDBLOCK => return error.WouldBlock,
|
||||||
@ -6575,7 +6575,7 @@ pub fn recvmsg(
|
|||||||
.NOMEM => return error.SystemResources,
|
.NOMEM => return error.SystemResources,
|
||||||
.NOTCONN => return error.SocketUnconnected,
|
.NOTCONN => return error.SocketUnconnected,
|
||||||
.NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
|
.NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
|
||||||
.MSGSIZE => return error.MessageTooBig,
|
.MSGSIZE => return error.MessageOversize,
|
||||||
.PIPE => return error.BrokenPipe,
|
.PIPE => return error.BrokenPipe,
|
||||||
.OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
|
.OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
|
||||||
.CONNRESET => return error.ConnectionResetByPeer,
|
.CONNRESET => return error.ConnectionResetByPeer,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user