| ... | ... | @@ -4840,7 +4840,7 @@ pub const SendError = error{ |
| 4840 | 4840 | NetworkSubsystemFailed, |
| 4841 | 4841 | } || UnexpectedError; |
| 4842 | 4842 | |
| 4843 | | pub const SendToError = SendError || error{ |
| 4843 | pub const SendMsgError = SendError || error{ |
| 4844 | 4844 | /// The passed address didn't have the correct address family in its sa_family field. |
| 4845 | 4845 | AddressFamilyNotSupported, |
| 4846 | 4846 | |
| ... | ... | @@ -4859,6 +4859,79 @@ pub const SendToError = SendError || error{ |
| 4859 | 4859 | AddressNotAvailable, |
| 4860 | 4860 | }; |
| 4861 | 4861 | |
| 4862 | pub fn sendmsg( |
| 4863 | /// The file descriptor of the sending socket. |
| 4864 | sockfd: socket_t, |
| 4865 | /// Message header and iovecs |
| 4866 | msg: msghdr_const, |
| 4867 | flags: u32, |
| 4868 | ) SendMsgError!usize { |
| 4869 | while (true) { |
| 4870 | const rc = system.sendmsg(sockfd, &msg, flags); |
| 4871 | if (builtin.os.tag == .windows) { |
| 4872 | if (rc == windows.ws2_32.SOCKET_ERROR) { |
| 4873 | switch (windows.ws2_32.WSAGetLastError()) { |
| 4874 | .WSAEACCES => return error.AccessDenied, |
| 4875 | .WSAEADDRNOTAVAIL => return error.AddressNotAvailable, |
| 4876 | .WSAECONNRESET => return error.ConnectionResetByPeer, |
| 4877 | .WSAEMSGSIZE => return error.MessageTooBig, |
| 4878 | .WSAENOBUFS => return error.SystemResources, |
| 4879 | .WSAENOTSOCK => return error.FileDescriptorNotASocket, |
| 4880 | .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported, |
| 4881 | .WSAEDESTADDRREQ => unreachable, // A destination address is required. |
| 4882 | .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. |
| 4883 | .WSAEHOSTUNREACH => return error.NetworkUnreachable, |
| 4884 | // TODO: WSAEINPROGRESS, WSAEINTR |
| 4885 | .WSAEINVAL => unreachable, |
| 4886 | .WSAENETDOWN => return error.NetworkSubsystemFailed, |
| 4887 | .WSAENETRESET => return error.ConnectionResetByPeer, |
| 4888 | .WSAENETUNREACH => return error.NetworkUnreachable, |
| 4889 | .WSAENOTCONN => return error.SocketNotConnected, |
| 4890 | .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. |
| 4891 | .WSAEWOULDBLOCK => return error.WouldBlock, |
| 4892 | .WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function. |
| 4893 | else => |err| return windows.unexpectedWSAError(err), |
| 4894 | } |
| 4895 | } else { |
| 4896 | return @intCast(usize, rc); |
| 4897 | } |
| 4898 | } else { |
| 4899 | switch (errno(rc)) { |
| 4900 | 0 => return @intCast(usize, rc), |
| 4901 | |
| 4902 | EACCES => return error.AccessDenied, |
| 4903 | EAGAIN => return error.WouldBlock, |
| 4904 | EALREADY => return error.FastOpenAlreadyInProgress, |
| 4905 | EBADF => unreachable, // always a race condition |
| 4906 | ECONNRESET => return error.ConnectionResetByPeer, |
| 4907 | EDESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set. |
| 4908 | EFAULT => unreachable, // An invalid user space address was specified for an argument. |
| 4909 | EINTR => continue, |
| 4910 | EINVAL => unreachable, // Invalid argument passed. |
| 4911 | EISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified |
| 4912 | EMSGSIZE => return error.MessageTooBig, |
| 4913 | ENOBUFS => return error.SystemResources, |
| 4914 | ENOMEM => return error.SystemResources, |
| 4915 | ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket. |
| 4916 | EOPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type. |
| 4917 | EPIPE => return error.BrokenPipe, |
| 4918 | EAFNOSUPPORT => return error.AddressFamilyNotSupported, |
| 4919 | ELOOP => return error.SymLinkLoop, |
| 4920 | ENAMETOOLONG => return error.NameTooLong, |
| 4921 | ENOENT => return error.FileNotFound, |
| 4922 | ENOTDIR => return error.NotDir, |
| 4923 | EHOSTUNREACH => return error.NetworkUnreachable, |
| 4924 | ENETUNREACH => return error.NetworkUnreachable, |
| 4925 | ENOTCONN => return error.SocketNotConnected, |
| 4926 | ENETDOWN => return error.NetworkSubsystemFailed, |
| 4927 | else => |err| return unexpectedErrno(err), |
| 4928 | } |
| 4929 | } |
| 4930 | } |
| 4931 | } |
| 4932 | |
| 4933 | pub const SendToError = SendMsgError; |
| 4934 | |
| 4862 | 4935 | /// Transmit a message to another socket. |
| 4863 | 4936 | /// |
| 4864 | 4937 | /// The `sendto` call may be used only when the socket is in a connected state (so that the intended |