in demo_example/asio/asio/detail/impl/socket_ops.ipp [3536:3662]
inline asio::error_code getnameinfo_emulation(
const socket_addr_type* sa, std::size_t salen, char* host,
std::size_t hostlen, char* serv, std::size_t servlen, int flags,
asio::error_code& ec)
{
using namespace std;
const char* addr;
size_t addr_len;
unsigned short port;
switch (sa->sa_family)
{
case ASIO_OS_DEF(AF_INET):
if (salen != sizeof(sockaddr_in4_type))
{
return ec = asio::error::invalid_argument;
}
addr = reinterpret_cast<const char*>(
&reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_addr);
addr_len = sizeof(in4_addr_type);
port = reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_port;
break;
case ASIO_OS_DEF(AF_INET6):
if (salen != sizeof(sockaddr_in6_type))
{
return ec = asio::error::invalid_argument;
}
addr = reinterpret_cast<const char*>(
&reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_addr);
addr_len = sizeof(in6_addr_type);
port = reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_port;
break;
default:
return ec = asio::error::address_family_not_supported;
}
if (host && hostlen > 0)
{
if (flags & NI_NUMERICHOST)
{
if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0)
{
return ec;
}
}
else
{
hostent hent;
char hbuf[8192] = "";
hostent* hptr = socket_ops::gethostbyaddr(addr,
static_cast<int>(addr_len), sa->sa_family,
&hent, hbuf, sizeof(hbuf), ec);
if (hptr && hptr->h_name && hptr->h_name[0] != '\0')
{
if (flags & NI_NOFQDN)
{
char* dot = strchr(hptr->h_name, '.');
if (dot)
{
*dot = 0;
}
}
gai_strcpy(host, hptr->h_name, hostlen);
socket_ops::freehostent(hptr);
}
else
{
socket_ops::freehostent(hptr);
if (flags & NI_NAMEREQD)
{
return ec = asio::error::host_not_found;
}
if (socket_ops::inet_ntop(sa->sa_family,
addr, host, hostlen, 0, ec) == 0)
{
return ec;
}
}
}
}
if (serv && servlen > 0)
{
if (flags & NI_NUMERICSERV)
{
if (servlen < 6)
{
return ec = asio::error::no_buffer_space;
}
#if defined(ASIO_HAS_SECURE_RTL)
sprintf_s(serv, servlen, "%u", ntohs(port));
#else // defined(ASIO_HAS_SECURE_RTL)
sprintf(serv, "%u", ntohs(port));
#endif // defined(ASIO_HAS_SECURE_RTL)
}
else
{
#if defined(ASIO_HAS_PTHREADS)
static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
::pthread_mutex_lock(&mutex);
#endif // defined(ASIO_HAS_PTHREADS)
servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0);
if (sptr && sptr->s_name && sptr->s_name[0] != '\0')
{
gai_strcpy(serv, sptr->s_name, servlen);
}
else
{
if (servlen < 6)
{
return ec = asio::error::no_buffer_space;
}
#if defined(ASIO_HAS_SECURE_RTL)
sprintf_s(serv, servlen, "%u", ntohs(port));
#else // defined(ASIO_HAS_SECURE_RTL)
sprintf(serv, "%u", ntohs(port));
#endif // defined(ASIO_HAS_SECURE_RTL)
}
#if defined(ASIO_HAS_PTHREADS)
::pthread_mutex_unlock(&mutex);
#endif // defined(ASIO_HAS_PTHREADS)
}
}
ec.assign(0, ec.category());
return ec;
}