1 /* 2 * Copyright 2007 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_key_t key = PTHREAD_ONCE_KEY_NP; 63 char *buf; 64 #endif 65 66 if (ecode >= 0 && ecode < (gai_nerr - 1)) 67 return (gai_errlist[ecode]); 68 69 #ifdef DO_PTHREADS 70 if (pthread_key_create_once_np(&key, free) != 0) 71 goto unknown; 72 buf = pthread_getspecific(key); 73 if (buf == NULL) { 74 buf = malloc(EAI_BUFSIZE); 75 if (buf == NULL) 76 goto unknown; 77 if (pthread_setspecific(key, buf) != 0) { 78 free(buf); 79 goto unknown; 80 } 81 } 82 #endif 83 /* 84 * XXX This really should be snprintf(buf, EAI_BUFSIZE, ...). 85 * It is safe until message catalogs are used. 86 */ 87 sprintf(buf, "%s: %d", gai_errlist[gai_nerr - 1], ecode); 88 return (buf); 89 90 #ifdef DO_PTHREADS 91 unknown: 92 return ("unknown error"); 93 #endif 94 } 95