diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2025-10-15 20:04:13 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-10-29 06:20:49 -0700 |
| commit | 18ec9685fbdac7e2e49cb1d0979d4aeea3775bc8 (patch) | |
| tree | e93c22eb62c31741b406f2067aa38990d0688ec1 /lib/std | |
| parent | 031044b3994d4510f64bd08ecba0ab01a7ed48c6 (diff) | |
| download | zig-18ec9685fbdac7e2e49cb1d0979d4aeea3775bc8.tar.gz zig-18ec9685fbdac7e2e49cb1d0979d4aeea3775bc8.zip | |
std.Io.Threaded: add support for getaddrinfo
this API sucks but it's the best we've got on some operating systems
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/Io/Threaded.zig | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index 6ceebc79e1..50cc10a765 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -2792,7 +2792,61 @@ fn netLookupFallible( if (builtin.link_libc) { // This operating system lacks a way to resolve asynchronously. We are // stuck with getaddrinfo. - @compileError("TODO"); + var name_buffer: [HostName.max_len + 1]u8 = undefined; + @memcpy(name_buffer[0..host_name.bytes.len], host_name.bytes); + name_buffer[host_name.bytes.len] = 0; + const name_c = name_buffer[0..host_name.bytes.len :0]; + + var port_buffer: [8]u8 = undefined; + const port_c = std.fmt.bufPrintZ(&port_buffer, "{d}", .{options.port}) catch unreachable; + + const hints: posix.addrinfo = .{ + .flags = .{ .NUMERICSERV = true }, + .family = posix.AF.UNSPEC, + .socktype = posix.SOCK.STREAM, + .protocol = posix.IPPROTO.TCP, + .canonname = null, + .addr = null, + .addrlen = 0, + .next = null, + }; + var res: ?*posix.addrinfo = null; + while (true) { + try t.checkCancel(); + switch (posix.system.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res)) { + @as(posix.system.EAI, @enumFromInt(0)) => {}, + .ADDRFAMILY => return error.AddressFamilyUnsupported, + .AGAIN => return error.NameServerFailure, + .FAIL => return error.NameServerFailure, + .FAMILY => return error.AddressFamilyUnsupported, + .MEMORY => return error.SystemResources, + .NODATA => return error.UnknownHostName, + .NONAME => return error.UnknownHostName, + .SYSTEM => switch (posix.errno(-1)) { + .INTR => continue, + else => |e| return posix.unexpectedErrno(e), + }, + else => return error.Unexpected, + } + } + defer if (res) |some| posix.system.freeaddrinfo(some); + + var it = res; + var canon_name: ?[]const u8 = null; + while (it) |info| : (it = info.next) { + const addr = info.addr orelse continue; + try resolved.putOne(addressFromPosix(addr)); + + if (info.canonname) |n| { + if (canon_name == null) { + canon_name = n; + } + } + } + if (canon_name) |n| { + try resolved.putOne(.{ .canonical_name = copyCanon(options.canonical_name_buffer, n) }); + } + return; } return error.OptionUnsupported; |
