wangzhengquan
2021-01-15 42d1c7ef91627d5ac920c8fa35573970ac1bd2d5
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
#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;
}