annotate lib/strerror_r.c @ 14853:bdc85db78f47

strerror: drop strerror_r dependency Since the errno module is responsible for introducing replacement errno values, it should also be responsible for translating those new values into strings. And by moving the replacements into a file managed by the errno, we can then break the dependency between strerror and strerror_r, so that strerror no longer drags in multi-threading modules required by strerror_r. Tested on glibc with: gl_cv_header_errno_h_complete=no gl_cv_func_working_strerror=no \ gl_cv_func_strerror_r_works=no ./gnulib-tool --with-tests \ --test strerror strerror_r-posix * lib/strerror_r.c (strerror_r): Move gnulib replacement strings... * lib/strerror-override.c (strerror_override): ...to new file. * lib/strerror-override.h: Add prototype. * lib/strerror-impl.h: Delete. * lib/strerror.c (strerror): New implementation. * modules/errno (Files): Add new files. (configure.ac): Compile new file as appropriate. * modules/strerror (Files): Drop unused file. (Depends-on): Drop strerror_r-posix. * MODULES.html.sh: Document strerror_r-posix. Requested by Sam Steingold. Signed-off-by: Eric Blake <eblake@redhat.com>
author Eric Blake <eblake@redhat.com>
date Tue, 24 May 2011 15:33:49 -0600
parents e9cc9d33a1b8
children 42eaca1a6673
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* strerror_r.c --- POSIX compatible system error routine
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
2
14079
97fc9a21a8fb maint: update almost all copyright ranges to include 2011
Jim Meyering <meyering@redhat.com>
parents: 13885
diff changeset
3 Copyright (C) 2010-2011 Free Software Foundation, Inc.
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 This program is free software: you can redistribute it and/or modify
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 the Free Software Foundation; either version 3 of the License, or
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 (at your option) any later version.
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 GNU General Public License for more details.
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18 /* Written by Bruno Haible <bruno@clisp.org>, 2010. */
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 #include <config.h>
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21
14765
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
22 /* Enable declaration of sys_nerr and sys_errlist in <errno.h> on NetBSD. */
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
23 #define _NETBSD_SOURCE 1
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
24
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 /* Specification. */
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 #include <string.h>
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 #include <errno.h>
14818
280af315920c strerror_r: fix missing header
Eric Blake <eblake@redhat.com>
parents: 14817
diff changeset
29 #include <stdio.h>
14851
e9cc9d33a1b8 strerror_r: fix includes for FreeBSD
Eric Blake <eblake@redhat.com>
parents: 14818
diff changeset
30 #include <stdlib.h>
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31
14853
bdc85db78f47 strerror: drop strerror_r dependency
Eric Blake <eblake@redhat.com>
parents: 14851
diff changeset
32 #include "strerror-override.h"
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
33
14766
3618a75b519d strerror_r: fix on newer cygwin
Eric Blake <eblake@redhat.com>
parents: 14765
diff changeset
34 #if (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__) && HAVE___XPG_STRERROR_R /* glibc >= 2.3.4, cygwin >= 1.7.9 */
3618a75b519d strerror_r: fix on newer cygwin
Eric Blake <eblake@redhat.com>
parents: 14765
diff changeset
35
3618a75b519d strerror_r: fix on newer cygwin
Eric Blake <eblake@redhat.com>
parents: 14765
diff changeset
36 # define USE_XPG_STRERROR_R 1
3618a75b519d strerror_r: fix on newer cygwin
Eric Blake <eblake@redhat.com>
parents: 14765
diff changeset
37
14786
5a40a173eb17 strerror_r: avoid clobbering strerror on cygwin
Eric Blake <eblake@redhat.com>
parents: 14782
diff changeset
38 #elif HAVE_DECL_STRERROR_R && !(__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__)
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 /* The system's strerror_r function is OK, except that its third argument
14270
9dc44fa092bd strerror_r-posix: port to cygwin
Eric Blake <eblake@redhat.com>
parents: 14207
diff changeset
41 is 'int', not 'size_t', or its return type is wrong. */
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
43 # include <limits.h>
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
45 # define USE_SYSTEM_STRERROR_R 1
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46
14786
5a40a173eb17 strerror_r: avoid clobbering strerror on cygwin
Eric Blake <eblake@redhat.com>
parents: 14782
diff changeset
47 #else /* (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__ ? !HAVE___XPG_STRERROR_R : !HAVE_DECL_STRERROR_R) */
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48
14786
5a40a173eb17 strerror_r: avoid clobbering strerror on cygwin
Eric Blake <eblake@redhat.com>
parents: 14782
diff changeset
49 /* Use the system's strerror(). Exclude glibc and cygwin because the
5a40a173eb17 strerror_r: avoid clobbering strerror on cygwin
Eric Blake <eblake@redhat.com>
parents: 14782
diff changeset
50 system strerror_r has the wrong return type, and cygwin 1.7.9
5a40a173eb17 strerror_r: avoid clobbering strerror on cygwin
Eric Blake <eblake@redhat.com>
parents: 14782
diff changeset
51 strerror_r clobbers strerror. */
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
52 # undef strerror
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
53
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
54 # define USE_SYSTEM_STRERROR 1
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55
14786
5a40a173eb17 strerror_r: avoid clobbering strerror on cygwin
Eric Blake <eblake@redhat.com>
parents: 14782
diff changeset
56 # if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __sgi || (defined __sun && !defined _LP64) || defined __CYGWIN__
14765
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
57
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
58 /* No locking needed. */
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
59
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
60 /* Get catgets internationalization functions. */
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
61 # if HAVE_CATGETS
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
62 # include <nl_types.h>
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
63 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
64
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
65 /* Get sys_nerr, sys_errlist on HP-UX (otherwise only declared in C++ mode).
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
66 Get sys_nerr, sys_errlist on IRIX (otherwise only declared with _SGIAPI). */
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
67 # if defined __hpux || defined __sgi
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
68 extern int sys_nerr;
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
69 extern char *sys_errlist[];
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
70 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
71
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
72 /* Get sys_nerr on Solaris. */
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
73 # if defined __sun && !defined _LP64
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
74 extern int sys_nerr;
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
75 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
76
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
77 # else
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
78
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
79 # include "glthread/lock.h"
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
80
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
81 /* This lock protects the buffer returned by strerror(). We assume that
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82 no other uses of strerror() exist in the program. */
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83 gl_lock_define_initialized(static, strerror_lock)
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
84
14765
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
85 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
86
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
87 #endif
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
88
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
89 /* Copy as much of MSG into BUF as possible, without corrupting errno.
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
90 Return 0 if MSG fit in BUFLEN, otherwise return ERANGE. */
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
91 static int
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
92 safe_copy (char *buf, size_t buflen, const char *msg)
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
93 {
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
94 size_t len = strlen (msg);
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
95 int ret;
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
96
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
97 if (len < buflen)
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
98 {
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
99 /* Although POSIX allows memcpy() to corrupt errno, we don't
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
100 know of any implementation where this is a real problem. */
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
101 memcpy (buf, msg, len + 1);
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
102 ret = 0;
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
103 }
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
104 else
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
105 {
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
106 memcpy (buf, msg, buflen - 1);
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
107 buf[buflen - 1] = '\0';
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
108 ret = ERANGE;
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
109 }
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
110 return ret;
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
111 }
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
112
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
113
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
114 int
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
115 strerror_r (int errnum, char *buf, size_t buflen)
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
116 #undef strerror_r
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
117 {
14782
5a7b4517a078 strerror_r: simplify AIX code.
Eric Blake <eblake@redhat.com>
parents: 14770
diff changeset
118 /* Filter this out now, so that rest of this replacement knows that
5a7b4517a078 strerror_r: simplify AIX code.
Eric Blake <eblake@redhat.com>
parents: 14770
diff changeset
119 there is room for a non-empty message and trailing NUL. */
5a7b4517a078 strerror_r: simplify AIX code.
Eric Blake <eblake@redhat.com>
parents: 14770
diff changeset
120 if (buflen <= 1)
5a7b4517a078 strerror_r: simplify AIX code.
Eric Blake <eblake@redhat.com>
parents: 14770
diff changeset
121 {
5a7b4517a078 strerror_r: simplify AIX code.
Eric Blake <eblake@redhat.com>
parents: 14770
diff changeset
122 if (buflen)
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
123 *buf = '\0';
14782
5a7b4517a078 strerror_r: simplify AIX code.
Eric Blake <eblake@redhat.com>
parents: 14770
diff changeset
124 return ERANGE;
5a7b4517a078 strerror_r: simplify AIX code.
Eric Blake <eblake@redhat.com>
parents: 14770
diff changeset
125 }
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
126 *buf = '\0';
14782
5a7b4517a078 strerror_r: simplify AIX code.
Eric Blake <eblake@redhat.com>
parents: 14770
diff changeset
127
14853
bdc85db78f47 strerror: drop strerror_r dependency
Eric Blake <eblake@redhat.com>
parents: 14851
diff changeset
128 /* Check for gnulib overrides. */
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
129 {
14853
bdc85db78f47 strerror: drop strerror_r dependency
Eric Blake <eblake@redhat.com>
parents: 14851
diff changeset
130 char const *msg = strerror_override (errnum);
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
131
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
132 if (msg)
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
133 return safe_copy (buf, buflen, msg);
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
134 }
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
135
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
136 {
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
137 int ret;
14769
8e815ef27998 strerror_r: guarantee unchanged errno
Eric Blake <eblake@redhat.com>
parents: 14768
diff changeset
138 int saved_errno = errno;
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
139
14768
a12deda870d9 strerror_r: Reorder #if blocks.
Bruno Haible <bruno@clisp.org>
parents: 14766
diff changeset
140 #if USE_XPG_STRERROR_R
a12deda870d9 strerror_r: Reorder #if blocks.
Bruno Haible <bruno@clisp.org>
parents: 14766
diff changeset
141
a12deda870d9 strerror_r: Reorder #if blocks.
Bruno Haible <bruno@clisp.org>
parents: 14766
diff changeset
142 {
a12deda870d9 strerror_r: Reorder #if blocks.
Bruno Haible <bruno@clisp.org>
parents: 14766
diff changeset
143 extern int __xpg_strerror_r (int errnum, char *buf, size_t buflen);
a12deda870d9 strerror_r: Reorder #if blocks.
Bruno Haible <bruno@clisp.org>
parents: 14766
diff changeset
144
a12deda870d9 strerror_r: Reorder #if blocks.
Bruno Haible <bruno@clisp.org>
parents: 14766
diff changeset
145 ret = __xpg_strerror_r (errnum, buf, buflen);
a12deda870d9 strerror_r: Reorder #if blocks.
Bruno Haible <bruno@clisp.org>
parents: 14766
diff changeset
146 if (ret < 0)
a12deda870d9 strerror_r: Reorder #if blocks.
Bruno Haible <bruno@clisp.org>
parents: 14766
diff changeset
147 ret = errno;
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
148 if (!*buf)
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
149 {
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
150 /* glibc 2.13 would not touch buf on err, so we have to fall
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
151 back to GNU strerror_r which always returns a thread-safe
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
152 untruncated string to (partially) copy into our buf. */
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
153 safe_copy (buf, buflen, strerror_r (errnum, buf, buflen));
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
154 }
14768
a12deda870d9 strerror_r: Reorder #if blocks.
Bruno Haible <bruno@clisp.org>
parents: 14766
diff changeset
155 }
a12deda870d9 strerror_r: Reorder #if blocks.
Bruno Haible <bruno@clisp.org>
parents: 14766
diff changeset
156
a12deda870d9 strerror_r: Reorder #if blocks.
Bruno Haible <bruno@clisp.org>
parents: 14766
diff changeset
157 #elif USE_SYSTEM_STRERROR_R
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
158
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
159 if (buflen > INT_MAX)
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
160 buflen = INT_MAX;
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
161
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
162 # ifdef __hpux
14817
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
163 /* On HP-UX 11.31, strerror_r always fails when buflen < 80; it
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
164 also fails to change buf on EINVAL. */
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
165 {
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
166 char stackbuf[80];
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
167
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
168 if (buflen < sizeof stackbuf)
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
169 {
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
170 ret = strerror_r (errnum, stackbuf, sizeof stackbuf);
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
171 if (ret == 0)
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
172 ret = safe_copy (buf, buflen, stackbuf);
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
173 }
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
174 else
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
175 ret = strerror_r (errnum, buf, buflen);
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
176 }
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
177 # else
14816
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
178 /* Solaris 10 does not populate buf on ERANGE. */
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
179 ret = strerror_r (errnum, buf, buflen);
14816
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
180 if (ret == ERANGE && !*buf)
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
181 {
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
182 char stackbuf[STACKBUF_LEN];
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
183
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
184 /* strerror-impl.h is also affected if our choice of stackbuf
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
185 size is not large enough. */
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
186 if (strerror_r (errnum, stackbuf, sizeof stackbuf) == ERANGE)
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
187 abort ();
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
188 safe_copy (buf, buflen, stackbuf);
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
189 }
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
190 # endif
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
191
14817
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
192 # ifdef _AIX
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
193 /* AIX returns 0 rather than ERANGE when truncating strings; try
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
194 again until we are sure we got the entire string. */
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
195 if (!ret && strlen (buf) == buflen - 1)
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
196 {
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
197 char stackbuf[STACKBUF_LEN];
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
198 size_t len;
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
199 strerror_r (errnum, stackbuf, sizeof stackbuf);
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
200 len = strlen (stackbuf);
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
201 /* stackbuf should have been large enough. */
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
202 if (len + 1 == sizeof stackbuf)
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
203 abort ();
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
204 if (buflen <= len)
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
205 ret = ERANGE;
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
206 }
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
207 # endif
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
208
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
209 /* Some old implementations may return (-1, EINVAL) instead of EINVAL. */
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
210 if (ret < 0)
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
211 ret = errno;
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
212
14762
3c012e3d3f43 strerror: enforce POSIX ruling on strerror(0)
Eric Blake <eblake@redhat.com>
parents: 14758
diff changeset
213 /* FreeBSD rejects 0; see http://austingroupbugs.net/view.php?id=382. */
3c012e3d3f43 strerror: enforce POSIX ruling on strerror(0)
Eric Blake <eblake@redhat.com>
parents: 14758
diff changeset
214 if (errnum == 0 && ret == EINVAL)
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
215 ret = safe_copy (buf, buflen, "Success");
14762
3c012e3d3f43 strerror: enforce POSIX ruling on strerror(0)
Eric Blake <eblake@redhat.com>
parents: 14758
diff changeset
216
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
217 #else /* USE_SYSTEM_STRERROR */
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
218
14765
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
219 /* Try to do what strerror (errnum) does, but without clobbering the
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
220 buffer used by strerror(). */
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
221
14786
5a40a173eb17 strerror_r: avoid clobbering strerror on cygwin
Eric Blake <eblake@redhat.com>
parents: 14782
diff changeset
222 # if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __CYGWIN__ /* NetBSD, HP-UX, native Win32, Cygwin */
14765
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
223
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
224 /* NetBSD: sys_nerr, sys_errlist are declared through _NETBSD_SOURCE
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
225 and <errno.h> above.
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
226 HP-UX: sys_nerr, sys_errlist are declared explicitly above.
14786
5a40a173eb17 strerror_r: avoid clobbering strerror on cygwin
Eric Blake <eblake@redhat.com>
parents: 14782
diff changeset
227 native Win32: sys_nerr, sys_errlist are declared in <stdlib.h>.
14792
fedc69ad1054 strerror_r: Fix comments.
Bruno Haible <bruno@clisp.org>
parents: 14786
diff changeset
228 Cygwin: sys_nerr, sys_errlist are declared in <errno.h>. */
14765
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
229 if (errnum >= 0 && errnum < sys_nerr)
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
230 {
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
231 # if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux)
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
232 # if defined __NetBSD__
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
233 nl_catd catd = catopen ("libc", NL_CAT_LOCALE);
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
234 const char *errmsg =
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
235 (catd != (nl_catd)-1
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
236 ? catgets (catd, 1, errnum, sys_errlist[errnum])
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
237 : sys_errlist[errnum]);
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
238 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
239 # if defined __hpux
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
240 nl_catd catd = catopen ("perror", NL_CAT_LOCALE);
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
241 const char *errmsg =
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
242 (catd != (nl_catd)-1
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
243 ? catgets (catd, 1, 1 + errnum, sys_errlist[errnum])
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
244 : sys_errlist[errnum]);
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
245 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
246 # else
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
247 const char *errmsg = sys_errlist[errnum];
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
248 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
249 if (errmsg == NULL || *errmsg == '\0')
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
250 ret = EINVAL;
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
251 else
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
252 ret = safe_copy (buf, buflen, errmsg);
14765
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
253 # if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux)
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
254 if (catd != (nl_catd)-1)
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
255 catclose (catd);
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
256 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
257 }
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
258 else
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
259 ret = EINVAL;
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
260
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
261 # elif defined __sgi || (defined __sun && !defined _LP64) /* IRIX, Solaris <= 9 32-bit */
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
262
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
263 /* For a valid error number, the system's strerror() function returns
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
264 a pointer to a not copied string, not to a buffer. */
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
265 if (errnum >= 0 && errnum < sys_nerr)
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
266 {
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
267 char *errmsg = strerror (errnum);
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
268
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
269 if (errmsg == NULL || *errmsg == '\0')
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
270 ret = EINVAL;
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
271 else
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
272 ret = safe_copy (buf, buflen, errmsg);
14765
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
273 }
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
274 else
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
275 ret = EINVAL;
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
276
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
277 # else
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
278
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
279 gl_lock_lock (strerror_lock);
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
280
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
281 {
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
282 char *errmsg = strerror (errnum);
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
283
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
284 /* For invalid error numbers, strerror() on
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
285 - IRIX 6.5 returns NULL,
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
286 - HP-UX 11 returns an empty string. */
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
287 if (errmsg == NULL || *errmsg == '\0')
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
288 ret = EINVAL;
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
289 else
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
290 ret = safe_copy (buf, buflen, errmsg);
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
291 }
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
292
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
293 gl_lock_unlock (strerror_lock);
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
294
14765
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
295 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
296
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
297 #endif
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
298
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
299 if (ret == EINVAL && !*buf)
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
300 snprintf (buf, buflen, "Unknown error %d", errnum);
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
301
14769
8e815ef27998 strerror_r: guarantee unchanged errno
Eric Blake <eblake@redhat.com>
parents: 14768
diff changeset
302 errno = saved_errno;
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
303 return ret;
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
304 }
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
305 }