#include <port_before.h>
#include <netdb.h>
#include <port_after.h>
#ifdef DO_PTHREADS
#include <pthread.h>
#include <stdlib.h>
#endif
static const char *gai_errlist[] = {
"no error",
"address family not supported for name",
"temporary failure",
"invalid flags",
"permanent failure",
"address family not supported",
"memory failure",
"no address",
"unknown name or service",
"service not supported for socktype",
"socktype not supported",
"system failure",
"bad hints",
"bad protocol",
"unknown error"
};
static const int gai_nerr = (sizeof(gai_errlist)/sizeof(*gai_errlist));
#define EAI_BUFSIZE 128
const char *
gai_strerror(int ecode) {
#ifndef DO_PTHREADS
static char buf[EAI_BUFSIZE];
#else
#ifndef LIBBIND_MUTEX_INITIALIZER
#define LIBBIND_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#endif
static pthread_mutex_t lock = LIBBIND_MUTEX_INITIALIZER;
static pthread_key_t key;
static int once = 0;
char *buf;
#endif
if (ecode >= 0 && ecode < (gai_nerr - 1))
return (gai_errlist[ecode]);
#ifdef DO_PTHREADS
if (!once) {
if (pthread_mutex_lock(&lock) != 0)
goto unknown;
if (!once) {
if (pthread_key_create(&key, free) != 0)
goto unknown;
once = 1;
}
if (pthread_mutex_unlock(&lock) != 0)
goto unknown;
}
buf = pthread_getspecific(key);
if (buf == NULL) {
buf = malloc(EAI_BUFSIZE);
if (buf == NULL)
goto unknown;
if (pthread_setspecific(key, buf) != 0) {
free(buf);
goto unknown;
}
}
#endif
sprintf(buf, "%s: %d", gai_errlist[gai_nerr - 1], ecode);
return (buf);
#ifdef DO_PTHREADS
unknown:
return ("unknown error");
#endif
}