summaryrefslogtreecommitdiffstats
path: root/src/polyp/error.c
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2006-05-22 15:20:46 +0000
committerPierre Ossman <ossman@cendio.se>2006-05-22 15:20:46 +0000
commit4e3dc7ce68561c16254712d713b2ccd472b8afe7 (patch)
tree2b0494e14605f3f3e133765126eaee3c77c8b482 /src/polyp/error.c
parentbf09399d0e84c43fbae3d24b5c71dc8d85b62fe7 (diff)
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
Diffstat (limited to 'src/polyp/error.c')
-rw-r--r--src/polyp/error.c90
1 files changed, 90 insertions, 0 deletions
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 <config.h>
#endif
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#include <polyp/utf8.h>
+#include <polyp/xmalloc.h>
+
+#include <polypcore/core-util.h>
#include <polypcore/native-common.h>
#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;
+}