authorgravatar for BarabasGitHub@users.noreply.github.comBas van den Berg <BarabasGitHub@users.noreply.github.com> 2020-09-03 13:23:48+02:00
committergravatar for BarabasGitHub@users.noreply.github.comBas van den Berg <BarabasGitHub@users.noreply.github.com> 2020-09-03 13:23:48+02:00
log0a40a61548ad9f666ed5300a8910f9040cc1390b
tree0e1084929c0bc0b99704113ab706d625ca61b5c8
parentd80554cedf313bc78f0419faf84776bd987263df

os.send(to) and os.recv(from) functions made to work on windows.


3 files changed, 92 insertions(+), 45 deletions(-)

lib/std/os.zig+70-44
......@@ -4630,7 +4630,7 @@ pub const SendError = error{
46304630/// possible to send more data.
46314631pub fn sendto(
46324632 /// The file descriptor of the sending socket.
4633 sockfd: fd_t,
4633 sockfd: socket_t,
46344634 /// Message to send.
46354635 buf: []const u8,
46364636 flags: u32,
......@@ -4639,32 +4639,43 @@ pub fn sendto(
46394639) SendError!usize {
46404640 while (true) {
46414641 const rc = system.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen);
4642 switch (errno(rc)) {
4643 0 => return @intCast(usize, rc),
4644
4645 EACCES => return error.AccessDenied,
4646 EAGAIN => if (std.event.Loop.instance) |loop| {
4647 loop.waitUntilFdWritable(sockfd);
4648 continue;
4642 if (builtin.os.tag == .windows) {
4643 if (rc == windows.ws2_32.SOCKET_ERROR) {
4644 switch (windows.ws2_32.WSAGetLastError()) {
4645 // TODO: handle errors
4646 else => |err| return windows.unexpectedWSAError(err),
4647 }
46494648 } else {
4650 return error.WouldBlock;
4651 },
4652 EALREADY => return error.FastOpenAlreadyInProgress,
4653 EBADF => unreachable, // always a race condition
4654 ECONNRESET => return error.ConnectionResetByPeer,
4655 EDESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
4656 EFAULT => unreachable, // An invalid user space address was specified for an argument.
4657 EINTR => continue,
4658 EINVAL => unreachable, // Invalid argument passed.
4659 EISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
4660 EMSGSIZE => return error.MessageTooBig,
4661 ENOBUFS => return error.SystemResources,
4662 ENOMEM => return error.SystemResources,
4663 ENOTCONN => unreachable, // The socket is not connected, and no target has been given.
4664 ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
4665 EOPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
4666 EPIPE => return error.BrokenPipe,
4667 else => |err| return unexpectedErrno(err),
4649 return @intCast(usize, rc);
4650 }
4651 } else {
4652 switch (errno(rc)) {
4653 0 => return @intCast(usize, rc),
4654
4655 EACCES => return error.AccessDenied,
4656 EAGAIN => if (std.event.Loop.instance) |loop| {
4657 loop.waitUntilFdWritable(sockfd);
4658 continue;
4659 } else {
4660 return error.WouldBlock;
4661 },
4662 EALREADY => return error.FastOpenAlreadyInProgress,
4663 EBADF => unreachable, // always a race condition
4664 ECONNRESET => return error.ConnectionResetByPeer,
4665 EDESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
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 }
46684679 }
46694680 }
46704681}
......@@ -4690,7 +4701,7 @@ pub fn sendto(
46904701/// possible to send more data.
46914702pub fn send(
46924703 /// The file descriptor of the sending socket.
4693 sockfd: fd_t,
4704 sockfd: socket_t,
46944705 buf: []const u8,
46954706 flags: u32,
46964707) SendError!usize {
......@@ -5125,8 +5136,12 @@ pub const RecvFromError = error{
51255136 SystemResources,
51265137} || UnexpectedError;
51275138
5139pub fn recv(sock: socket_t, buf: []u8, flags: u32) RecvFromError!usize {
5140 return recvfrom(sock, buf, flags, null, null);
5141}
5142
51285143pub fn recvfrom(
5129 sockfd: fd_t,
5144 sockfd: socket_t,
51305145 buf: []u8,
51315146 flags: u32,
51325147 src_addr: ?*sockaddr,
......@@ -5134,23 +5149,34 @@ pub fn recvfrom(
51345149) RecvFromError!usize {
51355150 while (true) {
51365151 const rc = system.recvfrom(sockfd, buf.ptr, buf.len, flags, src_addr, addrlen);
5137 switch (errno(rc)) {
5138 0 => return @intCast(usize, rc),
5139 EBADF => unreachable, // always a race condition
5140 EFAULT => unreachable,
5141 EINVAL => unreachable,
5142 ENOTCONN => unreachable,
5143 ENOTSOCK => unreachable,
5144 EINTR => continue,
5145 EAGAIN => if (std.event.Loop.instance) |loop| {
5146 loop.waitUntilFdReadable(sockfd);
5147 continue;
5152 if (builtin.os.tag == .windows) {
5153 if (rc == windows.ws2_32.SOCKET_ERROR) {
5154 switch (windows.ws2_32.WSAGetLastError()) {
5155 // TODO: handle errors
5156 else => |err| return windows.unexpectedWSAError(err),
5157 }
51485158 } else {
5149 return error.WouldBlock;
5150 },
5151 ENOMEM => return error.SystemResources,
5152 ECONNREFUSED => return error.ConnectionRefused,
5153 else => |err| return unexpectedErrno(err),
5159 return @intCast(usize, rc);
5160 }
5161 } else {
5162 switch (errno(rc)) {
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 }
51545180 }
51555181 }
51565182}
lib/std/os/windows.zig+21
......@@ -1190,6 +1190,27 @@ pub fn getsockname(s: ws2_32.SOCKET, name: *ws2_32.sockaddr, namelen: *ws2_32.so
11901190 return rc;
11911191}
11921192
1193pub fn sendto(s: ws2_32.SOCKET, buf: [*]const u8, len: usize, flags: u32, to: ?*const ws2_32.sockaddr, to_len: ws2_32.socklen_t) i32 {
1194 var buffer = ws2_32.WSABUF{ .len = @truncate(u31, len), .buf = @intToPtr([*]u8, @ptrToInt(buf)) };
1195 var bytes_send: DWORD = undefined;
1196 if (ws2_32.WSASendTo(s, @ptrCast([*]ws2_32.WSABUF, &buffer), 1, &bytes_send, flags, to, to_len, null, null) == ws2_32.SOCKET_ERROR) {
1197 return ws2_32.SOCKET_ERROR;
1198 } else {
1199 return @as(i32, @intCast(u31, bytes_send));
1200 }
1201}
1202
1203pub fn recvfrom(s: ws2_32.SOCKET, buf: [*]u8, len: usize, flags: u32, from: ?*ws2_32.sockaddr, from_len: ?*ws2_32.socklen_t) i32 {
1204 var buffer = ws2_32.WSABUF{ .len = @truncate(u31, len), .buf = buf };
1205 var bytes_received: DWORD = undefined;
1206 var flags_inout = flags;
1207 if (ws2_32.WSARecvFrom(s, @ptrCast([*]ws2_32.WSABUF, &buffer), 1, &bytes_received, &flags_inout, from, from_len, null, null) == ws2_32.SOCKET_ERROR) {
1208 return ws2_32.SOCKET_ERROR;
1209 } else {
1210 return @as(i32, @intCast(u31, bytes_received));
1211 }
1212}
1213
11931214pub fn WSAIoctl(
11941215 s: ws2_32.SOCKET,
11951216 dwIoControlCode: DWORD,
lib/std/os/windows/ws2_32.zig+1-1
......@@ -786,7 +786,7 @@ pub extern "ws2_32" fn WSASendTo(
786786 lpNumberOfBytesSent: ?*DWORD,
787787 dwFlags: DWORD,
788788 lpTo: ?*const sockaddr,
789 iTolen: socklen_t,
789 iTolen: c_int,
790790 lpOverlapped: ?*WSAOVERLAPPED,
791791 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
792792) callconv(.Stdcall) c_int;