/* $Id$ */ /*** This file is part of polypaudio. polypaudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. polypaudio is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with polypaudio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ***/ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #ifdef HAVE_PTHREAD #include #endif #ifdef HAVE_WINDOWS_H #include #endif #include #include #include #include #include "error.h" static const char* const errortab[PA_ERR_MAX] = { [PA_OK] = "OK", [PA_ERR_ACCESS] = "Access denied", [PA_ERR_COMMAND] = "Unknown command", [PA_ERR_INVALID] = "Invalid argument", [PA_ERR_EXIST] = "Entity exists", [PA_ERR_NOENTITY] = "No such entity", [PA_ERR_CONNECTIONREFUSED] = "Connection refused", [PA_ERR_PROTOCOL] = "Protocol error", [PA_ERR_TIMEOUT] = "Timeout", [PA_ERR_AUTHKEY] = "No authorization key", [PA_ERR_INTERNAL] = "Internal error", [PA_ERR_CONNECTIONTERMINATED] = "Connection terminated", [PA_ERR_KILLED] = "Entity killed", [PA_ERR_INVALIDSERVER] = "Invalid server", [PA_ERR_MODINITFAILED] = "Module initalization failed", [PA_ERR_BADSTATE] = "Bad state", [PA_ERR_NODATA] = "No data", [PA_ERR_VERSION] = "Incompatible protocol version", [PA_ERR_TOOLARGE] = "Too large" }; const char*pa_strerror(int error) { if (error < 0 || error >= PA_ERR_MAX) return NULL; return errortab[error]; } #ifdef HAVE_PTHREAD static pthread_once_t cstrerror_once = PTHREAD_ONCE_INIT; static pthread_key_t tlsstr_key; static void inittls(void) { int ret; ret = pthread_key_create(&tlsstr_key, pa_xfree); if (ret) { fprintf(stderr, __FILE__ ": CRITICAL: Unable to allocate TLS key (%d)\n", errno); exit(-1); } } #elif HAVE_WINDOWS_H static __declspec(thread) char *tlsstr; #else /* Unsafe, but we have no choice */ static char *tlsstr; #endif char* pa_cstrerror(int errnum) { const char *origbuf; #ifdef HAVE_STRERROR_R char errbuf[128]; #endif #ifdef HAVE_PTHREAD char *tlsstr; pthread_once(&cstrerror_once, inittls); tlsstr = pthread_getspecific(tlsstr_key); #endif if (tlsstr) pa_xfree(tlsstr); #ifdef HAVE_STRERROR_R #ifdef __GLIBC__ origbuf = strerror_r(errnum, errbuf, sizeof(errbuf)); if (origbuf == NULL) origbuf = ""; #else if (strerror_r(errnum, errbuf, sizeof(errbuf)) == 0) { origbuf = errbuf; errbuf[sizeof(errbuf) - 1] = '\0'; } else origbuf = ""; #endif #else /* This might not be thread safe, but we hope for the best */ origbuf = strerror(errnum); #endif tlsstr = pa_locale_to_utf8(origbuf); if (!tlsstr) { fprintf(stderr, "Unable to convert, filtering\n"); tlsstr = pa_utf8_filter(origbuf); } #ifdef HAVE_PTHREAD pthread_setspecific(tlsstr_key, tlsstr); #endif return tlsstr; }