Fu Juntang
2021-09-17 5c912c70e9333298ff48f7ea15424f72ca977b99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#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;
 
}