1 /* 2 * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 2001 by Internet Software Consortium. 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 14 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 16 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 17 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 18 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 19 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20 * SOFTWARE. 21 */ 22 23 #pragma ident "%Z%%M% %I% %E% SMI" 24 25 #include <port_before.h> 26 #include <netdb.h> 27 #include <port_after.h> 28 29 #ifdef DO_PTHREADS 30 #include <pthread.h> 31 #include <stdlib.h> 32 #endif 33 34 static const char *gai_errlist[] = { 35 "no error", 36 "address family not supported for name",/* EAI_ADDRFAMILY */ 37 "temporary failure", /* EAI_AGAIN */ 38 "invalid flags", /* EAI_BADFLAGS */ 39 "permanent failure", /* EAI_FAIL */ 40 "address family not supported", /* EAI_FAMILY */ 41 "memory failure", /* EAI_MEMORY */ 42 "no address", /* EAI_NODATA */ 43 "unknown name or service", /* EAI_NONAME */ 44 "service not supported for socktype", /* EAI_SERVICE */ 45 "socktype not supported", /* EAI_SOCKTYPE */ 46 "system failure", /* EAI_SYSTEM */ 47 "bad hints", /* EAI_BADHINTS */ 48 "bad protocol", /* EAI_PROTOCOL */ 49 50 "unknown error" /* Must be last. */ 51 }; 52 53 static const int gai_nerr = (sizeof(gai_errlist)/sizeof(*gai_errlist)); 54 55 #define EAI_BUFSIZE 128 56 57 const char * 58 gai_strerror(int ecode) { 59 #ifndef DO_PTHREADS 60 static char buf[EAI_BUFSIZE]; 61 #else /* DO_PTHREADS */ 62 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 63 static pthread_key_t key; 64 static int once = 0; 65 char *buf; 66 #endif 67 68 if (ecode >= 0 && ecode < (gai_nerr - 1)) 69 return (gai_errlist[ecode]); 70 71 #ifdef DO_PTHREADS 72 if (!once) { 73 pthread_mutex_lock(&lock); 74 if (!once++) 75 pthread_key_create(&key, free); 76 pthread_mutex_unlock(&lock); 77 } 78 79 buf = pthread_getspecific(key); 80 if (buf == NULL) { 81 buf = malloc(EAI_BUFSIZE); 82 if (buf == NULL) 83 return ("unknown error"); 84 pthread_setspecific(key, buf); 85 } 86 #endif 87 /* 88 * XXX This really should be snprintf(buf, EAI_BUFSIZE, ...). 89 * It is safe until message catalogs are used. 90 */ 91 sprintf(buf, "%s: %d", gai_errlist[gai_nerr - 1], ecode); 92 return (buf); 93 } 94