From 4e3dc7ce68561c16254712d713b2ccd472b8afe7 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 22 May 2006 15:20:46 +0000 Subject: Wrap strerror() in a function that makes it thread safe and converts the output to UTF-8. git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@945 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/polyp/error.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'src/polyp/error.c') diff --git a/src/polyp/error.c b/src/polyp/error.c index e78d072e..062b6f36 100644 --- a/src/polyp/error.c +++ b/src/polyp/error.c @@ -23,9 +23,23 @@ #include #endif +#include #include #include +#include +#ifdef HAVE_PTHREAD +#include +#endif + +#ifdef HAVE_WINDOWS_H +#include +#endif + +#include +#include + +#include #include #include "error.h" @@ -58,3 +72,79 @@ const char*pa_strerror(int error) { 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; +} -- cgit