| ... | ... | @@ -1608,139 +1608,6 @@ pub fn ppoll(fds: []pollfd, timeout: ?*const timespec, mask: ?*const sigset_t) P |
| 1608 | 1608 | } |
| 1609 | 1609 | } |
| 1610 | 1610 | |
| 1611 | | pub const RecvFromError = error{ |
| 1612 | | /// The socket is marked nonblocking and the requested operation would block, and |
| 1613 | | /// there is no global event loop configured. |
| 1614 | | WouldBlock, |
| 1615 | | |
| 1616 | | /// A remote host refused to allow the network connection, typically because it is not |
| 1617 | | /// running the requested service. |
| 1618 | | ConnectionRefused, |
| 1619 | | |
| 1620 | | /// Could not allocate kernel memory. |
| 1621 | | SystemResources, |
| 1622 | | |
| 1623 | | ConnectionResetByPeer, |
| 1624 | | Timeout, |
| 1625 | | |
| 1626 | | /// The socket has not been bound. |
| 1627 | | SocketNotBound, |
| 1628 | | |
| 1629 | | /// The UDP message was too big for the buffer and part of it has been discarded |
| 1630 | | MessageOversize, |
| 1631 | | |
| 1632 | | /// The network subsystem has failed. |
| 1633 | | NetworkDown, |
| 1634 | | |
| 1635 | | /// The socket is not connected (connection-oriented sockets only). |
| 1636 | | SocketUnconnected, |
| 1637 | | |
| 1638 | | /// The other end closed the socket unexpectedly or a read is executed on a shut down socket |
| 1639 | | BrokenPipe, |
| 1640 | | } || UnexpectedError; |
| 1641 | | |
| 1642 | | pub fn recv(sock: socket_t, buf: []u8, flags: u32) RecvFromError!usize { |
| 1643 | | return recvfrom(sock, buf, flags, null, null); |
| 1644 | | } |
| 1645 | | |
| 1646 | | /// If `sockfd` is opened in non blocking mode, the function will |
| 1647 | | /// return error.WouldBlock when EAGAIN is received. |
| 1648 | | pub fn recvfrom( |
| 1649 | | sockfd: socket_t, |
| 1650 | | buf: []u8, |
| 1651 | | flags: u32, |
| 1652 | | src_addr: ?*sockaddr, |
| 1653 | | addrlen: ?*socklen_t, |
| 1654 | | ) RecvFromError!usize { |
| 1655 | | while (true) { |
| 1656 | | const rc = system.recvfrom(sockfd, buf.ptr, buf.len, flags, src_addr, addrlen); |
| 1657 | | if (native_os == .windows) { |
| 1658 | | if (rc == windows.ws2_32.SOCKET_ERROR) { |
| 1659 | | switch (windows.ws2_32.WSAGetLastError()) { |
| 1660 | | .NOTINITIALISED => unreachable, |
| 1661 | | .ECONNRESET => return error.ConnectionResetByPeer, |
| 1662 | | .EINVAL => return error.SocketNotBound, |
| 1663 | | .EMSGSIZE => return error.MessageOversize, |
| 1664 | | .ENETDOWN => return error.NetworkDown, |
| 1665 | | .ENOTCONN => return error.SocketUnconnected, |
| 1666 | | .EWOULDBLOCK => return error.WouldBlock, |
| 1667 | | .ETIMEDOUT => return error.Timeout, |
| 1668 | | // TODO: handle more errors |
| 1669 | | else => |err| return windows.unexpectedWSAError(err), |
| 1670 | | } |
| 1671 | | } else { |
| 1672 | | return @intCast(rc); |
| 1673 | | } |
| 1674 | | } else { |
| 1675 | | switch (errno(rc)) { |
| 1676 | | .SUCCESS => return @intCast(rc), |
| 1677 | | .BADF => unreachable, // always a race condition |
| 1678 | | .FAULT => unreachable, |
| 1679 | | .INVAL => unreachable, |
| 1680 | | .NOTCONN => return error.SocketUnconnected, |
| 1681 | | .NOTSOCK => unreachable, |
| 1682 | | .INTR => continue, |
| 1683 | | .AGAIN => return error.WouldBlock, |
| 1684 | | .NOMEM => return error.SystemResources, |
| 1685 | | .CONNREFUSED => return error.ConnectionRefused, |
| 1686 | | .CONNRESET => return error.ConnectionResetByPeer, |
| 1687 | | .TIMEDOUT => return error.Timeout, |
| 1688 | | .PIPE => return error.BrokenPipe, |
| 1689 | | else => |err| return unexpectedErrno(err), |
| 1690 | | } |
| 1691 | | } |
| 1692 | | } |
| 1693 | | } |
| 1694 | | |
| 1695 | | pub const RecvMsgError = RecvFromError || error{ |
| 1696 | | /// Reception of SCM_RIGHTS fds via ancillary data in msg.control would |
| 1697 | | /// exceed some system limit (generally this is retryable by trying to |
| 1698 | | /// receive fewer fds or closing some existing fds) |
| 1699 | | SystemFdQuotaExceeded, |
| 1700 | | |
| 1701 | | /// Reception of SCM_RIGHTS fds via ancillary data in msg.control would |
| 1702 | | /// exceed some process limit (generally this is retryable by trying to |
| 1703 | | /// receive fewer fds, closing some existing fds, or changing the ulimit) |
| 1704 | | ProcessFdQuotaExceeded, |
| 1705 | | }; |
| 1706 | | |
| 1707 | | /// If `sockfd` is opened in non blocking mode, the function will |
| 1708 | | /// return error.WouldBlock when EAGAIN is received. |
| 1709 | | pub fn recvmsg( |
| 1710 | | /// The file descriptor of the sending socket. |
| 1711 | | sockfd: socket_t, |
| 1712 | | /// Message header and iovecs |
| 1713 | | msg: *msghdr, |
| 1714 | | flags: u32, |
| 1715 | | ) RecvMsgError!usize { |
| 1716 | | if (@TypeOf(system.recvmsg) == void) |
| 1717 | | @compileError("recvmsg() not supported on this OS"); |
| 1718 | | while (true) { |
| 1719 | | const rc = system.recvmsg(sockfd, msg, flags); |
| 1720 | | switch (errno(rc)) { |
| 1721 | | .SUCCESS => return @intCast(rc), |
| 1722 | | .AGAIN => return error.WouldBlock, |
| 1723 | | .BADF => unreachable, // always a race condition |
| 1724 | | .NFILE => return error.SystemFdQuotaExceeded, |
| 1725 | | .MFILE => return error.ProcessFdQuotaExceeded, |
| 1726 | | .INTR => continue, |
| 1727 | | .FAULT => unreachable, // An invalid user space address was specified for an argument. |
| 1728 | | .INVAL => unreachable, // Invalid argument passed. |
| 1729 | | .ISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified |
| 1730 | | .NOBUFS => return error.SystemResources, |
| 1731 | | .NOMEM => return error.SystemResources, |
| 1732 | | .NOTCONN => return error.SocketUnconnected, |
| 1733 | | .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket. |
| 1734 | | .MSGSIZE => return error.MessageOversize, |
| 1735 | | .PIPE => return error.BrokenPipe, |
| 1736 | | .OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type. |
| 1737 | | .CONNRESET => return error.ConnectionResetByPeer, |
| 1738 | | .NETDOWN => return error.NetworkDown, |
| 1739 | | else => |err| return unexpectedErrno(err), |
| 1740 | | } |
| 1741 | | } |
| 1742 | | } |
| 1743 | | |
| 1744 | 1611 | pub const SetSockOptError = error{ |
| 1745 | 1612 | /// The socket is already connected, and a specified option cannot be set while the socket is connected. |
| 1746 | 1613 | AlreadyConnected, |