| ... | @@ -4630,7 +4630,7 @@ pub const SendError = error{ | ... | @@ -4630,7 +4630,7 @@ pub const SendError = error{ |
| 4630 | /// possible to send more data. | 4630 | /// possible to send more data. |
| 4631 | pub fn sendto( | 4631 | pub fn sendto( |
| 4632 | /// The file descriptor of the sending socket. | 4632 | /// The file descriptor of the sending socket. |
| 4633 | sockfd: fd_t, | 4633 | sockfd: socket_t, |
| 4634 | /// Message to send. | 4634 | /// Message to send. |
| 4635 | buf: []const u8, | 4635 | buf: []const u8, |
| 4636 | flags: u32, | 4636 | flags: u32, |
| ... | @@ -4639,32 +4639,43 @@ pub fn sendto( | ... | @@ -4639,32 +4639,43 @@ pub fn sendto( |
| 4639 | ) SendError!usize { | 4639 | ) SendError!usize { |
| 4640 | while (true) { | 4640 | while (true) { |
| 4641 | const rc = system.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen); | 4641 | const rc = system.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen); |
| 4642 | switch (errno(rc)) { | 4642 | if (builtin.os.tag == .windows) { |
| 4643 | 0 => return @intCast(usize, rc), | 4643 | if (rc == windows.ws2_32.SOCKET_ERROR) { |
| 4644 | | 4644 | switch (windows.ws2_32.WSAGetLastError()) { |
| 4645 | EACCES => return error.AccessDenied, | 4645 | // TODO: handle errors |
| 4646 | EAGAIN => if (std.event.Loop.instance) |loop| { | 4646 | else => |err| return windows.unexpectedWSAError(err), |
| 4647 | loop.waitUntilFdWritable(sockfd); | 4647 | } |
| 4648 | continue; | | |
| 4649 | } else { | 4648 | } else { |
| 4650 | return error.WouldBlock; | 4649 | return @intCast(usize, rc); |
| 4651 | }, | 4650 | } |
| 4652 | EALREADY => return error.FastOpenAlreadyInProgress, | 4651 | } else { |
| 4653 | EBADF => unreachable, // always a race condition | 4652 | switch (errno(rc)) { |
| 4654 | ECONNRESET => return error.ConnectionResetByPeer, | 4653 | 0 => return @intCast(usize, rc), |
| 4655 | EDESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set. | 4654 | |
| 4656 | EFAULT => unreachable, // An invalid user space address was specified for an argument. | 4655 | EACCES => return error.AccessDenied, |
| 4657 | EINTR => continue, | 4656 | EAGAIN => if (std.event.Loop.instance) |loop| { |
| 4658 | EINVAL => unreachable, // Invalid argument passed. | 4657 | loop.waitUntilFdWritable(sockfd); |
| 4659 | EISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified | 4658 | continue; |
| 4660 | EMSGSIZE => return error.MessageTooBig, | 4659 | } else { |
| 4661 | ENOBUFS => return error.SystemResources, | 4660 | return error.WouldBlock; |
| 4662 | ENOMEM => return error.SystemResources, | 4661 | }, |
| 4663 | ENOTCONN => unreachable, // The socket is not connected, and no target has been given. | 4662 | EALREADY => return error.FastOpenAlreadyInProgress, |
| 4664 | ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket. | 4663 | EBADF => unreachable, // always a race condition |
| 4665 | EOPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type. | 4664 | ECONNRESET => return error.ConnectionResetByPeer, |
| 4666 | EPIPE => return error.BrokenPipe, | 4665 | EDESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set. |
| 4667 | else => |err| return unexpectedErrno(err), | 4666 | EFAULT => unreachable, // An invalid user space address was specified for an argument. |
| | 4667 | EINTR => continue, |
| | 4668 | EINVAL => unreachable, // Invalid argument passed. |
| | 4669 | EISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified |
| | 4670 | EMSGSIZE => return error.MessageTooBig, |
| | 4671 | ENOBUFS => return error.SystemResources, |
| | 4672 | ENOMEM => return error.SystemResources, |
| | 4673 | ENOTCONN => unreachable, // The socket is not connected, and no target has been given. |
| | 4674 | ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket. |
| | 4675 | EOPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type. |
| | 4676 | EPIPE => return error.BrokenPipe, |
| | 4677 | else => |err| return unexpectedErrno(err), |
| | 4678 | } |
| 4668 | } | 4679 | } |
| 4669 | } | 4680 | } |
| 4670 | } | 4681 | } |
| ... | @@ -4690,7 +4701,7 @@ pub fn sendto( | ... | @@ -4690,7 +4701,7 @@ pub fn sendto( |
| 4690 | /// possible to send more data. | 4701 | /// possible to send more data. |
| 4691 | pub fn send( | 4702 | pub fn send( |
| 4692 | /// The file descriptor of the sending socket. | 4703 | /// The file descriptor of the sending socket. |
| 4693 | sockfd: fd_t, | 4704 | sockfd: socket_t, |
| 4694 | buf: []const u8, | 4705 | buf: []const u8, |
| 4695 | flags: u32, | 4706 | flags: u32, |
| 4696 | ) SendError!usize { | 4707 | ) SendError!usize { |
| ... | @@ -5125,8 +5136,12 @@ pub const RecvFromError = error{ | ... | @@ -5125,8 +5136,12 @@ pub const RecvFromError = error{ |
| 5125 | SystemResources, | 5136 | SystemResources, |
| 5126 | } || UnexpectedError; | 5137 | } || UnexpectedError; |
| 5127 | | 5138 | |
| | 5139 | pub fn recv(sock: socket_t, buf: []u8, flags: u32) RecvFromError!usize { |
| | 5140 | return recvfrom(sock, buf, flags, null, null); |
| | 5141 | } |
| | 5142 | |
| 5128 | pub fn recvfrom( | 5143 | pub fn recvfrom( |
| 5129 | sockfd: fd_t, | 5144 | sockfd: socket_t, |
| 5130 | buf: []u8, | 5145 | buf: []u8, |
| 5131 | flags: u32, | 5146 | flags: u32, |
| 5132 | src_addr: ?*sockaddr, | 5147 | src_addr: ?*sockaddr, |
| ... | @@ -5134,23 +5149,34 @@ pub fn recvfrom( | ... | @@ -5134,23 +5149,34 @@ pub fn recvfrom( |
| 5134 | ) RecvFromError!usize { | 5149 | ) RecvFromError!usize { |
| 5135 | while (true) { | 5150 | while (true) { |
| 5136 | const rc = system.recvfrom(sockfd, buf.ptr, buf.len, flags, src_addr, addrlen); | 5151 | const rc = system.recvfrom(sockfd, buf.ptr, buf.len, flags, src_addr, addrlen); |
| 5137 | switch (errno(rc)) { | 5152 | if (builtin.os.tag == .windows) { |
| 5138 | 0 => return @intCast(usize, rc), | 5153 | if (rc == windows.ws2_32.SOCKET_ERROR) { |
| 5139 | EBADF => unreachable, // always a race condition | 5154 | switch (windows.ws2_32.WSAGetLastError()) { |
| 5140 | EFAULT => unreachable, | 5155 | // TODO: handle errors |
| 5141 | EINVAL => unreachable, | 5156 | else => |err| return windows.unexpectedWSAError(err), |
| 5142 | ENOTCONN => unreachable, | 5157 | } |
| 5143 | ENOTSOCK => unreachable, | | |
| 5144 | EINTR => continue, | | |
| 5145 | EAGAIN => if (std.event.Loop.instance) |loop| { | | |
| 5146 | loop.waitUntilFdReadable(sockfd); | | |
| 5147 | continue; | | |
| 5148 | } else { | 5158 | } else { |
| 5149 | return error.WouldBlock; | 5159 | return @intCast(usize, rc); |
| 5150 | }, | 5160 | } |
| 5151 | ENOMEM => return error.SystemResources, | 5161 | } else { |
| 5152 | ECONNREFUSED => return error.ConnectionRefused, | 5162 | switch (errno(rc)) { |
| 5153 | else => |err| return unexpectedErrno(err), | 5163 | 0 => return @intCast(usize, rc), |
| | 5164 | EBADF => unreachable, // always a race condition |
| | 5165 | EFAULT => unreachable, |
| | 5166 | EINVAL => unreachable, |
| | 5167 | ENOTCONN => unreachable, |
| | 5168 | ENOTSOCK => unreachable, |
| | 5169 | EINTR => continue, |
| | 5170 | EAGAIN => if (std.event.Loop.instance) |loop| { |
| | 5171 | loop.waitUntilFdReadable(sockfd); |
| | 5172 | continue; |
| | 5173 | } else { |
| | 5174 | return error.WouldBlock; |
| | 5175 | }, |
| | 5176 | ENOMEM => return error.SystemResources, |
| | 5177 | ECONNREFUSED => return error.ConnectionRefused, |
| | 5178 | else => |err| return unexpectedErrno(err), |
| | 5179 | } |
| 5154 | } | 5180 | } |
| 5155 | } | 5181 | } |
| 5156 | } | 5182 | } |