2 * Copyright (C) 2002 Manuel Novoa III
3 * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
5 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
12 #include <bits/uClibc_uintmaxtostr.h>
13 #include "_syserrmsg.h"
15 libc_hidden_proto(__xpg_strerror_r)
16 libc_hidden_proto(memcpy)
17 libc_hidden_proto(strlen)
19 #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
21 extern const char _string_syserrmsgs[] attribute_hidden;
23 #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
25 static const unsigned char estridx[] = {
26 0, /* success is always 0 */
149 0, /* mips has an outrageous value for this... */
155 #if defined(__mips__) || defined(__sparc__)
162 int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen)
166 char buf[_STRERROR_BUFSIZE];
167 static const char unknown[] = {
168 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
174 #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
176 #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
177 /* Need to translate errno to string index. */
178 for (i = 0 ; i < sizeof(estridx)/sizeof(estridx[0]) ; i++) {
179 if (estridx[i] == errnum) {
183 i = INT_MAX; /* Failed, but may need to check mips special case. */
185 if (errnum == EDQUOT) { /* Deal with large EDQUOT value on mips */
188 #endif /* __mips__ */
191 /* No errno to string index translation needed. */
195 if (((unsigned int) i) < _SYS_NERR) {
196 /* Trade time for space. This function should rarely be called
197 * so rather than keeping an array of pointers for the different
198 * messages, just run through the buffer until we find the
200 for (s = (char *) _string_syserrmsgs ; i ; ++s) {
205 if (*s) { /* Make sure we have an actual message. */
211 #endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
213 s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
214 memcpy(s, unknown, sizeof(unknown));
217 if (!strerrbuf) { /* SUSv3 */
227 memcpy(strerrbuf, s, i);
228 strerrbuf[i-1] = 0; /* In case buf was too small. */
238 #else /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
240 int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen)
244 char buf[_STRERROR_BUFSIZE];
245 static const char unknown[] = {
246 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
249 s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
250 memcpy(s, unknown, sizeof(unknown));
252 if (!strerrbuf) { /* SUSv3 */
258 i = buf + sizeof(buf) - s;
266 memcpy(strerrbuf, s, i);
267 strerrbuf[i-1] = 0; /* In case buf was too small. */
275 #endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
276 libc_hidden_def(__xpg_strerror_r)