strerror_r.m4 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. # strerror_r.m4 serial 20
  2. dnl Copyright (C) 2002, 2007-2021 Free Software Foundation, Inc.
  3. dnl This file is free software; the Free Software Foundation
  4. dnl gives unlimited permission to copy and/or distribute it,
  5. dnl with or without modifications, as long as this notice is preserved.
  6. AC_DEFUN([gl_FUNC_STRERROR_R],
  7. [
  8. AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
  9. AC_REQUIRE([gl_FUNC_STRERROR_R_WORKS])
  10. dnl Persuade Solaris <string.h> to declare strerror_r().
  11. AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
  12. dnl Some systems don't declare strerror_r() if _THREAD_SAFE and _REENTRANT
  13. dnl are not defined.
  14. AC_CHECK_DECLS_ONCE([strerror_r])
  15. if test $ac_cv_have_decl_strerror_r = no; then
  16. HAVE_DECL_STRERROR_R=0
  17. fi
  18. if test $ac_cv_func_strerror_r = yes; then
  19. if test "$ERRNO_H:$REPLACE_STRERROR_0" = :0; then
  20. if test $gl_cv_func_strerror_r_posix_signature = yes; then
  21. case "$gl_cv_func_strerror_r_works" in
  22. dnl The system's strerror_r has bugs. Replace it.
  23. *no) REPLACE_STRERROR_R=1 ;;
  24. esac
  25. else
  26. dnl The system's strerror_r() has a wrong signature. Replace it.
  27. REPLACE_STRERROR_R=1
  28. fi
  29. else
  30. dnl The system's strerror_r() cannot know about the new errno values we
  31. dnl add to <errno.h>, or any fix for strerror(0). Replace it.
  32. REPLACE_STRERROR_R=1
  33. fi
  34. fi
  35. ])
  36. # Prerequisites of lib/strerror_r.c.
  37. AC_DEFUN([gl_PREREQ_STRERROR_R], [
  38. dnl glibc >= 2.3.4 and cygwin 1.7.9 have a function __xpg_strerror_r.
  39. AC_CHECK_FUNCS_ONCE([__xpg_strerror_r])
  40. AC_CHECK_FUNCS_ONCE([catgets])
  41. AC_CHECK_FUNCS_ONCE([snprintf])
  42. ])
  43. # Detect if strerror_r works, but without affecting whether a replacement
  44. # strerror_r will be used.
  45. AC_DEFUN([gl_FUNC_STRERROR_R_WORKS],
  46. [
  47. AC_REQUIRE([gl_HEADER_ERRNO_H])
  48. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  49. AC_REQUIRE([gl_FUNC_STRERROR_0])
  50. AC_CHECK_FUNCS_ONCE([strerror_r])
  51. if test $ac_cv_func_strerror_r = yes; then
  52. if test "$ERRNO_H:$REPLACE_STRERROR_0" = :0; then
  53. dnl The POSIX prototype is: int strerror_r (int, char *, size_t);
  54. dnl glibc, Cygwin: char *strerror_r (int, char *, size_t);
  55. dnl AIX 5.1, OSF/1 5.1: int strerror_r (int, char *, int);
  56. AC_CACHE_CHECK([for strerror_r with POSIX signature],
  57. [gl_cv_func_strerror_r_posix_signature],
  58. [AC_COMPILE_IFELSE(
  59. [AC_LANG_PROGRAM(
  60. [[#include <string.h>
  61. int strerror_r (int, char *, size_t);
  62. ]],
  63. [])],
  64. [gl_cv_func_strerror_r_posix_signature=yes],
  65. [gl_cv_func_strerror_r_posix_signature=no])
  66. ])
  67. if test $gl_cv_func_strerror_r_posix_signature = yes; then
  68. dnl AIX 6.1 strerror_r fails by returning -1, not an error number.
  69. dnl HP-UX 11.31 strerror_r always fails when the buffer length argument
  70. dnl is less than 80.
  71. dnl FreeBSD 8.s strerror_r claims failure on 0
  72. dnl Mac OS X 10.5 strerror_r treats 0 like -1
  73. dnl Solaris 10 strerror_r corrupts errno on failure
  74. AC_CACHE_CHECK([whether strerror_r works],
  75. [gl_cv_func_strerror_r_works],
  76. [AC_RUN_IFELSE(
  77. [AC_LANG_PROGRAM(
  78. [[#include <errno.h>
  79. #include <string.h>
  80. ]],
  81. [[int result = 0;
  82. char buf[79];
  83. if (strerror_r (EACCES, buf, 0) < 0)
  84. result |= 1;
  85. errno = 0;
  86. if (strerror_r (EACCES, buf, sizeof buf) != 0)
  87. result |= 2;
  88. strcpy (buf, "Unknown");
  89. if (strerror_r (0, buf, sizeof buf) != 0)
  90. result |= 4;
  91. if (errno)
  92. result |= 8;
  93. if (strstr (buf, "nknown") || strstr (buf, "ndefined"))
  94. result |= 0x10;
  95. errno = 0;
  96. *buf = 0;
  97. if (strerror_r (-3, buf, sizeof buf) < 0)
  98. result |= 0x20;
  99. if (errno)
  100. result |= 0x40;
  101. if (!*buf)
  102. result |= 0x80;
  103. return result;
  104. ]])],
  105. [gl_cv_func_strerror_r_works=yes],
  106. [gl_cv_func_strerror_r_works=no],
  107. [
  108. changequote(,)dnl
  109. case "$host_os" in
  110. # Guess no on AIX.
  111. aix*) gl_cv_func_strerror_r_works="guessing no";;
  112. # Guess no on HP-UX.
  113. hpux*) gl_cv_func_strerror_r_works="guessing no";;
  114. # Guess no on BSD variants.
  115. *bsd*) gl_cv_func_strerror_r_works="guessing no";;
  116. # Guess yes otherwise.
  117. *) gl_cv_func_strerror_r_works="guessing yes";;
  118. esac
  119. changequote([,])dnl
  120. ])
  121. ])
  122. else
  123. dnl The system's strerror() has a wrong signature.
  124. dnl glibc >= 2.3.4 and cygwin 1.7.9 have a function __xpg_strerror_r.
  125. AC_CHECK_FUNCS_ONCE([__xpg_strerror_r])
  126. dnl In glibc < 2.14, __xpg_strerror_r does not populate buf on failure.
  127. dnl In cygwin < 1.7.10, __xpg_strerror_r clobbers strerror's buffer.
  128. if test $ac_cv_func___xpg_strerror_r = yes; then
  129. AC_CACHE_CHECK([whether __xpg_strerror_r works],
  130. [gl_cv_func_strerror_r_works],
  131. [AC_RUN_IFELSE(
  132. [AC_LANG_PROGRAM(
  133. [[#include <errno.h>
  134. #include <string.h>
  135. extern
  136. #ifdef __cplusplus
  137. "C"
  138. #endif
  139. int __xpg_strerror_r(int, char *, size_t);
  140. ]],
  141. [[int result = 0;
  142. char buf[256] = "^";
  143. char copy[256];
  144. char *str = strerror (-1);
  145. strcpy (copy, str);
  146. if (__xpg_strerror_r (-2, buf, 1) == 0)
  147. result |= 1;
  148. if (*buf)
  149. result |= 2;
  150. __xpg_strerror_r (-2, buf, 256);
  151. if (strcmp (str, copy))
  152. result |= 4;
  153. return result;
  154. ]])],
  155. [gl_cv_func_strerror_r_works=yes],
  156. [gl_cv_func_strerror_r_works=no],
  157. [dnl Guess no on all platforms that have __xpg_strerror_r,
  158. dnl at least until fixed glibc and cygwin are more common.
  159. gl_cv_func_strerror_r_works="$gl_cross_guess_normal"
  160. ])
  161. ])
  162. fi
  163. fi
  164. fi
  165. fi
  166. ])