Coverage Report

Created: 2025-06-13 06:36

/src/json-c/strerror_override.c
Line
Count
Source (jump to first uncovered line)
1
#define STRERROR_OVERRIDE_IMPL 1
2
#include "strerror_override.h"
3
4
/*
5
 * Override strerror() to get consistent output across platforms.
6
 */
7
8
static struct
9
{
10
  int errno_value;
11
  const char *errno_str;
12
} errno_list[] = {
13
/* clang-format off */
14
#define STRINGIFY(x) #x
15
#define ENTRY(x) {x, &STRINGIFY(undef_ ## x)[6]}
16
  ENTRY(EPERM),
17
  ENTRY(ENOENT),
18
  ENTRY(ESRCH),
19
  ENTRY(EINTR),
20
  ENTRY(EIO),
21
  ENTRY(ENXIO),
22
  ENTRY(E2BIG),
23
#ifdef ENOEXEC
24
  ENTRY(ENOEXEC),
25
#endif
26
  ENTRY(EBADF),
27
  ENTRY(ECHILD),
28
  ENTRY(EDEADLK),
29
  ENTRY(ENOMEM),
30
  ENTRY(EACCES),
31
  ENTRY(EFAULT),
32
#ifdef ENOTBLK
33
  ENTRY(ENOTBLK),
34
#endif
35
  ENTRY(EBUSY),
36
  ENTRY(EEXIST),
37
  ENTRY(EXDEV),
38
  ENTRY(ENODEV),
39
  ENTRY(ENOTDIR),
40
  ENTRY(EISDIR),
41
  ENTRY(EINVAL),
42
  ENTRY(ENFILE),
43
  ENTRY(EMFILE),
44
  ENTRY(ENOTTY),
45
#ifdef ETXTBSY
46
  ENTRY(ETXTBSY),
47
#endif
48
  ENTRY(EFBIG),
49
  ENTRY(ENOSPC),
50
  ENTRY(ESPIPE),
51
  ENTRY(EROFS),
52
  ENTRY(EMLINK),
53
  ENTRY(EPIPE),
54
  ENTRY(EDOM),
55
  ENTRY(ERANGE),
56
  ENTRY(EAGAIN),
57
  { 0, (char *)0 }
58
};
59
/* clang-format on */
60
61
// Enabled during tests
62
static int _json_c_strerror_enable = 0;
63
extern char *getenv(const char *name); // Avoid including stdlib.h
64
65
0
#define PREFIX "ERRNO="
66
static char errno_buf[128] = PREFIX;
67
char *_json_c_strerror(int errno_in)
68
0
{
69
0
  int start_idx;
70
0
  char digbuf[20];
71
0
  int ii, jj;
72
73
0
  if (!_json_c_strerror_enable)
74
0
    _json_c_strerror_enable = (getenv("_JSON_C_STRERROR_ENABLE") == NULL) ? -1 : 1;
75
0
  if (_json_c_strerror_enable == -1)
76
0
    return strerror(errno_in);
77
78
  // Avoid standard functions, so we don't need to include any
79
  // headers, or guess at signatures.
80
81
0
  for (ii = 0; errno_list[ii].errno_str != (char *)0; ii++)
82
0
  {
83
0
    const char *errno_str = errno_list[ii].errno_str;
84
0
    if (errno_list[ii].errno_value != errno_in)
85
0
      continue;
86
87
0
    for (start_idx = sizeof(PREFIX) - 1, jj = 0; errno_str[jj] != '\0';
88
0
         jj++, start_idx++)
89
0
    {
90
0
      errno_buf[start_idx] = errno_str[jj];
91
0
    }
92
0
    errno_buf[start_idx] = '\0';
93
0
    return errno_buf;
94
0
  }
95
96
  // It's not one of the known errno values, return the numeric value.
97
0
  for (ii = 0; errno_in >= 10; errno_in /= 10, ii++)
98
0
  {
99
0
    digbuf[ii] = "0123456789"[(errno_in % 10)];
100
0
  }
101
0
  digbuf[ii] = "0123456789"[(errno_in % 10)];
102
103
  // Reverse the digits
104
0
  for (start_idx = sizeof(PREFIX) - 1; ii >= 0; ii--, start_idx++)
105
0
  {
106
0
    errno_buf[start_idx] = digbuf[ii];
107
0
  }
108
0
  errno_buf[start_idx] = '\0';
109
0
  return errno_buf;
110
0
}