| ... | @@ -4774,9 +4774,34 @@ pub const SendError = error{ | ... | @@ -4774,9 +4774,34 @@ pub const SendError = error{ |
| 4774 | BrokenPipe, | 4774 | BrokenPipe, |
| 4775 | | 4775 | |
| 4776 | FileDescriptorNotASocket, | 4776 | FileDescriptorNotASocket, |
| 4777 | AddressFamilyNotSupported, | | |
| 4778 | } || UnexpectedError; | 4777 | } || UnexpectedError; |
| 4779 | | 4778 | |
| | 4779 | pub const SendToError = SendError || error{ |
| | 4780 | /// The passed address didn't have the correct address family in its sa_family field. |
| | 4781 | AddressFamilyNotSupported, |
| | 4782 | |
| | 4783 | /// Returned when socket is AF_UNIX and the given path has a symlink loop. |
| | 4784 | SymLinkLoop, |
| | 4785 | |
| | 4786 | /// Returned when socket is AF_UNIX and the given path length exceeds `MAX_PATH_BYTES` bytes. |
| | 4787 | NameTooLong, |
| | 4788 | |
| | 4789 | /// Returned when socket is AF_UNIX and the given path does not point to an existing file. |
| | 4790 | FileNotFound, |
| | 4791 | NotDir, |
| | 4792 | |
| | 4793 | /// Network is unreachable. |
| | 4794 | NetworkUnreachable, |
| | 4795 | |
| | 4796 | /// Insufficient memory was available to fulfill the request. |
| | 4797 | SystemResources, |
| | 4798 | |
| | 4799 | /// The socket is not connected (connection-oriented sockets only). |
| | 4800 | SocketNotConnected, |
| | 4801 | WouldBlock, |
| | 4802 | AddressNotAvailable, |
| | 4803 | }; |
| | 4804 | |
| 4780 | /// Transmit a message to another socket. | 4805 | /// Transmit a message to another socket. |
| 4781 | /// | 4806 | /// |
| 4782 | /// The `sendto` call may be used only when the socket is in a connected state (so that the intended | 4807 | /// The `sendto` call may be used only when the socket is in a connected state (so that the intended |
| ... | @@ -4810,19 +4835,31 @@ pub fn sendto( | ... | @@ -4810,19 +4835,31 @@ pub fn sendto( |
| 4810 | flags: u32, | 4835 | flags: u32, |
| 4811 | dest_addr: ?*const sockaddr, | 4836 | dest_addr: ?*const sockaddr, |
| 4812 | addrlen: socklen_t, | 4837 | addrlen: socklen_t, |
| 4813 | ) SendError!usize { | 4838 | ) SendToError!usize { |
| 4814 | while (true) { | 4839 | while (true) { |
| 4815 | const rc = system.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen); | 4840 | const rc = system.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen); |
| 4816 | if (builtin.os.tag == .windows) { | 4841 | if (builtin.os.tag == .windows) { |
| 4817 | if (rc == windows.ws2_32.SOCKET_ERROR) { | 4842 | if (rc == windows.ws2_32.SOCKET_ERROR) { |
| 4818 | switch (windows.ws2_32.WSAGetLastError()) { | 4843 | switch (windows.ws2_32.WSAGetLastError()) { |
| 4819 | .WSAEACCES => return error.AccessDenied, | 4844 | .WSAEACCES => return error.AccessDenied, |
| | 4845 | .WSAEADDRNOTAVAIL => return error.AddressNotAvailable, |
| 4820 | .WSAECONNRESET => return error.ConnectionResetByPeer, | 4846 | .WSAECONNRESET => return error.ConnectionResetByPeer, |
| 4821 | .WSAEMSGSIZE => return error.MessageTooBig, | 4847 | .WSAEMSGSIZE => return error.MessageTooBig, |
| 4822 | .WSAENOBUFS => return error.SystemResources, | 4848 | .WSAENOBUFS => return error.SystemResources, |
| 4823 | .WSAENOTSOCK => return error.FileDescriptorNotASocket, | 4849 | .WSAENOTSOCK => return error.FileDescriptorNotASocket, |
| 4824 | .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported, | 4850 | .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported, |
| 4825 | // TODO: handle more errors | 4851 | .WSAEDESTADDRREQ => unreachable, // A destination address is required. |
| | 4852 | .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. |
| | 4853 | .WSAEHOSTUNREACH => return error.NetworkUnreachable, |
| | 4854 | // TODO: WSAEINPROGRESS, WSAEINTR |
| | 4855 | .WSAEINVAL => unreachable, |
| | 4856 | .WSAENETDOWN => return error.NetworkUnreachable, |
| | 4857 | .WSAENETRESET => return error.ConnectionResetByPeer, |
| | 4858 | .WSAENETUNREACH => return error.NetworkUnreachable, |
| | 4859 | .WSAENOTCONN => return error.SocketNotConnected, |
| | 4860 | .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. |
| | 4861 | .WSAEWOULDBLOCK => return error.WouldBlock, |
| | 4862 | .WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function. |
| 4826 | else => |err| return windows.unexpectedWSAError(err), | 4863 | else => |err| return windows.unexpectedWSAError(err), |
| 4827 | } | 4864 | } |
| 4828 | } else { | 4865 | } else { |
| ... | @@ -4850,6 +4887,11 @@ pub fn sendto( | ... | @@ -4850,6 +4887,11 @@ pub fn sendto( |
| 4850 | EOPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type. | 4887 | EOPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type. |
| 4851 | EPIPE => return error.BrokenPipe, | 4888 | EPIPE => return error.BrokenPipe, |
| 4852 | EAFNOSUPPORT => return error.AddressFamilyNotSupported, | 4889 | EAFNOSUPPORT => return error.AddressFamilyNotSupported, |
| | 4890 | ELOOP => return error.SymLinkLoop, |
| | 4891 | ENAMETOOLONG => return error.NameTooLong, |
| | 4892 | ENOENT => return error.FileNotFound, |
| | 4893 | ENOTDIR => return error.NotDir, |
| | 4894 | EHOSTUNREACH => return error.NetworkUnreachable, |
| 4853 | else => |err| return unexpectedErrno(err), | 4895 | else => |err| return unexpectedErrno(err), |
| 4854 | } | 4896 | } |
| 4855 | } | 4897 | } |