std.Io.Threaded: implement Unix sockets for Windows

This commit is contained in:
Andrew Kelley 2025-10-28 06:58:58 -07:00
parent b39f3d294d
commit c4dc7d7c3d
2 changed files with 95 additions and 7 deletions

View File

@ -3172,10 +3172,62 @@ fn netListenUnixWindows(
) net.UnixAddress.ListenError!net.Socket.Handle {
if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
const t: *Threaded = @ptrCast(@alignCast(userdata));
try t.checkCancel();
_ = address;
_ = options;
@panic("TODO implement netListenUnixWindows");
const socket_handle = openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
else => |e| return e,
};
errdefer closeSocketWindows(socket_handle);
var storage: WsaAddress = undefined;
const addr_len = addressUnixToWsa(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, .OPERATION_ABORTED => 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.listen(socket_handle, options.kernel_backlog);
if (rc != ws2_32.SOCKET_ERROR) break;
switch (ws2_32.WSAGetLastError()) {
.EINTR => continue,
.ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
.NOTINITIALISED => {
try initializeWsa(t);
continue;
},
.ENETDOWN => return error.NetworkDown,
.EADDRINUSE => return error.AddressInUse,
.EISCONN => |err| return wsaErrorBug(err),
.EINVAL => |err| return wsaErrorBug(err),
.EMFILE, .ENOBUFS => return error.SystemResources,
.ENOTSOCK => |err| return wsaErrorBug(err),
.EOPNOTSUPP => |err| return wsaErrorBug(err),
.EINPROGRESS => |err| return wsaErrorBug(err),
else => |err| return windows.unexpectedWSAError(err),
}
}
return socket_handle;
}
fn netListenUnixUnavailable(
@ -3493,9 +3545,37 @@ fn netConnectUnixWindows(
) net.UnixAddress.ConnectError!net.Socket.Handle {
if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
const t: *Threaded = @ptrCast(@alignCast(userdata));
try t.checkCancel();
_ = address;
@panic("TODO implement netConnectUnixWindows");
const socket_handle = try openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream });
errdefer closeSocketWindows(socket_handle);
var storage: WsaAddress = undefined;
const addr_len = addressUnixToWsa(address, &storage);
while (true) {
const rc = ws2_32.connect(socket_handle, &storage.any, addr_len);
if (rc != ws2_32.SOCKET_ERROR) break;
switch (ws2_32.WSAGetLastError()) {
.EINTR => continue,
.ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
.NOTINITIALISED => {
try initializeWsa(t);
continue;
},
.ECONNREFUSED => return error.FileNotFound,
.EFAULT => |err| return wsaErrorBug(err),
.EINVAL => |err| return wsaErrorBug(err),
.EISCONN => |err| return wsaErrorBug(err),
.ENOTSOCK => |err| return wsaErrorBug(err),
.EWOULDBLOCK => return error.WouldBlock,
.EACCES => return error.AccessDenied,
.ENOBUFS => return error.SystemResources,
.EAFNOSUPPORT => return error.AddressFamilyUnsupported,
else => |err| return windows.unexpectedWSAError(err),
}
}
return socket_handle;
}
fn netConnectUnixUnavailable(
@ -4935,6 +5015,13 @@ fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.so
return @sizeOf(posix.sockaddr.un);
}
fn addressUnixToWsa(a: *const net.UnixAddress, storage: *WsaAddress) i32 {
@memcpy(storage.un.path[0..a.path.len], a.path);
storage.un.family = posix.AF.UNIX;
storage.un.path[a.path.len] = 0;
return @sizeOf(posix.sockaddr.un);
}
fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address {
return .{
.port = std.mem.bigToNative(u16, in.port),

View File

@ -879,6 +879,7 @@ pub const UnixAddress = struct {
NotDir,
ReadOnlyFileSystem,
WouldBlock,
NetworkDown,
} || Io.Cancelable || Io.UnexpectedError;
pub fn connect(ua: *const UnixAddress, io: Io) ConnectError!Stream {