authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-20 22:59:05-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:50-07:00
log76107e9e655378b7d62c1d5d93ef9e17d241975f
treeb12bae37602af995c6a1111199de2696e94748a7
parent0b5179a231c3f639f2fe3f2cafffa8b2cfd02482

std.Io.Threaded: implement netBindIp for Windows


1 files changed, 82 insertions(+), 2 deletions(-)

lib/std/Io/Threaded.zig+82-2
......@@ -248,7 +248,7 @@ pub fn io(t: *Threaded) Io {
248248 else => netAcceptPosix,
249249 },
250250 .netBindIp = switch (builtin.os.tag) {
251 .windows => @panic("TODO"),
251 .windows => netBindIpWindows,
252252 else => netBindIpPosix,
253253 },
254254 .netConnectIp = switch (builtin.os.tag) {
......@@ -2828,7 +2828,7 @@ fn netListenIpWindows(
28282828 .EAFNOSUPPORT => return error.AddressFamilyUnsupported,
28292829 .EMFILE => return error.ProcessFdQuotaExceeded,
28302830 .ENOBUFS => return error.SystemResources,
2831 .EPROTONOSUPPORT => return error.ProtocolUnsupportedBySystem,
2831 .EPROTONOSUPPORT => return error.ProtocolUnsupportedByAddressFamily,
28322832 else => |err| return windows.unexpectedWSAError(err),
28332833 }
28342834 };
......@@ -3176,6 +3176,86 @@ fn netBindIpPosix(
31763176 };
31773177}
31783178
3179fn netBindIpWindows(
3180 userdata: ?*anyopaque,
3181 address: *const IpAddress,
3182 options: IpAddress.BindOptions,
3183) IpAddress.BindError!net.Socket {
3184 if (!have_networking) return error.NetworkDown;
3185 const t: *Threaded = @ptrCast(@alignCast(userdata));
3186 const family = posixAddressFamily(address);
3187 const mode = posixSocketMode(options.mode);
3188 const protocol = posixProtocol(options.protocol);
3189 const socket_handle = while (true) {
3190 try t.checkCancel();
3191 const flags: u32 = ws2_32.WSA_FLAG_OVERLAPPED | ws2_32.WSA_FLAG_NO_HANDLE_INHERIT;
3192 const rc = ws2_32.WSASocketW(family, @bitCast(mode), @bitCast(protocol), null, 0, flags);
3193 if (rc != ws2_32.INVALID_SOCKET) break rc;
3194 switch (ws2_32.WSAGetLastError()) {
3195 .EINTR => continue,
3196 .ECANCELLED, .E_CANCELLED => return error.Canceled,
3197 .NOTINITIALISED => {
3198 try initializeWsa(t);
3199 continue;
3200 },
3201 .EAFNOSUPPORT => return error.AddressFamilyUnsupported,
3202 .EMFILE => return error.ProcessFdQuotaExceeded,
3203 .ENOBUFS => return error.SystemResources,
3204 .EPROTONOSUPPORT => return error.ProtocolUnsupportedByAddressFamily,
3205 else => |err| return windows.unexpectedWSAError(err),
3206 }
3207 };
3208 errdefer closeSocketWindows(socket_handle);
3209 var storage: WsaAddress = undefined;
3210 var addr_len = addressToWsa(address, &storage);
3211
3212 while (true) {
3213 try t.checkCancel();
3214 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
3215 if (rc != ws2_32.SOCKET_ERROR) break;
3216 switch (ws2_32.WSAGetLastError()) {
3217 .EINTR => continue,
3218 .ECANCELLED, .E_CANCELLED => return error.Canceled,
3219 .NOTINITIALISED => {
3220 try initializeWsa(t);
3221 continue;
3222 },
3223 .EADDRINUSE => return error.AddressInUse,
3224 .EADDRNOTAVAIL => return error.AddressUnavailable,
3225 .ENOTSOCK => |err| return wsaErrorBug(err),
3226 .EFAULT => |err| return wsaErrorBug(err),
3227 .EINVAL => |err| return wsaErrorBug(err),
3228 .ENOBUFS => return error.SystemResources,
3229 .ENETDOWN => return error.NetworkDown,
3230 else => |err| return windows.unexpectedWSAError(err),
3231 }
3232 }
3233
3234 while (true) {
3235 try t.checkCancel();
3236 const rc = ws2_32.getsockname(socket_handle, &storage.any, &addr_len);
3237 if (rc != ws2_32.SOCKET_ERROR) break;
3238 switch (ws2_32.WSAGetLastError()) {
3239 .EINTR => continue,
3240 .ECANCELLED, .E_CANCELLED => return error.Canceled,
3241 .NOTINITIALISED => {
3242 try initializeWsa(t);
3243 continue;
3244 },
3245 .ENETDOWN => return error.NetworkDown,
3246 .EFAULT => |err| return wsaErrorBug(err),
3247 .ENOTSOCK => |err| return wsaErrorBug(err),
3248 .EINVAL => |err| return wsaErrorBug(err),
3249 else => |err| return windows.unexpectedWSAError(err),
3250 }
3251 }
3252
3253 return .{
3254 .handle = socket_handle,
3255 .address = addressFromWsa(&storage),
3256 };
3257}
3258
31793259fn openSocketPosix(
31803260 t: *Threaded,
31813261 family: posix.sa_family_t,