mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
std.Io.Threaded: implement netBindIp for Windows
This commit is contained in:
parent
0b5179a231
commit
76107e9e65
1 changed files with 82 additions and 2 deletions
|
|
@ -248,7 +248,7 @@ pub fn io(t: *Threaded) Io {
|
||||||
else => netAcceptPosix,
|
else => netAcceptPosix,
|
||||||
},
|
},
|
||||||
.netBindIp = switch (builtin.os.tag) {
|
.netBindIp = switch (builtin.os.tag) {
|
||||||
.windows => @panic("TODO"),
|
.windows => netBindIpWindows,
|
||||||
else => netBindIpPosix,
|
else => netBindIpPosix,
|
||||||
},
|
},
|
||||||
.netConnectIp = switch (builtin.os.tag) {
|
.netConnectIp = switch (builtin.os.tag) {
|
||||||
|
|
@ -2828,7 +2828,7 @@ fn netListenIpWindows(
|
||||||
.EAFNOSUPPORT => return error.AddressFamilyUnsupported,
|
.EAFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
.EMFILE => return error.ProcessFdQuotaExceeded,
|
.EMFILE => return error.ProcessFdQuotaExceeded,
|
||||||
.ENOBUFS => return error.SystemResources,
|
.ENOBUFS => return error.SystemResources,
|
||||||
.EPROTONOSUPPORT => return error.ProtocolUnsupportedBySystem,
|
.EPROTONOSUPPORT => return error.ProtocolUnsupportedByAddressFamily,
|
||||||
else => |err| return windows.unexpectedWSAError(err),
|
else => |err| return windows.unexpectedWSAError(err),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -3176,6 +3176,86 @@ fn netBindIpPosix(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn netBindIpWindows(
|
||||||
|
userdata: ?*anyopaque,
|
||||||
|
address: *const IpAddress,
|
||||||
|
options: IpAddress.BindOptions,
|
||||||
|
) IpAddress.BindError!net.Socket {
|
||||||
|
if (!have_networking) return error.NetworkDown;
|
||||||
|
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||||
|
const family = posixAddressFamily(address);
|
||||||
|
const mode = posixSocketMode(options.mode);
|
||||||
|
const protocol = posixProtocol(options.protocol);
|
||||||
|
const socket_handle = while (true) {
|
||||||
|
try t.checkCancel();
|
||||||
|
const flags: u32 = ws2_32.WSA_FLAG_OVERLAPPED | ws2_32.WSA_FLAG_NO_HANDLE_INHERIT;
|
||||||
|
const rc = ws2_32.WSASocketW(family, @bitCast(mode), @bitCast(protocol), null, 0, flags);
|
||||||
|
if (rc != ws2_32.INVALID_SOCKET) break rc;
|
||||||
|
switch (ws2_32.WSAGetLastError()) {
|
||||||
|
.EINTR => continue,
|
||||||
|
.ECANCELLED, .E_CANCELLED => return error.Canceled,
|
||||||
|
.NOTINITIALISED => {
|
||||||
|
try initializeWsa(t);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
.EAFNOSUPPORT => return error.AddressFamilyUnsupported,
|
||||||
|
.EMFILE => return error.ProcessFdQuotaExceeded,
|
||||||
|
.ENOBUFS => return error.SystemResources,
|
||||||
|
.EPROTONOSUPPORT => return error.ProtocolUnsupportedByAddressFamily,
|
||||||
|
else => |err| return windows.unexpectedWSAError(err),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
errdefer closeSocketWindows(socket_handle);
|
||||||
|
var storage: WsaAddress = undefined;
|
||||||
|
var addr_len = addressToWsa(address, &storage);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
try t.checkCancel();
|
||||||
|
const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
|
||||||
|
if (rc != ws2_32.SOCKET_ERROR) break;
|
||||||
|
switch (ws2_32.WSAGetLastError()) {
|
||||||
|
.EINTR => continue,
|
||||||
|
.ECANCELLED, .E_CANCELLED => return error.Canceled,
|
||||||
|
.NOTINITIALISED => {
|
||||||
|
try initializeWsa(t);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
.EADDRINUSE => return error.AddressInUse,
|
||||||
|
.EADDRNOTAVAIL => return error.AddressUnavailable,
|
||||||
|
.ENOTSOCK => |err| return wsaErrorBug(err),
|
||||||
|
.EFAULT => |err| return wsaErrorBug(err),
|
||||||
|
.EINVAL => |err| return wsaErrorBug(err),
|
||||||
|
.ENOBUFS => return error.SystemResources,
|
||||||
|
.ENETDOWN => return error.NetworkDown,
|
||||||
|
else => |err| return windows.unexpectedWSAError(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
try t.checkCancel();
|
||||||
|
const rc = ws2_32.getsockname(socket_handle, &storage.any, &addr_len);
|
||||||
|
if (rc != ws2_32.SOCKET_ERROR) break;
|
||||||
|
switch (ws2_32.WSAGetLastError()) {
|
||||||
|
.EINTR => continue,
|
||||||
|
.ECANCELLED, .E_CANCELLED => return error.Canceled,
|
||||||
|
.NOTINITIALISED => {
|
||||||
|
try initializeWsa(t);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
.ENETDOWN => return error.NetworkDown,
|
||||||
|
.EFAULT => |err| return wsaErrorBug(err),
|
||||||
|
.ENOTSOCK => |err| return wsaErrorBug(err),
|
||||||
|
.EINVAL => |err| return wsaErrorBug(err),
|
||||||
|
else => |err| return windows.unexpectedWSAError(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.handle = socket_handle,
|
||||||
|
.address = addressFromWsa(&storage),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn openSocketPosix(
|
fn openSocketPosix(
|
||||||
t: *Threaded,
|
t: *Threaded,
|
||||||
family: posix.sa_family_t,
|
family: posix.sa_family_t,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue