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