You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

strerror_override.c 2.1 kB

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