#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 const 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", "Service not supported", "Resource busy", "Resource not provide", "Invalid parameters", "No enough memory" }; 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 flag) { 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 + sizeof(int)); if (buf == NULL) err_exit(errno, "malloc"); memset(buf, 0x00, MAX_ERROR_LEN + sizeof(int)); s = pthread_setspecific(strerrorKey, buf); if (s != 0) err_exit(s, "pthread_setspecific"); } if (flag != 0) { err = *(int *)(buf + MAX_ERROR_LEN); } if (err == 0) { err = EBUS_BASE; } 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; } void bus_errorset(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 + sizeof(int)); if (buf == NULL) err_exit(errno, "malloc"); s = pthread_setspecific(strerrorKey, buf); if (s != 0) err_exit(s, "pthread_setspecific"); } *(int *)(buf + MAX_ERROR_LEN) = err; }