asio::error_code getaddrinfo()

in demo_example/asio/asio/detail/impl/socket_ops.ipp [3705:3770]


asio::error_code getaddrinfo(const char* host,
    const char* service, const addrinfo_type& hints,
    addrinfo_type** result, asio::error_code& ec)
{
  host = (host && *host) ? host : 0;
  service = (service && *service) ? service : 0;
  clear_last_error();
#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
# if defined(ASIO_HAS_GETADDRINFO)
  // Building for Windows XP, Windows Server 2003, or later.
  int error = ::getaddrinfo(host, service, &hints, result);
  return ec = translate_addrinfo_error(error);
# else
  // Building for Windows 2000 or earlier.
  typedef int (WSAAPI *gai_t)(const char*,
      const char*, const addrinfo_type*, addrinfo_type**);
  if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
  {
    if (gai_t gai = (gai_t)::GetProcAddress(winsock_module, "getaddrinfo"))
    {
      int error = gai(host, service, &hints, result);
      return ec = translate_addrinfo_error(error);
    }
  }
  int error = getaddrinfo_emulation(host, service, &hints, result);
  return ec = translate_addrinfo_error(error);
# endif
#elif !defined(ASIO_HAS_GETADDRINFO)
  int error = getaddrinfo_emulation(host, service, &hints, result);
  return ec = translate_addrinfo_error(error);
#else
  int error = ::getaddrinfo(host, service, &hints, result);
#if defined(__MACH__) && defined(__APPLE__)
  using namespace std; // For isdigit and atoi.
  if (error == 0 && service && isdigit(static_cast<unsigned char>(service[0])))
  {
    u_short_type port = host_to_network_short(atoi(service));
    for (addrinfo_type* ai = *result; ai; ai = ai->ai_next)
    {
      switch (ai->ai_family)
      {
      case ASIO_OS_DEF(AF_INET):
        {
          sockaddr_in4_type* sinptr =
            reinterpret_cast<sockaddr_in4_type*>(ai->ai_addr);
          if (sinptr->sin_port == 0)
            sinptr->sin_port = port;
          break;
        }
      case ASIO_OS_DEF(AF_INET6):
        {
          sockaddr_in6_type* sin6ptr =
            reinterpret_cast<sockaddr_in6_type*>(ai->ai_addr);
          if (sin6ptr->sin6_port == 0)
            sin6ptr->sin6_port = port;
          break;
        }
      default:
        break;
      }
    }
  }
#endif
  return ec = translate_addrinfo_error(error);
#endif
}