mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
std.Io.Threaded: implement netAccept for Windows
This commit is contained in:
parent
34891b528e
commit
0b5179a231
3 changed files with 34 additions and 46 deletions
|
|
@ -244,7 +244,7 @@ pub fn io(t: *Threaded) Io {
|
||||||
},
|
},
|
||||||
.netListenUnix = netListenUnix,
|
.netListenUnix = netListenUnix,
|
||||||
.netAccept = switch (builtin.os.tag) {
|
.netAccept = switch (builtin.os.tag) {
|
||||||
.windows => @panic("TODO"),
|
.windows => netAcceptWindows,
|
||||||
else => netAcceptPosix,
|
else => netAcceptPosix,
|
||||||
},
|
},
|
||||||
.netBindIp = switch (builtin.os.tag) {
|
.netBindIp = switch (builtin.os.tag) {
|
||||||
|
|
@ -3288,6 +3288,38 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
|
||||||
} };
|
} };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net.Server.AcceptError!net.Stream {
|
||||||
|
if (!have_networking) return error.NetworkDown;
|
||||||
|
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||||
|
var storage: WsaAddress = undefined;
|
||||||
|
var addr_len: i32 = @sizeOf(WsaAddress);
|
||||||
|
while (true) {
|
||||||
|
try t.checkCancel();
|
||||||
|
const rc = ws2_32.accept(listen_handle, &storage.any, &addr_len);
|
||||||
|
if (rc != windows.ws2_32.INVALID_SOCKET) return .{ .socket = .{
|
||||||
|
.handle = rc,
|
||||||
|
.address = addressFromWsa(&storage),
|
||||||
|
} };
|
||||||
|
switch (windows.ws2_32.WSAGetLastError()) {
|
||||||
|
.EINTR => continue,
|
||||||
|
.ECANCELLED, .E_CANCELLED => return error.Canceled,
|
||||||
|
.NOTINITIALISED => {
|
||||||
|
try initializeWsa(t);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
.ECONNRESET => return error.ConnectionAborted,
|
||||||
|
.EFAULT => |err| return wsaErrorBug(err),
|
||||||
|
.ENOTSOCK => |err| return wsaErrorBug(err),
|
||||||
|
.EINVAL => |err| return wsaErrorBug(err),
|
||||||
|
.EMFILE => return error.ProcessFdQuotaExceeded,
|
||||||
|
.ENETDOWN => return error.NetworkDown,
|
||||||
|
.ENOBUFS => return error.SystemResources,
|
||||||
|
.EOPNOTSUPP => |err| return wsaErrorBug(err),
|
||||||
|
else => |err| return windows.unexpectedWSAError(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
|
fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
|
||||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1574,11 +1574,6 @@ pub fn GetFileAttributesW(lpFileName: [*:0]const u16) GetFileAttributesError!DWO
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn accept(s: ws2_32.SOCKET, name: ?*ws2_32.sockaddr, namelen: ?*ws2_32.socklen_t) ws2_32.SOCKET {
|
|
||||||
assert((name == null) == (namelen == null));
|
|
||||||
return ws2_32.accept(s, name, @as(?*i32, @ptrCast(namelen)));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getpeername(s: ws2_32.SOCKET, name: *ws2_32.sockaddr, namelen: *ws2_32.socklen_t) i32 {
|
pub fn getpeername(s: ws2_32.SOCKET, name: *ws2_32.sockaddr, namelen: *ws2_32.socklen_t) i32 {
|
||||||
return ws2_32.getpeername(s, name, @as(*i32, @ptrCast(namelen)));
|
return ws2_32.getpeername(s, name, @as(*i32, @ptrCast(namelen)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3471,31 +3471,10 @@ pub fn listen(sock: socket_t, backlog: u31) ListenError!void {
|
||||||
|
|
||||||
pub const AcceptError = std.Io.net.Server.AcceptError;
|
pub const AcceptError = std.Io.net.Server.AcceptError;
|
||||||
|
|
||||||
/// Accept a connection on a socket.
|
|
||||||
/// If `sockfd` is opened in non blocking mode, the function will
|
|
||||||
/// return error.WouldBlock when EAGAIN is received.
|
|
||||||
pub fn accept(
|
pub fn accept(
|
||||||
/// This argument is a socket that has been created with `socket`, bound to a local address
|
|
||||||
/// with `bind`, and is listening for connections after a `listen`.
|
|
||||||
sock: socket_t,
|
sock: socket_t,
|
||||||
/// This argument is a pointer to a sockaddr structure. This structure is filled in with the
|
|
||||||
/// address of the peer socket, as known to the communications layer. The exact format of the
|
|
||||||
/// address returned addr is determined by the socket's address family (see `socket` and the
|
|
||||||
/// respective protocol man pages).
|
|
||||||
addr: ?*sockaddr,
|
addr: ?*sockaddr,
|
||||||
/// This argument is a value-result argument: the caller must initialize it to contain the
|
|
||||||
/// size (in bytes) of the structure pointed to by addr; on return it will contain the actual size
|
|
||||||
/// of the peer address.
|
|
||||||
///
|
|
||||||
/// The returned address is truncated if the buffer provided is too small; in this case, `addr_size`
|
|
||||||
/// will return a value greater than was supplied to the call.
|
|
||||||
addr_size: ?*socklen_t,
|
addr_size: ?*socklen_t,
|
||||||
/// The following values can be bitwise ORed in flags to obtain different behavior:
|
|
||||||
/// * `SOCK.NONBLOCK` - Set the `NONBLOCK` file status flag on the open file description (see `open`)
|
|
||||||
/// referred to by the new file descriptor. Using this flag saves extra calls to `fcntl` to achieve
|
|
||||||
/// the same result.
|
|
||||||
/// * `SOCK.CLOEXEC` - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor. See the
|
|
||||||
/// description of the `CLOEXEC` flag in `open` for reasons why this may be useful.
|
|
||||||
flags: u32,
|
flags: u32,
|
||||||
) AcceptError!socket_t {
|
) AcceptError!socket_t {
|
||||||
const have_accept4 = !(builtin.target.os.tag.isDarwin() or native_os == .windows or native_os == .haiku);
|
const have_accept4 = !(builtin.target.os.tag.isDarwin() or native_os == .windows or native_os == .haiku);
|
||||||
|
|
@ -3504,29 +3483,11 @@ pub fn accept(
|
||||||
const accepted_sock: socket_t = while (true) {
|
const accepted_sock: socket_t = while (true) {
|
||||||
const rc = if (have_accept4)
|
const rc = if (have_accept4)
|
||||||
system.accept4(sock, addr, addr_size, flags)
|
system.accept4(sock, addr, addr_size, flags)
|
||||||
else if (native_os == .windows)
|
|
||||||
windows.accept(sock, addr, addr_size)
|
|
||||||
else
|
else
|
||||||
system.accept(sock, addr, addr_size);
|
system.accept(sock, addr, addr_size);
|
||||||
|
|
||||||
if (native_os == .windows) {
|
if (native_os == .windows) {
|
||||||
if (rc == windows.ws2_32.INVALID_SOCKET) {
|
@compileError("use std.Io instead");
|
||||||
switch (windows.ws2_32.WSAGetLastError()) {
|
|
||||||
.NOTINITIALISED => unreachable, // not initialized WSA
|
|
||||||
.ECONNRESET => return error.ConnectionResetByPeer,
|
|
||||||
.EFAULT => unreachable,
|
|
||||||
.ENOTSOCK => return error.FileDescriptorNotASocket,
|
|
||||||
.EINVAL => return error.SocketNotListening,
|
|
||||||
.EMFILE => return error.ProcessFdQuotaExceeded,
|
|
||||||
.ENETDOWN => return error.NetworkDown,
|
|
||||||
.ENOBUFS => return error.FileDescriptorNotASocket,
|
|
||||||
.EOPNOTSUPP => return error.OperationNotSupported,
|
|
||||||
.EWOULDBLOCK => return error.WouldBlock,
|
|
||||||
else => |err| return windows.unexpectedWSAError(err),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break rc;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
switch (errno(rc)) {
|
switch (errno(rc)) {
|
||||||
.SUCCESS => break @intCast(rc),
|
.SUCCESS => break @intCast(rc),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue