| ... | ... | @@ -1684,6 +1684,7 @@ pub fn io(t: *Threaded) Io { |
| 1684 | 1684 | .windows => netConnectUnixWindows, |
| 1685 | 1685 | else => netConnectUnixPosix, |
| 1686 | 1686 | }, |
| 1687 | .netSocketCreatePair = netSocketCreatePair, |
| 1687 | 1688 | .netClose = netClose, |
| 1688 | 1689 | .netShutdown = switch (native_os) { |
| 1689 | 1690 | .windows => netShutdownWindows, |
| ... | ... | @@ -1824,6 +1825,7 @@ pub fn ioBasic(t: *Threaded) Io { |
| 1824 | 1825 | .netAccept = netAcceptUnavailable, |
| 1825 | 1826 | .netBindIp = netBindIpUnavailable, |
| 1826 | 1827 | .netConnectIp = netConnectIpUnavailable, |
| 1828 | .netSocketCreatePair = netSocketCreatePairUnavailable, |
| 1827 | 1829 | .netConnectUnix = netConnectUnixUnavailable, |
| 1828 | 1830 | .netClose = netCloseUnavailable, |
| 1829 | 1831 | .netShutdown = netShutdownUnavailable, |
| ... | ... | @@ -10612,43 +10614,36 @@ fn posixConnect( |
| 10612 | 10614 | addr_len: posix.socklen_t, |
| 10613 | 10615 | ) !void { |
| 10614 | 10616 | const syscall: Syscall = try .start(); |
| 10615 | | while (true) { |
| 10616 | | switch (posix.errno(posix.system.connect(socket_fd, addr, addr_len))) { |
| 10617 | | .SUCCESS => { |
| 10618 | | syscall.finish(); |
| 10619 | | return; |
| 10620 | | }, |
| 10621 | | .INTR => { |
| 10622 | | try syscall.checkCancel(); |
| 10623 | | continue; |
| 10624 | | }, |
| 10625 | | else => |e| { |
| 10626 | | syscall.finish(); |
| 10627 | | switch (e) { |
| 10628 | | .ADDRNOTAVAIL => return error.AddressUnavailable, |
| 10629 | | .AFNOSUPPORT => return error.AddressFamilyUnsupported, |
| 10630 | | .AGAIN, .INPROGRESS => return error.WouldBlock, |
| 10631 | | .ALREADY => return error.ConnectionPending, |
| 10632 | | .BADF => |err| return errnoBug(err), // File descriptor used after closed. |
| 10633 | | .CONNREFUSED => return error.ConnectionRefused, |
| 10634 | | .CONNRESET => return error.ConnectionResetByPeer, |
| 10635 | | .FAULT => |err| return errnoBug(err), |
| 10636 | | .ISCONN => |err| return errnoBug(err), |
| 10637 | | .HOSTUNREACH => return error.HostUnreachable, |
| 10638 | | .NETUNREACH => return error.NetworkUnreachable, |
| 10639 | | .NOTSOCK => |err| return errnoBug(err), |
| 10640 | | .PROTOTYPE => |err| return errnoBug(err), |
| 10641 | | .TIMEDOUT => return error.Timeout, |
| 10642 | | .CONNABORTED => |err| return errnoBug(err), |
| 10643 | | .ACCES => return error.AccessDenied, |
| 10644 | | .PERM => |err| return errnoBug(err), |
| 10645 | | .NOENT => |err| return errnoBug(err), |
| 10646 | | .NETDOWN => return error.NetworkDown, |
| 10647 | | else => |err| return posix.unexpectedErrno(err), |
| 10648 | | } |
| 10649 | | }, |
| 10650 | | } |
| 10651 | | } |
| 10617 | while (true) switch (posix.errno(posix.system.connect(socket_fd, addr, addr_len))) { |
| 10618 | .SUCCESS => { |
| 10619 | syscall.finish(); |
| 10620 | return; |
| 10621 | }, |
| 10622 | .INTR => { |
| 10623 | try syscall.checkCancel(); |
| 10624 | continue; |
| 10625 | }, |
| 10626 | .ADDRNOTAVAIL => return syscall.fail(error.AddressUnavailable), |
| 10627 | .AFNOSUPPORT => return syscall.fail(error.AddressFamilyUnsupported), |
| 10628 | .AGAIN, .INPROGRESS => return syscall.fail(error.WouldBlock), |
| 10629 | .ALREADY => return syscall.fail(error.ConnectionPending), |
| 10630 | .CONNREFUSED => return syscall.fail(error.ConnectionRefused), |
| 10631 | .CONNRESET => return syscall.fail(error.ConnectionResetByPeer), |
| 10632 | .HOSTUNREACH => return syscall.fail(error.HostUnreachable), |
| 10633 | .NETUNREACH => return syscall.fail(error.NetworkUnreachable), |
| 10634 | .TIMEDOUT => return syscall.fail(error.Timeout), |
| 10635 | .ACCES => return syscall.fail(error.AccessDenied), |
| 10636 | .NETDOWN => return syscall.fail(error.NetworkDown), |
| 10637 | .BADF => |err| return syscall.errnoBug(err), // File descriptor used after closed. |
| 10638 | .CONNABORTED => |err| return syscall.errnoBug(err), |
| 10639 | .FAULT => |err| return syscall.errnoBug(err), |
| 10640 | .ISCONN => |err| return syscall.errnoBug(err), |
| 10641 | .NOENT => |err| return syscall.errnoBug(err), |
| 10642 | .NOTSOCK => |err| return syscall.errnoBug(err), |
| 10643 | .PERM => |err| return syscall.errnoBug(err), |
| 10644 | .PROTOTYPE => |err| return syscall.errnoBug(err), |
| 10645 | else => |err| return syscall.unexpectedErrno(err), |
| 10646 | }; |
| 10652 | 10647 | } |
| 10653 | 10648 | |
| 10654 | 10649 | fn posixConnectUnix( |
| ... | ... | @@ -11106,46 +11101,31 @@ fn openSocketPosix( |
| 11106 | 11101 | }!posix.socket_t { |
| 11107 | 11102 | const mode = posixSocketMode(options.mode); |
| 11108 | 11103 | const protocol = posixProtocol(options.protocol); |
| 11104 | const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC; |
| 11109 | 11105 | const syscall: Syscall = try .start(); |
| 11110 | 11106 | const socket_fd = while (true) { |
| 11111 | | const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC; |
| 11112 | | const socket_rc = posix.system.socket(family, flags, protocol); |
| 11113 | | switch (posix.errno(socket_rc)) { |
| 11107 | const rc = posix.system.socket(family, flags, protocol); |
| 11108 | switch (posix.errno(rc)) { |
| 11114 | 11109 | .SUCCESS => { |
| 11115 | | const fd: posix.fd_t = @intCast(socket_rc); |
| 11116 | | errdefer posix.close(fd); |
| 11117 | | if (socket_flags_unsupported) while (true) { |
| 11118 | | try syscall.checkCancel(); |
| 11119 | | switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) { |
| 11120 | | .SUCCESS => break, |
| 11121 | | .INTR => continue, |
| 11122 | | else => |err| { |
| 11123 | | syscall.finish(); |
| 11124 | | return posix.unexpectedErrno(err); |
| 11125 | | }, |
| 11126 | | } |
| 11127 | | }; |
| 11128 | 11110 | syscall.finish(); |
| 11111 | const fd: posix.fd_t = @intCast(rc); |
| 11112 | errdefer posix.close(fd); |
| 11113 | if (socket_flags_unsupported) try setCloexec(fd); |
| 11129 | 11114 | break fd; |
| 11130 | 11115 | }, |
| 11131 | 11116 | .INTR => { |
| 11132 | 11117 | try syscall.checkCancel(); |
| 11133 | 11118 | continue; |
| 11134 | 11119 | }, |
| 11135 | | else => |e| { |
| 11136 | | syscall.finish(); |
| 11137 | | switch (e) { |
| 11138 | | .AFNOSUPPORT => return error.AddressFamilyUnsupported, |
| 11139 | | .INVAL => return error.ProtocolUnsupportedBySystem, |
| 11140 | | .MFILE => return error.ProcessFdQuotaExceeded, |
| 11141 | | .NFILE => return error.SystemFdQuotaExceeded, |
| 11142 | | .NOBUFS => return error.SystemResources, |
| 11143 | | .NOMEM => return error.SystemResources, |
| 11144 | | .PROTONOSUPPORT => return error.ProtocolUnsupportedByAddressFamily, |
| 11145 | | .PROTOTYPE => return error.SocketModeUnsupported, |
| 11146 | | else => |err| return posix.unexpectedErrno(err), |
| 11147 | | } |
| 11148 | | }, |
| 11120 | .AFNOSUPPORT => return syscall.fail(error.AddressFamilyUnsupported), |
| 11121 | .INVAL => return syscall.fail(error.ProtocolUnsupportedBySystem), |
| 11122 | .MFILE => return syscall.fail(error.ProcessFdQuotaExceeded), |
| 11123 | .NFILE => return syscall.fail(error.SystemFdQuotaExceeded), |
| 11124 | .NOBUFS => return syscall.fail(error.SystemResources), |
| 11125 | .NOMEM => return syscall.fail(error.SystemResources), |
| 11126 | .PROTONOSUPPORT => return syscall.fail(error.ProtocolUnsupportedByAddressFamily), |
| 11127 | .PROTOTYPE => return syscall.fail(error.SocketModeUnsupported), |
| 11128 | else => |err| return syscall.unexpectedErrno(err), |
| 11149 | 11129 | } |
| 11150 | 11130 | }; |
| 11151 | 11131 | errdefer posix.close(socket_fd); |
| ... | ... | @@ -11158,6 +11138,84 @@ fn openSocketPosix( |
| 11158 | 11138 | return socket_fd; |
| 11159 | 11139 | } |
| 11160 | 11140 | |
| 11141 | fn setCloexec(fd: posix.fd_t) error{ Canceled, Unexpected }!void { |
| 11142 | const syscall: Syscall = try .start(); |
| 11143 | while (true) switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) { |
| 11144 | .SUCCESS => return syscall.finish(), |
| 11145 | .INTR => { |
| 11146 | try syscall.checkCancel(); |
| 11147 | continue; |
| 11148 | }, |
| 11149 | else => |err| return syscall.unexpectedErrno(err), |
| 11150 | }; |
| 11151 | } |
| 11152 | |
| 11153 | fn netSocketCreatePair( |
| 11154 | userdata: ?*anyopaque, |
| 11155 | options: net.Socket.CreatePairOptions, |
| 11156 | ) net.Socket.CreatePairError![2]net.Socket { |
| 11157 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 11158 | _ = t; |
| 11159 | if (!have_networking) return error.OperationUnsupported; |
| 11160 | if (@TypeOf(posix.system.socketpair) == void) return error.OperationUnsupported; |
| 11161 | if (native_os == .haiku) @panic("TODO"); |
| 11162 | |
| 11163 | const family: posix.sa_family_t = switch (options.family) { |
| 11164 | .ip4 => posix.AF.INET, |
| 11165 | .ip6 => posix.AF.INET6, |
| 11166 | }; |
| 11167 | const mode = posixSocketMode(options.mode); |
| 11168 | const protocol = posixProtocol(options.protocol); |
| 11169 | const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC; |
| 11170 | |
| 11171 | var sockets: [2]posix.socket_t = undefined; |
| 11172 | const syscall: Syscall = try .start(); |
| 11173 | while (true) switch (posix.errno(posix.system.socketpair(family, flags, protocol, &sockets))) { |
| 11174 | .SUCCESS => { |
| 11175 | syscall.finish(); |
| 11176 | errdefer { |
| 11177 | posix.close(sockets[0]); |
| 11178 | posix.close(sockets[1]); |
| 11179 | } |
| 11180 | if (socket_flags_unsupported) { |
| 11181 | try setCloexec(sockets[0]); |
| 11182 | try setCloexec(sockets[1]); |
| 11183 | } |
| 11184 | var storages: [2]PosixAddress = undefined; |
| 11185 | var addr_lens: [2]posix.socklen_t = .{ @sizeOf(PosixAddress), @sizeOf(PosixAddress) }; |
| 11186 | try posixGetSockName(sockets[0], &storages[0].any, &addr_lens[0]); |
| 11187 | try posixGetSockName(sockets[1], &storages[1].any, &addr_lens[1]); |
| 11188 | return .{ |
| 11189 | .{ .handle = sockets[0], .address = addressFromPosix(&storages[0]) }, |
| 11190 | .{ .handle = sockets[1], .address = addressFromPosix(&storages[1]) }, |
| 11191 | }; |
| 11192 | }, |
| 11193 | .INTR => { |
| 11194 | try syscall.checkCancel(); |
| 11195 | continue; |
| 11196 | }, |
| 11197 | .ACCES => return syscall.fail(error.AccessDenied), |
| 11198 | .AFNOSUPPORT => return syscall.fail(error.AddressFamilyUnsupported), |
| 11199 | .INVAL => return syscall.fail(error.ProtocolUnsupportedBySystem), |
| 11200 | .MFILE => return syscall.fail(error.ProcessFdQuotaExceeded), |
| 11201 | .NFILE => return syscall.fail(error.SystemFdQuotaExceeded), |
| 11202 | .NOBUFS => return syscall.fail(error.SystemResources), |
| 11203 | .NOMEM => return syscall.fail(error.SystemResources), |
| 11204 | .PROTONOSUPPORT => return syscall.fail(error.ProtocolUnsupportedByAddressFamily), |
| 11205 | .PROTOTYPE => return syscall.fail(error.SocketModeUnsupported), |
| 11206 | else => |err| return syscall.unexpectedErrno(err), |
| 11207 | }; |
| 11208 | } |
| 11209 | |
| 11210 | fn netSocketCreatePairUnavailable( |
| 11211 | userdata: ?*anyopaque, |
| 11212 | options: net.Socket.CreatePairOptions, |
| 11213 | ) net.Socket.CreatePairError![2]net.Socket { |
| 11214 | _ = userdata; |
| 11215 | _ = options; |
| 11216 | return error.OperationUnsupported; |
| 11217 | } |
| 11218 | |
| 11161 | 11219 | fn openSocketWsa( |
| 11162 | 11220 | t: *Threaded, |
| 11163 | 11221 | family: posix.sa_family_t, |
| ... | ... | @@ -11216,20 +11274,10 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve |
| 11216 | 11274 | posix.system.accept(listen_fd, &storage.any, &addr_len); |
| 11217 | 11275 | switch (posix.errno(rc)) { |
| 11218 | 11276 | .SUCCESS => { |
| 11277 | syscall.finish(); |
| 11219 | 11278 | const fd: posix.fd_t = @intCast(rc); |
| 11220 | 11279 | errdefer posix.close(fd); |
| 11221 | | if (!have_accept4) while (true) { |
| 11222 | | try syscall.checkCancel(); |
| 11223 | | switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) { |
| 11224 | | .SUCCESS => break, |
| 11225 | | .INTR => continue, |
| 11226 | | else => |err| { |
| 11227 | | syscall.finish(); |
| 11228 | | return posix.unexpectedErrno(err); |
| 11229 | | }, |
| 11230 | | } |
| 11231 | | }; |
| 11232 | | syscall.finish(); |
| 11280 | if (!have_accept4) try setCloexec(fd); |
| 11233 | 11281 | break fd; |
| 11234 | 11282 | }, |
| 11235 | 11283 | .INTR => { |