#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", "Timed out", "The other end is not inline", "Key already in use", "Network fault", "Send to self error", "Receive from wrong end", "Service stoped", "Exceed resource limit" }; 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; char *buf; /* 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(err < EBUS_BASE) { // libc错误 if (err < 0 || err >= _sys_nerr || _sys_errlist[err] == NULL) { snprintf(buf, MAX_ERROR_LEN, "Unknown error %d", err); } else { strncpy(buf, _sys_errlist[err], MAX_ERROR_LEN - 1); buf[MAX_ERROR_LEN - 1] = '\0'; /* Ensure null termination */ } } else { //自定义错误 err -= EBUS_BASE; if (err < 0 || err >= _bus_nerr || _bus_errlist[err] == NULL) { snprintf(buf, MAX_ERROR_LEN, "Unknown error %d", err); } else { strncpy(buf, _bus_errlist[err], MAX_ERROR_LEN - 1); buf[MAX_ERROR_LEN - 1] = '\0'; /* Ensure null termination */ } } return buf; }