#include <freeradius-devel/ident.h>
RCSID("$Id$")
#include <freeradius-devel/libradius.h>
#define FR_STRERROR_BUFSIZE (1024)
#ifdef HAVE_THREAD_TLS
#define THREAD_TLS __thread
#elif defined(HAVE_DECLSPEC_THREAD)
#define THREAD_TLS __declspec(thread)
#else
#define THREAD_TLS
#ifdef HAVE_PTHREAD_H
#define USE_PTHREAD_FOR_TLS (1)
#endif
#endif
#ifndef USE_PTHREAD_FOR_TLS
static THREAD_TLS char fr_strerror_buffer[FR_STRERROR_BUFSIZE];
#else
#include <pthread.h>
static pthread_key_t fr_strerror_key;
static pthread_once_t fr_strerror_once = PTHREAD_ONCE_INIT;
static void fr_strerror_make_key(void)
{
pthread_key_create(&fr_strerror_key, NULL);
}
#endif
void fr_strerror_printf(const char *fmt, ...)
{
va_list ap;
#ifdef USE_PTHREAD_FOR_TLS
char *buffer;
pthread_once(&fr_strerror_once, fr_strerror_make_key);
buffer = pthread_getspecific(fr_strerror_key);
if (!buffer) {
buffer = malloc(FR_STRERROR_BUFSIZE);
if (!buffer) return;
pthread_setspecific(fr_strerror_key, buffer);
}
va_start(ap, fmt);
vsnprintf(buffer, FR_STRERROR_BUFSIZE, fmt, ap);
#else
va_start(ap, fmt);
vsnprintf(fr_strerror_buffer, sizeof(fr_strerror_buffer), fmt, ap);
#endif
va_end(ap);
}
const char *fr_strerror(void)
{
#ifndef USE_PTHREAD_FOR_TLS
return fr_strerror_buffer;
#else
const char *msg;
pthread_once(&fr_strerror_once, fr_strerror_make_key);
msg = pthread_getspecific(fr_strerror_key);
if (msg) return msg;
return "(unknown error)";
#endif
}
void fr_perror(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
if (strchr(fmt, ':') == NULL)
fprintf(stderr, ": ");
fprintf(stderr, "%s\n", fr_strerror());
va_end(ap);
}