authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-28 06:58:58-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:52-07:00
logc4dc7d7c3d4eade5f1092eb5c4af9bf45e3e2fda
tree8f56577d827cb0883180e0d8d662d79fab7e2a84
parentb39f3d294da3ce9075bbc08651965615839219f2

std.Io.Threaded: implement Unix sockets for Windows


2 files changed, 95 insertions(+), 7 deletions(-)

lib/std/Io/Threaded.zig+94-7
......@@ -3172,10 +3172,62 @@ fn netListenUnixWindows(
31723172) net.UnixAddress.ListenError!net.Socket.Handle {
31733173 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
31743174 const t: *Threaded = @ptrCast(@alignCast(userdata));
3175 try t.checkCancel();
3176 _ = address;
3177 _ = options;
3178 @panic("TODO implement netListenUnixWindows");
3175
3176 const socket_handle = openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
3177 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
3178 else => |e| return e,
3179 };
3180 errdefer closeSocketWindows(socket_handle);
3181
3182 var storage: WsaAddress = undefined;
3183 const addr_len = addressUnixToWsa(address, &storage);
3184
3185 while (true) {
3186 try t.checkCancel();
3187 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
3188 if (rc != ws2_32.SOCKET_ERROR) break;
3189 switch (ws2_32.WSAGetLastError()) {
3190 .EINTR => continue,
3191 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3192 .NOTINITIALISED => {
3193 try initializeWsa(t);
3194 continue;
3195 },
3196 .EADDRINUSE => return error.AddressInUse,
3197 .EADDRNOTAVAIL => return error.AddressUnavailable,
3198 .ENOTSOCK => |err| return wsaErrorBug(err),
3199 .EFAULT => |err| return wsaErrorBug(err),
3200 .EINVAL => |err| return wsaErrorBug(err),
3201 .ENOBUFS => return error.SystemResources,
3202 .ENETDOWN => return error.NetworkDown,
3203 else => |err| return windows.unexpectedWSAError(err),
3204 }
3205 }
3206
3207 while (true) {
3208 try t.checkCancel();
3209 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);
3210 if (rc != ws2_32.SOCKET_ERROR) break;
3211 switch (ws2_32.WSAGetLastError()) {
3212 .EINTR => continue,
3213 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3214 .NOTINITIALISED => {
3215 try initializeWsa(t);
3216 continue;
3217 },
3218 .ENETDOWN => return error.NetworkDown,
3219 .EADDRINUSE => return error.AddressInUse,
3220 .EISCONN => |err| return wsaErrorBug(err),
3221 .EINVAL => |err| return wsaErrorBug(err),
3222 .EMFILE, .ENOBUFS => return error.SystemResources,
3223 .ENOTSOCK => |err| return wsaErrorBug(err),
3224 .EOPNOTSUPP => |err| return wsaErrorBug(err),
3225 .EINPROGRESS => |err| return wsaErrorBug(err),
3226 else => |err| return windows.unexpectedWSAError(err),
3227 }
3228 }
3229
3230 return socket_handle;
31793231}
31803232
31813233fn netListenUnixUnavailable(
......@@ -3493,9 +3545,37 @@ fn netConnectUnixWindows(
34933545) net.UnixAddress.ConnectError!net.Socket.Handle {
34943546 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
34953547 const t: *Threaded = @ptrCast(@alignCast(userdata));
3496 try t.checkCancel();
3497 _ = address;
3498 @panic("TODO implement netConnectUnixWindows");
3548
3549 const socket_handle = try openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream });
3550 errdefer closeSocketWindows(socket_handle);
3551 var storage: WsaAddress = undefined;
3552 const addr_len = addressUnixToWsa(address, &storage);
3553
3554 while (true) {
3555 const rc = ws2_32.connect(socket_handle, &storage.any, addr_len);
3556 if (rc != ws2_32.SOCKET_ERROR) break;
3557 switch (ws2_32.WSAGetLastError()) {
3558 .EINTR => continue,
3559 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
3560 .NOTINITIALISED => {
3561 try initializeWsa(t);
3562 continue;
3563 },
3564
3565 .ECONNREFUSED => return error.FileNotFound,
3566 .EFAULT => |err| return wsaErrorBug(err),
3567 .EINVAL => |err| return wsaErrorBug(err),
3568 .EISCONN => |err| return wsaErrorBug(err),
3569 .ENOTSOCK => |err| return wsaErrorBug(err),
3570 .EWOULDBLOCK => return error.WouldBlock,
3571 .EACCES => return error.AccessDenied,
3572 .ENOBUFS => return error.SystemResources,
3573 .EAFNOSUPPORT => return error.AddressFamilyUnsupported,
3574 else => |err| return windows.unexpectedWSAError(err),
3575 }
3576 }
3577
3578 return socket_handle;
34993579}
35003580
35013581fn netConnectUnixUnavailable(
......@@ -4935,6 +5015,13 @@ fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.so
49355015 return @sizeOf(posix.sockaddr.un);
49365016}
49375017
5018fn addressUnixToWsa(a: *const net.UnixAddress, storage: *WsaAddress) i32 {
5019 @memcpy(storage.un.path[0..a.path.len], a.path);
5020 storage.un.family = posix.AF.UNIX;
5021 storage.un.path[a.path.len] = 0;
5022 return @sizeOf(posix.sockaddr.un);
5023}
5024
49385025fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address {
49395026 return .{
49405027 .port = std.mem.bigToNative(u16, in.port),
lib/std/Io/net.zig+1
......@@ -879,6 +879,7 @@ pub const UnixAddress = struct {
879879 NotDir,
880880 ReadOnlyFileSystem,
881881 WouldBlock,
882 NetworkDown,
882883 } || Io.Cancelable || Io.UnexpectedError;
883884
884885 pub fn connect(ua: *const UnixAddress, io: Io) ConnectError!Stream {