mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 15:13:08 +00:00
os.send(to) and os.recv(from) functions made to work on windows.
This commit is contained in:
parent
d80554cedf
commit
0a40a61548
114
lib/std/os.zig
114
lib/std/os.zig
@ -4630,7 +4630,7 @@ pub const SendError = error{
|
||||
/// possible to send more data.
|
||||
pub fn sendto(
|
||||
/// The file descriptor of the sending socket.
|
||||
sockfd: fd_t,
|
||||
sockfd: socket_t,
|
||||
/// Message to send.
|
||||
buf: []const u8,
|
||||
flags: u32,
|
||||
@ -4639,32 +4639,43 @@ pub fn sendto(
|
||||
) SendError!usize {
|
||||
while (true) {
|
||||
const rc = system.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen);
|
||||
switch (errno(rc)) {
|
||||
0 => return @intCast(usize, rc),
|
||||
|
||||
EACCES => return error.AccessDenied,
|
||||
EAGAIN => if (std.event.Loop.instance) |loop| {
|
||||
loop.waitUntilFdWritable(sockfd);
|
||||
continue;
|
||||
if (builtin.os.tag == .windows) {
|
||||
if (rc == windows.ws2_32.SOCKET_ERROR) {
|
||||
switch (windows.ws2_32.WSAGetLastError()) {
|
||||
// TODO: handle errors
|
||||
else => |err| return windows.unexpectedWSAError(err),
|
||||
}
|
||||
} else {
|
||||
return error.WouldBlock;
|
||||
},
|
||||
EALREADY => return error.FastOpenAlreadyInProgress,
|
||||
EBADF => unreachable, // always a race condition
|
||||
ECONNRESET => return error.ConnectionResetByPeer,
|
||||
EDESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
|
||||
EFAULT => unreachable, // An invalid user space address was specified for an argument.
|
||||
EINTR => continue,
|
||||
EINVAL => unreachable, // Invalid argument passed.
|
||||
EISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
|
||||
EMSGSIZE => return error.MessageTooBig,
|
||||
ENOBUFS => return error.SystemResources,
|
||||
ENOMEM => return error.SystemResources,
|
||||
ENOTCONN => unreachable, // The socket is not connected, and no target has been given.
|
||||
ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
|
||||
EOPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
|
||||
EPIPE => return error.BrokenPipe,
|
||||
else => |err| return unexpectedErrno(err),
|
||||
return @intCast(usize, rc);
|
||||
}
|
||||
} else {
|
||||
switch (errno(rc)) {
|
||||
0 => return @intCast(usize, rc),
|
||||
|
||||
EACCES => return error.AccessDenied,
|
||||
EAGAIN => if (std.event.Loop.instance) |loop| {
|
||||
loop.waitUntilFdWritable(sockfd);
|
||||
continue;
|
||||
} else {
|
||||
return error.WouldBlock;
|
||||
},
|
||||
EALREADY => return error.FastOpenAlreadyInProgress,
|
||||
EBADF => unreachable, // always a race condition
|
||||
ECONNRESET => return error.ConnectionResetByPeer,
|
||||
EDESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
|
||||
EFAULT => unreachable, // An invalid user space address was specified for an argument.
|
||||
EINTR => continue,
|
||||
EINVAL => unreachable, // Invalid argument passed.
|
||||
EISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
|
||||
EMSGSIZE => return error.MessageTooBig,
|
||||
ENOBUFS => return error.SystemResources,
|
||||
ENOMEM => return error.SystemResources,
|
||||
ENOTCONN => unreachable, // The socket is not connected, and no target has been given.
|
||||
ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
|
||||
EOPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
|
||||
EPIPE => return error.BrokenPipe,
|
||||
else => |err| return unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4690,7 +4701,7 @@ pub fn sendto(
|
||||
/// possible to send more data.
|
||||
pub fn send(
|
||||
/// The file descriptor of the sending socket.
|
||||
sockfd: fd_t,
|
||||
sockfd: socket_t,
|
||||
buf: []const u8,
|
||||
flags: u32,
|
||||
) SendError!usize {
|
||||
@ -5125,8 +5136,12 @@ pub const RecvFromError = error{
|
||||
SystemResources,
|
||||
} || UnexpectedError;
|
||||
|
||||
pub fn recv(sock: socket_t, buf: []u8, flags: u32) RecvFromError!usize {
|
||||
return recvfrom(sock, buf, flags, null, null);
|
||||
}
|
||||
|
||||
pub fn recvfrom(
|
||||
sockfd: fd_t,
|
||||
sockfd: socket_t,
|
||||
buf: []u8,
|
||||
flags: u32,
|
||||
src_addr: ?*sockaddr,
|
||||
@ -5134,23 +5149,34 @@ pub fn recvfrom(
|
||||
) RecvFromError!usize {
|
||||
while (true) {
|
||||
const rc = system.recvfrom(sockfd, buf.ptr, buf.len, flags, src_addr, addrlen);
|
||||
switch (errno(rc)) {
|
||||
0 => return @intCast(usize, rc),
|
||||
EBADF => unreachable, // always a race condition
|
||||
EFAULT => unreachable,
|
||||
EINVAL => unreachable,
|
||||
ENOTCONN => unreachable,
|
||||
ENOTSOCK => unreachable,
|
||||
EINTR => continue,
|
||||
EAGAIN => if (std.event.Loop.instance) |loop| {
|
||||
loop.waitUntilFdReadable(sockfd);
|
||||
continue;
|
||||
if (builtin.os.tag == .windows) {
|
||||
if (rc == windows.ws2_32.SOCKET_ERROR) {
|
||||
switch (windows.ws2_32.WSAGetLastError()) {
|
||||
// TODO: handle errors
|
||||
else => |err| return windows.unexpectedWSAError(err),
|
||||
}
|
||||
} else {
|
||||
return error.WouldBlock;
|
||||
},
|
||||
ENOMEM => return error.SystemResources,
|
||||
ECONNREFUSED => return error.ConnectionRefused,
|
||||
else => |err| return unexpectedErrno(err),
|
||||
return @intCast(usize, rc);
|
||||
}
|
||||
} else {
|
||||
switch (errno(rc)) {
|
||||
0 => return @intCast(usize, rc),
|
||||
EBADF => unreachable, // always a race condition
|
||||
EFAULT => unreachable,
|
||||
EINVAL => unreachable,
|
||||
ENOTCONN => unreachable,
|
||||
ENOTSOCK => unreachable,
|
||||
EINTR => continue,
|
||||
EAGAIN => if (std.event.Loop.instance) |loop| {
|
||||
loop.waitUntilFdReadable(sockfd);
|
||||
continue;
|
||||
} else {
|
||||
return error.WouldBlock;
|
||||
},
|
||||
ENOMEM => return error.SystemResources,
|
||||
ECONNREFUSED => return error.ConnectionRefused,
|
||||
else => |err| return unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1190,6 +1190,27 @@ pub fn getsockname(s: ws2_32.SOCKET, name: *ws2_32.sockaddr, namelen: *ws2_32.so
|
||||
return rc;
|
||||
}
|
||||
|
||||
pub 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 {
|
||||
var buffer = ws2_32.WSABUF{ .len = @truncate(u31, len), .buf = @intToPtr([*]u8, @ptrToInt(buf)) };
|
||||
var bytes_send: DWORD = undefined;
|
||||
if (ws2_32.WSASendTo(s, @ptrCast([*]ws2_32.WSABUF, &buffer), 1, &bytes_send, flags, to, to_len, null, null) == ws2_32.SOCKET_ERROR) {
|
||||
return ws2_32.SOCKET_ERROR;
|
||||
} else {
|
||||
return @as(i32, @intCast(u31, bytes_send));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn recvfrom(s: ws2_32.SOCKET, buf: [*]u8, len: usize, flags: u32, from: ?*ws2_32.sockaddr, from_len: ?*ws2_32.socklen_t) i32 {
|
||||
var buffer = ws2_32.WSABUF{ .len = @truncate(u31, len), .buf = buf };
|
||||
var bytes_received: DWORD = undefined;
|
||||
var flags_inout = flags;
|
||||
if (ws2_32.WSARecvFrom(s, @ptrCast([*]ws2_32.WSABUF, &buffer), 1, &bytes_received, &flags_inout, from, from_len, null, null) == ws2_32.SOCKET_ERROR) {
|
||||
return ws2_32.SOCKET_ERROR;
|
||||
} else {
|
||||
return @as(i32, @intCast(u31, bytes_received));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn WSAIoctl(
|
||||
s: ws2_32.SOCKET,
|
||||
dwIoControlCode: DWORD,
|
||||
|
||||
@ -786,7 +786,7 @@ pub extern "ws2_32" fn WSASendTo(
|
||||
lpNumberOfBytesSent: ?*DWORD,
|
||||
dwFlags: DWORD,
|
||||
lpTo: ?*const sockaddr,
|
||||
iTolen: socklen_t,
|
||||
iTolen: c_int,
|
||||
lpOverlapped: ?*WSAOVERLAPPED,
|
||||
lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
|
||||
) callconv(.Stdcall) c_int;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user