#include "usg_common.h"
|
#include "bus_error.h"
|
|
#define MAX_ERROR_LEN 256 /* Maximum length of string in per-thread
|
buffer returned by strerror() */
|
#define _bus_nerr 256
|
|
int bus_errno;
|
|
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
static pthread_key_t strerrorKey;
|
|
|
static char *_bus_errlist[_bus_nerr] = {
|
"\0",
|
"timeout",
|
"The other end is not inline",
|
"Key already in use"
|
|
};
|
|
static void /* Free thread-specific data buffer */
|
destructor(void *buf)
|
{
|
free(buf);
|
}
|
|
static void /* One-time key creation function */
|
createKey(void)
|
{
|
int s;
|
|
/* Allocate a unique thread-specific data key and save the address
|
of the destructor for thread-specific data buffers */
|
|
s = pthread_key_create(&strerrorKey, destructor);
|
if (s != 0)
|
err_exit(s, "pthread_key_create");
|
}
|
|
char *
|
bus_strerror(int err)
|
{
|
int s, eindex;
|
char *buf;
|
eindex = err - 10000;
|
/* Make first caller allocate key for thread-specific data */
|
|
s = pthread_once(&once, createKey);
|
if (s != 0)
|
err_exit(s, "pthread_once");
|
|
buf = (char *)pthread_getspecific(strerrorKey);
|
if (buf == NULL)
|
{
|
/* If first call from this thread, allocate
|
buffer for thread, and save its location */
|
buf = (char *)malloc(MAX_ERROR_LEN);
|
if (buf == NULL)
|
err_exit(errno, "malloc");
|
|
s = pthread_setspecific(strerrorKey, buf);
|
if (s != 0)
|
err_exit(s, "pthread_setspecific");
|
}
|
|
if (eindex < 0 || eindex >= _bus_nerr || _bus_errlist[eindex] == NULL)
|
{
|
snprintf(buf, MAX_ERROR_LEN, "Unknown error %d", eindex);
|
}
|
else
|
{
|
strncpy(buf, _bus_errlist[eindex], MAX_ERROR_LEN - 1);
|
buf[MAX_ERROR_LEN - 1] = '\0'; /* Ensure null termination */
|
}
|
|
return buf;
|
}
|