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