From 35a94efcc6eb5a844c0e463fe0be88cd882099a8 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 15 Aug 2021 08:19:04 -0700 Subject: getaddrinfo: implement canonname. Paul A. Patience noted that the canonname_s variable is not used in the C code. This indicates that the AI_CANONNAME functionality of getaddrinfo isn't implemented. Let's do that. * stdlib/socket.tl (sockaddr): New slot, canonname. (addrinfo): Default canonname to nil, not 0, since it is a string that may be absent. * socket.c (getaddrinfo_wrap): If the first address object has a non-null ai_canonname and it was requested via the flags, then stick that name into every returned structure. * txr.1: Documented. --- socket.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index c4745241..37158052 100644 --- a/socket.c +++ b/socket.c @@ -207,7 +207,9 @@ static val getaddrinfo_wrap(val node_in, val service_in, val hints_in) uw_catch_end; if (res == 0) { + val canonname = nil; for (aiter = alist; aiter; aiter = aiter->ai_next) { + val addr = nil; switch (aiter->ai_family) { case AF_INET: { @@ -216,7 +218,7 @@ static val getaddrinfo_wrap(val node_in, val service_in, val hints_in) ipv4_addr_from_num(&sa->sin_addr, node); if (svc_num_p) sa->sin_port = htons(c_num(service, self)); - ptail = list_collect(ptail, sockaddr_in_unpack(sa)); + addr = sockaddr_in_unpack(sa); } break; case AF_INET6: @@ -226,10 +228,18 @@ static val getaddrinfo_wrap(val node_in, val service_in, val hints_in) ipv6_addr_from_num(&sa->sin6_addr, node); if (svc_num_p) sa->sin6_port = ntohs(c_num(service, self)); - ptail = list_collect(ptail, sockaddr_in6_unpack(sa)); + addr = sockaddr_in6_unpack(sa); } break; } + if (addr) { + if (aiter == alist && (hints_ai.ai_flags & AI_CANONNAME) != 0 + && aiter->ai_canonname) + canonname = string_utf8(aiter->ai_canonname); + if (canonname) + slotset(addr, canonname_s, canonname); + ptail = list_collect(ptail, addr); + } } } -- cgit v1.2.3