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
This commit is contained in:
Pierre Ossman 2006-05-22 15:20:46 +00:00
parent bf09399d0e
commit 4e3dc7ce68
49 changed files with 337 additions and 169 deletions

View file

@ -29,6 +29,7 @@
#include <errno.h>
#include <string.h>
#include <polyp/error.h>
#include <polyp/xmalloc.h>
#include <polypcore/log.h>
@ -123,7 +124,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) {
pa_open_config_file(DEFAULT_CLIENT_CONFIG_FILE, DEFAULT_CLIENT_CONFIG_FILE_USER, ENV_CLIENT_CONFIG_FILE, &fn, "r");
if (!f && errno != EINTR) {
pa_log(__FILE__": WARNING: failed to open configuration file '%s': %s", filename, strerror(errno));
pa_log(__FILE__": WARNING: failed to open configuration file '%s': %s", filename, pa_cstrerror(errno));
goto finish;
}

View file

@ -47,6 +47,7 @@
#include "../polypcore/winsock.h"
#include <polyp/error.h>
#include <polyp/version.h>
#include <polyp/xmalloc.h>
@ -440,7 +441,7 @@ static int context_connect_spawn(pa_context *c) {
pa_context_ref(c);
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
pa_log(__FILE__": socketpair() failed: %s", strerror(errno));
pa_log(__FILE__": socketpair(): %s", pa_cstrerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
goto fail;
}
@ -454,7 +455,7 @@ static int context_connect_spawn(pa_context *c) {
c->spawn_api.prefork();
if ((pid = fork()) < 0) {
pa_log(__FILE__": fork() failed: %s", strerror(errno));
pa_log(__FILE__": fork(): %s", pa_cstrerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
if (c->spawn_api.postfork)
@ -510,7 +511,7 @@ static int context_connect_spawn(pa_context *c) {
c->spawn_api.postfork();
if (r < 0) {
pa_log(__FILE__": waitpid() failed: %s", strerror(errno));
pa_log(__FILE__": waitpid(): %s", pa_cstrerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
goto fail;
} else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {

View file

@ -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;
}

View file

@ -33,6 +33,12 @@ PA_C_DECL_BEGIN
/** Return a human readable error message for the specified numeric error code */
const char* pa_strerror(int error);
/** A wrapper around the standard strerror() function that converts the
* string to UTF-8. The function is thread safe but the returned string is
* only guaranteed to exist until the thread exits or pa_cstrerror() is
* called again from the same thread. */
char* pa_cstrerror(int errnum);
PA_C_DECL_END
#endif

View file

@ -36,6 +36,7 @@
#include <windows.h>
#endif
#include <polyp/error.h>
#include <polyp/xmalloc.h>
#include <polypcore/core-util.h>
@ -89,7 +90,7 @@ static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags
if (errno == EAGAIN)
return;
pa_log(__FILE__": read(): %s", strerror(errno));
pa_log(__FILE__": read(): %s", pa_cstrerror(errno));
return;
}
@ -106,7 +107,7 @@ int pa_signal_init(pa_mainloop_api *a) {
assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event);
if (pipe(signal_pipe) < 0) {
pa_log(__FILE__": pipe() failed: %s", strerror(errno));
pa_log(__FILE__": pipe(): %s", pa_cstrerror(errno));
return -1;
}

View file

@ -44,6 +44,7 @@
#include "../polypcore/pipe.h"
#endif
#include <polyp/error.h>
#include <polyp/timeval.h>
#include <polyp/xmalloc.h>
@ -689,7 +690,7 @@ int pa_mainloop_poll(pa_mainloop *m) {
if (errno == EINTR)
r = 0;
else
pa_log(__FILE__": poll(): %s", strerror(errno));
pa_log(__FILE__": poll(): %s", pa_cstrerror(errno));
}
}

View file

@ -51,6 +51,8 @@
#include "../polypcore/winsock.h"
#include <polyp/error.h>
#include <polypcore/log.h>
#include <polypcore/core-util.h>
@ -107,7 +109,7 @@ char *pa_get_user_name(char *s, size_t l) {
char *pa_get_host_name(char *s, size_t l) {
assert(s && l > 0);
if (gethostname(s, l) < 0) {
pa_log(__FILE__": gethostname(): %s", strerror(errno));
pa_log(__FILE__": gethostname(): %s", pa_cstrerror(errno));
return NULL;
}
s[l-1] = 0;