authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-15 20:04:13-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:49-07:00
log18ec9685fbdac7e2e49cb1d0979d4aeea3775bc8
treee93c22eb62c31741b406f2067aa38990d0688ec1
parent031044b3994d4510f64bd08ecba0ab01a7ed48c6

std.Io.Threaded: add support for getaddrinfo

this API sucks but it's the best we've got on some operating systems

1 files changed, 55 insertions(+), 1 deletions(-)

lib/std/Io/Threaded.zig+55-1
......@@ -2792,7 +2792,61 @@ fn netLookupFallible(
27922792 if (builtin.link_libc) {
27932793 // This operating system lacks a way to resolve asynchronously. We are
27942794 // stuck with getaddrinfo.
2795 @compileError("TODO");
2795 var name_buffer: [HostName.max_len + 1]u8 = undefined;
2796 @memcpy(name_buffer[0..host_name.bytes.len], host_name.bytes);
2797 name_buffer[host_name.bytes.len] = 0;
2798 const name_c = name_buffer[0..host_name.bytes.len :0];
2799
2800 var port_buffer: [8]u8 = undefined;
2801 const port_c = std.fmt.bufPrintZ(&port_buffer, "{d}", .{options.port}) catch unreachable;
2802
2803 const hints: posix.addrinfo = .{
2804 .flags = .{ .NUMERICSERV = true },
2805 .family = posix.AF.UNSPEC,
2806 .socktype = posix.SOCK.STREAM,
2807 .protocol = posix.IPPROTO.TCP,
2808 .canonname = null,
2809 .addr = null,
2810 .addrlen = 0,
2811 .next = null,
2812 };
2813 var res: ?*posix.addrinfo = null;
2814 while (true) {
2815 try t.checkCancel();
2816 switch (posix.system.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res)) {
2817 @as(posix.system.EAI, @enumFromInt(0)) => {},
2818 .ADDRFAMILY => return error.AddressFamilyUnsupported,
2819 .AGAIN => return error.NameServerFailure,
2820 .FAIL => return error.NameServerFailure,
2821 .FAMILY => return error.AddressFamilyUnsupported,
2822 .MEMORY => return error.SystemResources,
2823 .NODATA => return error.UnknownHostName,
2824 .NONAME => return error.UnknownHostName,
2825 .SYSTEM => switch (posix.errno(-1)) {
2826 .INTR => continue,
2827 else => |e| return posix.unexpectedErrno(e),
2828 },
2829 else => return error.Unexpected,
2830 }
2831 }
2832 defer if (res) |some| posix.system.freeaddrinfo(some);
2833
2834 var it = res;
2835 var canon_name: ?[]const u8 = null;
2836 while (it) |info| : (it = info.next) {
2837 const addr = info.addr orelse continue;
2838 try resolved.putOne(addressFromPosix(addr));
2839
2840 if (info.canonname) |n| {
2841 if (canon_name == null) {
2842 canon_name = n;
2843 }
2844 }
2845 }
2846 if (canon_name) |n| {
2847 try resolved.putOne(.{ .canonical_name = copyCanon(options.canonical_name_buffer, n) });
2848 }
2849 return;
27962850 }
27972851
27982852 return error.OptionUnsupported;