Mercurial > hg > octave-lojdl > gnulib-hg
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 |
rev | line source |
---|---|
13847 | 1 /* strerror_r.c --- POSIX compatible system error routine |
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 | 4 |
5 This program is free software: you can redistribute it and/or modify | |
6 it under the terms of the GNU General Public License as published by | |
7 the Free Software Foundation; either version 3 of the License, or | |
8 (at your option) any later version. | |
9 | |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
17 | |
18 /* Written by Bruno Haible <bruno@clisp.org>, 2010. */ | |
19 | |
20 #include <config.h> | |
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 | 25 /* Specification. */ |
26 #include <string.h> | |
27 | |
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 | 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 | 39 |
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 | 42 |
43 # include <limits.h> | |
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 | 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 | 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 | 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 | 81 /* This lock protects the buffer returned by strerror(). We assume that |
82 no other uses of strerror() exist in the program. */ | |
83 gl_lock_define_initialized(static, strerror_lock) | |
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 | 114 int |
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 | 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 | 135 |
136 { | |
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 | 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 | 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 | 292 |
293 gl_lock_unlock (strerror_lock); | |
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 | 303 return ret; |
304 } | |
305 } |