annotate lib/strerror_r.c @ 14862:42eaca1a6673

strerror_r: Fix comments. * lib/strerror_r.c (strerror_r): Update comments after 2011-06-01 commit.
author Bruno Haible <bruno@clisp.org>
date Sat, 04 Jun 2011 13:01:55 +0200
parents bdc85db78f47
children 66b65ce5da39
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 if (strerror_r (errnum, stackbuf, sizeof stackbuf) == ERANGE)
14862
42eaca1a6673 strerror_r: Fix comments.
Bruno Haible <bruno@clisp.org>
parents: 14853
diff changeset
185 /* STACKBUF_LEN should have been large enough. */
14816
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
186 abort ();
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
187 safe_copy (buf, buflen, stackbuf);
b6363790caec strerror_r: fix Solaris test failures
Eric Blake <eblake@redhat.com>
parents: 14815
diff changeset
188 }
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
189 # endif
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
190
14817
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
191 # ifdef _AIX
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
192 /* 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
193 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
194 if (!ret && strlen (buf) == buflen - 1)
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
195 {
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
196 char stackbuf[STACKBUF_LEN];
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
197 size_t len;
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
198 strerror_r (errnum, stackbuf, sizeof stackbuf);
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
199 len = strlen (stackbuf);
14862
42eaca1a6673 strerror_r: Fix comments.
Bruno Haible <bruno@clisp.org>
parents: 14853
diff changeset
200 /* STACKBUF_LEN should have been large enough. */
14817
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
201 if (len + 1 == sizeof stackbuf)
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
202 abort ();
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
203 if (buflen <= len)
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
204 ret = ERANGE;
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
205 }
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
206 # endif
2835cfc7d63e strerror_r: fix AIX test failures
Eric Blake <eblake@redhat.com>
parents: 14816
diff changeset
207
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
208 /* 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
209 if (ret < 0)
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
210 ret = errno;
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
211
14762
3c012e3d3f43 strerror: enforce POSIX ruling on strerror(0)
Eric Blake <eblake@redhat.com>
parents: 14758
diff changeset
212 /* 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
213 if (errnum == 0 && ret == EINVAL)
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
214 ret = safe_copy (buf, buflen, "Success");
14762
3c012e3d3f43 strerror: enforce POSIX ruling on strerror(0)
Eric Blake <eblake@redhat.com>
parents: 14758
diff changeset
215
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
216 #else /* USE_SYSTEM_STRERROR */
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
217
14765
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
218 /* 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
219 buffer used by strerror(). */
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
220
14786
5a40a173eb17 strerror_r: avoid clobbering strerror on cygwin
Eric Blake <eblake@redhat.com>
parents: 14782
diff changeset
221 # 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
222
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
223 /* 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
224 and <errno.h> above.
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
225 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
226 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
227 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
228 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
229 {
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
230 # 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
231 # if defined __NetBSD__
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
232 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
233 const char *errmsg =
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
234 (catd != (nl_catd)-1
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
235 ? 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
236 : sys_errlist[errnum]);
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
237 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
238 # if defined __hpux
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
239 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
240 const char *errmsg =
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
241 (catd != (nl_catd)-1
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
242 ? 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
243 : sys_errlist[errnum]);
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
244 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
245 # else
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
246 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
247 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
248 if (errmsg == NULL || *errmsg == '\0')
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
249 ret = EINVAL;
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
250 else
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
251 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
252 # 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
253 if (catd != (nl_catd)-1)
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
254 catclose (catd);
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
255 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
256 }
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
257 else
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
258 ret = EINVAL;
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
259
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
260 # 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
261
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
262 /* 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
263 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
264 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
265 {
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
266 char *errmsg = strerror (errnum);
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
267
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
268 if (errmsg == NULL || *errmsg == '\0')
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
269 ret = EINVAL;
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
270 else
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
271 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
272 }
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
273 else
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
274 ret = EINVAL;
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
275
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
276 # else
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
277
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
278 gl_lock_lock (strerror_lock);
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
279
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 char *errmsg = strerror (errnum);
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
282
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
283 /* 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
284 - IRIX 6.5 returns NULL,
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
285 - 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
286 if (errmsg == NULL || *errmsg == '\0')
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
287 ret = EINVAL;
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
288 else
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
289 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
290 }
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
291
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
292 gl_lock_unlock (strerror_lock);
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
293
14765
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
294 # endif
8e23facf1d9e strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14764
diff changeset
295
14758
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
296 #endif
0ed8de9d6bbe strerror_r: Avoid clobbering the strerror buffer when possible.
Bruno Haible <bruno@clisp.org>
parents: 14270
diff changeset
297
14815
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
298 if (ret == EINVAL && !*buf)
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
299 snprintf (buf, buflen, "Unknown error %d", errnum);
820329b2a895 strerror_r: enforce POSIX recommendations
Eric Blake <eblake@redhat.com>
parents: 14792
diff changeset
300
14769
8e815ef27998 strerror_r: guarantee unchanged errno
Eric Blake <eblake@redhat.com>
parents: 14768
diff changeset
301 errno = saved_errno;
13847
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
302 return ret;
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
303 }
99dd2b4fab8b New module 'strerror_r-posix'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
304 }