authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-23 04:14:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:51-07:00
logf17c6bba579e2c8929bf37a5980b37ebe9ccc517
treeaa879c0fba2858078001937c61971c8063c603a7
parent9d6750f01ccef0d4dfb6fc69a2011d83a18fd325

std.Io.Kqueue: implement netConnect


1 files changed, 50 insertions(+), 4 deletions(-)

lib/std/Io/Kqueue.zig+50-4
......@@ -1265,12 +1265,57 @@ fn netBindIp(
12651265 };
12661266}
12671267fn netConnectIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.ConnectOptions) net.IpAddress.ConnectError!net.Stream {
1268 if (options.timeout != .none) @panic("TODO");
12681269 const k: *Kqueue = @ptrCast(@alignCast(userdata));
1269 _ = k;
1270 _ = address;
1271 _ = options;
1272 @panic("TODO");
1270 const family = Io.Threaded.posixAddressFamily(address);
1271 const socket_fd = try openSocketPosix(k, family, .{
1272 .mode = options.mode,
1273 .protocol = options.protocol,
1274 });
1275 errdefer posix.close(socket_fd);
1276 var storage: Io.Threaded.PosixAddress = undefined;
1277 var addr_len = Io.Threaded.addressToPosix(address, &storage);
1278 try posixConnect(k, socket_fd, &storage.any, addr_len);
1279 try posixGetSockName(k, socket_fd, &storage.any, &addr_len);
1280 return .{ .socket = .{
1281 .handle = socket_fd,
1282 .address = Io.Threaded.addressFromPosix(&storage),
1283 } };
12731284}
1285
1286fn posixConnect(k: *Kqueue, socket_fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {
1287 while (true) {
1288 try k.checkCancel();
1289 switch (posix.errno(posix.system.connect(socket_fd, addr, addr_len))) {
1290 .SUCCESS => return,
1291 .INTR => continue,
1292 .CANCELED => return error.Canceled,
1293 .AGAIN => @panic("TODO"),
1294 .INPROGRESS => return, // Due to TCP fast open, we find out possible error later.
1295
1296 .ADDRNOTAVAIL => return error.AddressUnavailable,
1297 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
1298 .ALREADY => return error.ConnectionPending,
1299 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
1300 .CONNREFUSED => return error.ConnectionRefused,
1301 .CONNRESET => return error.ConnectionResetByPeer,
1302 .FAULT => |err| return errnoBug(err),
1303 .ISCONN => |err| return errnoBug(err),
1304 .HOSTUNREACH => return error.HostUnreachable,
1305 .NETUNREACH => return error.NetworkUnreachable,
1306 .NOTSOCK => |err| return errnoBug(err),
1307 .PROTOTYPE => |err| return errnoBug(err),
1308 .TIMEDOUT => return error.Timeout,
1309 .CONNABORTED => |err| return errnoBug(err),
1310 .ACCES => return error.AccessDenied,
1311 .PERM => |err| return errnoBug(err),
1312 .NOENT => |err| return errnoBug(err),
1313 .NETDOWN => return error.NetworkDown,
1314 else => |err| return posix.unexpectedErrno(err),
1315 }
1316 }
1317}
1318
12741319fn netListenUnix(
12751320 userdata: ?*anyopaque,
12761321 unix_address: *const net.UnixAddress,
......@@ -1343,6 +1388,7 @@ fn netSendOne(
13431388 },
13441389 .INTR => continue,
13451390 .CANCELED => return error.Canceled,
1391 .AGAIN => @panic("TODO register kevent"),
13461392
13471393 .ACCES => return error.AccessDenied,
13481394 .ALREADY => return error.FastOpenAlreadyInProgress,