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(...@@ -3172,10 +3172,62 @@ fn netListenUnixWindows(
3172) net.UnixAddress.ListenError!net.Socket.Handle {3172) net.UnixAddress.ListenError!net.Socket.Handle {
3173 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;3173 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
3174 const t: *Threaded = @ptrCast(@alignCast(userdata));3174 const t: *Threaded = @ptrCast(@alignCast(userdata));
3175 try t.checkCancel();3175
3176 _ = address;3176 const socket_handle = openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
3177 _ = options;3177 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
3178 @panic("TODO implement netListenUnixWindows");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;
3179}3231}
31803232
3181fn netListenUnixUnavailable(3233fn netListenUnixUnavailable(
...@@ -3493,9 +3545,37 @@ fn netConnectUnixWindows(...@@ -3493,9 +3545,37 @@ fn netConnectUnixWindows(
3493) net.UnixAddress.ConnectError!net.Socket.Handle {3545) net.UnixAddress.ConnectError!net.Socket.Handle {
3494 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;3546 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
3495 const t: *Threaded = @ptrCast(@alignCast(userdata));3547 const t: *Threaded = @ptrCast(@alignCast(userdata));
3496 try t.checkCancel();3548
3497 _ = address;3549 const socket_handle = try openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream });
3498 @panic("TODO implement netConnectUnixWindows");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;
3499}3579}
35003580
3501fn netConnectUnixUnavailable(3581fn netConnectUnixUnavailable(
...@@ -4935,6 +5015,13 @@ fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.so...@@ -4935,6 +5015,13 @@ fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.so
4935 return @sizeOf(posix.sockaddr.un);5015 return @sizeOf(posix.sockaddr.un);
4936}5016}
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
4938fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address {5025fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address {
4939 return .{5026 return .{
4940 .port = std.mem.bigToNative(u16, in.port),5027 .port = std.mem.bigToNative(u16, in.port),
lib/std/Io/net.zig+1
...@@ -879,6 +879,7 @@ pub const UnixAddress = struct {...@@ -879,6 +879,7 @@ pub const UnixAddress = struct {
879 NotDir,879 NotDir,
880 ReadOnlyFileSystem,880 ReadOnlyFileSystem,
881 WouldBlock,881 WouldBlock,
882 NetworkDown,
882 } || Io.Cancelable || Io.UnexpectedError;883 } || Io.Cancelable || Io.UnexpectedError;
883884
884 pub fn connect(ua: *const UnixAddress, io: Io) ConnectError!Stream {885 pub fn connect(ua: *const UnixAddress, io: Io) ConnectError!Stream {