summaryrefslogtreecommitdiff
path: root/libc/string
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2002-07-07 20:13:41 +0000
committerManuel Novoa III <mjn3@codepoet.org>2002-07-07 20:13:41 +0000
commitb815b84a5942f591e8a79c731100712558fa41c6 (patch)
treeff518c2c84178cdbf35699ca463577bf6e9dee19 /libc/string
parentc1383d79d31e9607a938215462f025bad3f14060 (diff)
Attempt to clean up the strerror_r situation.
Diffstat (limited to 'libc/string')
-rw-r--r--libc/string/strerror.c133
-rw-r--r--libc/string/sys_errlist.c140
-rw-r--r--libc/string/wstring.c385
3 files changed, 375 insertions, 283 deletions
diff --git a/libc/string/strerror.c b/libc/string/strerror.c
deleted file mode 100644
index 80f82de25..000000000
--- a/libc/string/strerror.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-/*
- * Manuel Novoa III Dec 2000
- *
- * Converted to use my new (un)signed long (long) to string routines, which
- * are smaller than the previous functions and don't require static buffers.
- * Removed dependence on strcat in the process.
- *
- * Also appended a test routine ( -DCHECK_BUF ) to allow a quick check
- * on the buffer length when the sys_errorlist is modified.
- *
- * Added the option WANT_ERRORLIST for low-memory applications to omit the
- * error message strings and only output the error number.
- *
- * Manuel Novoa III Feb 2002
- *
- * Change to _int10tostr and fix a bug in end-of-buf arg.
- *
- * Erik Andersen June 2002
- *
- * Added strerror_r (per SuSv3 which differs from glibc) and adapted
- * strerror to match.
- */
-
-#define WANT_ERRORLIST 1
-
-#define _STDIO_UTILITY /* For _int10tostr. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-int strerror_r(int err, char *retbuf, size_t buflen)
-{
-#if WANT_ERRORLIST
- if (err < 0 || err >= sys_nerr || sys_errlist[err] == NULL) {
- return -EINVAL;
- }
- if (retbuf==NULL || buflen < 1) {
- return -ERANGE;
- }
- strncpy(retbuf, sys_errlist[err], buflen);
- retbuf[buflen-1] = '\0';
- return 0;
-#else
- char *pos;
- static const char unknown_error[] = "Unknown Error: errno"; /* = */
-
- if (err < 0 || err >= sys_nerr || sys_errlist[err] == NULL) {
- return -EINVAL;
- }
- /* unknown error -- leave space for the '=' */
- pos = _int10tostr(retbuf+sizeof(retbuf)-1, err) - sizeof(unknown_error);
- strcpy(pos, unknown_error);
- *(pos + sizeof(unknown_error) - 1) = '=';
- return 0;
-#endif
-}
-
-/* Return a string descibing the errno code in ERRNUM.
- The storage is good only until the next call to strerror.
- Writing to the storage causes undefined behavior. */
-char *strerror(int err)
-{
-#if WANT_ERRORLIST
- static char retbuf[48];
-#else
-#if __BUFLEN_INT10TOSTR > 12
-#error currently set up for 32 bit ints max!
-#endif
- static char retbuf[33]; /* 33 is sufficient for 32 bit ints */
-#endif
-
- if (strerror_r(err, retbuf, sizeof(retbuf)) != 0) {
- return NULL;
- }
- return(retbuf);
-}
-
-#ifdef CHECK_BUF
-/* quick way to check buffer length */
-#include <stdio.h>
-#include <stdlib.h>
-int main(void)
-{
- int max = 0;
- int j, retcode;
- char *p;
-#if WANT_ERRORLIST
- int i;
-#endif
-
- retcode = EXIT_SUCCESS;
-
-#if WANT_ERRORLIST
- for ( i=0 ; i < sys_nerr ; i++ ) {
- j = strlen(sys_errlist[i])+1;
- if (j > max) max = j;
- }
-#endif
-
- p = strerror(INT_MIN);
- j = retbuf+sizeof(retbuf) - p;
- if ( > max) {
- max = j;
- printf("strerror.c - Test of INT_MIN: <%s> %d\n", p, j);
- }
-
- if (sizeof(retbuf) != max) {
- printf("Error: strerror.c - dimension of retbuf should be = %d\n", max);
- retcode = EXIT_FAILURE;
- }
- printf("Passed.\n");
-
- return retcode;
-}
-#endif
diff --git a/libc/string/sys_errlist.c b/libc/string/sys_errlist.c
deleted file mode 100644
index c92302fce..000000000
--- a/libc/string/sys_errlist.c
+++ /dev/null
@@ -1,140 +0,0 @@
-#include <stddef.h>
-#if 0
-#include <errno.h>
-#endif
-
-/* This is a list of all known signal numbers. */
-
-const char * const sys_errlist[] = {
- "Success", /* 0 */
- "Operation not permitted", /* EPERM */
- "No such file or directory", /* ENOENT */
- "No such process", /* ESRCH */
- "Interrupted system call", /* EINTR */
- "I/O error", /* EIO */
- "No such device or address", /* ENXIO */
- "Arg list too long", /* E2BIG */
- "Exec format error", /* ENOEXEC */
- "Bad file number", /* EBADF */
- "No child processes", /* ECHILD */
- "Try again", /* EAGAIN */
- "Out of memory", /* ENOMEM */
- "Permission denied", /* EACCES */
- "Bad address", /* EFAULT */
- "Block device required", /* ENOTBLK */
- "Device or resource busy", /* EBUSY */
- "File exists", /* EEXIST */
- "Cross-device link", /* EXDEV */
- "No such device", /* ENODEV */
- "Not a directory", /* ENOTDIR */
- "Is a directory", /* EISDIR */
- "Invalid argument", /* EINVAL */
- "File table overflow", /* ENFILE */
- "Too many open files", /* EMFILE */
- "Not a typewriter", /* ENOTTY */
- "Text file busy", /* ETXTBSY */
- "File too large", /* EFBIG */
- "No space left on device", /* ENOSPC */
- "Illegal seek", /* ESPIPE */
- "Read-only file system", /* EROFS */
- "Too many links", /* EMLINK */
- "Broken pipe", /* EPIPE */
- "Math argument out of domain of func", /* EDOM */
- "Math result not representable", /* ERANGE */
- "Resource deadlock would occur", /* EDEADLK */
- "File name too long", /* ENAMETOOLONG */
- "No record locks available", /* ENOLCK */
- "Function not implemented", /* ENOSYS */
- "Directory not empty", /* ENOTEMPTY */
- "Too many symbolic links encountered", /* ELOOP */
- "Operation would block", /* EWOULDBLOCK */
- "No message of desired type", /* ENOMSG */
- "Identifier removed", /* EIDRM */
- "Channel number out of range", /* ECHRNG */
- "Level 2 not synchronized", /* EL2NSYNC */
- "Level 3 halted", /* EL3HLT */
- "Level 3 reset", /* EL3RST */
- "Link number out of range", /* ELNRNG */
- "Protocol driver not attached", /* EUNATCH */
- "No CSI structure available", /* ENOCSI */
- "Level 2 halted", /* EL2HLT */
- "Invalid exchange", /* EBADE */
- "Invalid request descriptor", /* EBADR */
- "Exchange full", /* EXFULL */
- "No anode", /* ENOANO */
- "Invalid request code", /* EBADRQC */
- "Invalid slot", /* EBADSLT */
- "File locking deadlock error", /* EDEADLOCK */
- "Bad font file format", /* EBFONT */
- "Device not a stream", /* ENOSTR */
- "No data available", /* ENODATA */
- "Timer expired", /* ETIME */
- "Out of streams resources", /* ENOSR */
- "Machine is not on the network", /* ENONET */
- "Package not installed", /* ENOPKG */
- "Object is remote", /* EREMOTE */
- "Link has been severed", /* ENOLINK */
- "Advertise error", /* EADV */
- "Srmount error", /* ESRMNT */
- "Communication error on send", /* ECOMM */
- "Protocol error", /* EPROTO */
- "Multihop attempted", /* EMULTIHOP */
- "RFS specific error", /* EDOTDOT */
- "Not a data message", /* EBADMSG */
- "Value too large for defined data type", /* EOVERFLOW */
- "Name not unique on network", /* ENOTUNIQ */
- "File descriptor in bad state", /* EBADFD */
- "Remote address changed", /* EREMCHG */
- "Can not access a needed shared library", /* ELIBACC */
- "Accessing a corrupted shared library", /* ELIBBAD */
- ".lib section in a.out corrupted", /* ELIBSCN */
- "Attempting to link in too many shared libraries", /* ELIBMAX */
- "Cannot exec a shared library directly", /* ELIBEXEC */
- "Illegal byte sequence", /* EILSEQ */
- "Interrupted system call should be restarted", /* ERESTART */
- "Streams pipe error", /* ESTRPIPE */
- "Too many users", /* EUSERS */
- "Socket operation on non-socket", /* ENOTSOCK */
- "Destination address required", /* EDESTADDRREQ */
- "Message too long", /* EMSGSIZE */
- "Protocol wrong type for socket", /* EPROTOTYPE */
- "Protocol not available", /* ENOPROTOOPT */
- "Protocol not supported", /* EPROTONOSUPPORT */
- "Socket type not supported", /* ESOCKTNOSUPPORT */
- "Operation not supported on transport endpoint", /* EOPNOTSUPP */
- "Protocol family not supported", /* EPFNOSUPPORT */
- "Address family not supported by protocol", /* EAFNOSUPPORT */
- "Address already in use", /* EADDRINUSE */
- "Cannot assign requested address", /* EADDRNOTAVAIL */
- "Network is down", /* ENETDOWN */
- "Network is unreachable", /* ENETUNREACH */
- "Network dropped connection because of reset", /* ENETRESET */
- "Software caused connection abort", /* ECONNABORTED */
- "Connection reset by peer", /* ECONNRESET */
- "No buffer space available", /* ENOBUFS */
- "Transport endpoint is already connected", /* EISCONN */
- "Transport endpoint is not connected", /* ENOTCONN */
- "Cannot send after transport endpoint shutdown", /* ESHUTDOWN */
- "Too many references: cannot splice", /* ETOOMANYREFS */
- "Connection timed out", /* ETIMEDOUT */
- "Connection refused", /* ECONNREFUSED */
- "Host is down", /* EHOSTDOWN */
- "No route to host", /* EHOSTUNREACH */
- "Operation already in progress", /* EALREADY */
- "Operation now in progress", /* EINPROGRESS */
- "Stale NFS file handle", /* ESTALE */
- "Structure needs cleaning", /* EUCLEAN */
- "Not a XENIX named type file", /* ENOTNAM */
- "No XENIX semaphores available", /* ENAVAIL */
- "Is a named type file", /* EISNAM */
- "Remote I/O error", /* EREMOTEIO */
- "Quota exceeded", /* EDQUOT */
- "No medium found", /* ENOMEDIUM */
- "Wrong medium type", /* EMEDIUMTYPE */
- NULL
-};
-
-
-#define NR_ERRORS ((sizeof (sys_errlist))/(sizeof(char *))-1)
-
-const int sys_nerr = NR_ERRORS;
diff --git a/libc/string/wstring.c b/libc/string/wstring.c
index c78dbce0f..fd9e07d3d 100644
--- a/libc/string/wstring.c
+++ b/libc/string/wstring.c
@@ -26,12 +26,15 @@
*
* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
+#define _STDIO_UTILITY
#define _GNU_SOURCE
#include <string.h>
#include <strings.h>
+#include <stdio.h>
#include <limits.h>
#include <ctype.h>
#include <stdlib.h>
+#include <errno.h>
#ifdef WANT_WIDE
#include <wchar.h>
@@ -54,6 +57,291 @@ typedef unsigned char __string_uchar_t;
#endif
/**********************************************************************/
+/* NOTE: If we ever do internationalized syserr messages, this will
+ * have to be changed! */
+
+#if _SYS_ERRMSG_MAXLEN < __UIM_BUFLEN_INT + 14
+#define _STRERROR_BUFSIZE (__UIM_BUFLEN_INT + 14)
+#else
+#define _STRERROR_BUFSIZE _SYS_ERRMSG_MAXLEN
+#endif
+
+#define _SYS_NERR 125
+#define _SYS_ERRMSG_MAXLEN 50
+
+extern const char _string_syserrmsgs[];
+
+/**********************************************************************/
+#ifdef L__string_syserrmsgs
+
+const char _string_syserrmsgs[] = {
+ /* 0: 0, 8 */ "Success\0"
+ /* 1: 8, 24 */ "Operation not permitted\0"
+ /* 2: 32, 26 */ "No such file or directory\0"
+ /* 3: 58, 16 */ "No such process\0"
+ /* 4: 74, 24 */ "Interrupted system call\0"
+ /* 5: 98, 19 */ "Input/output error\0"
+ /* 6: 117, 26 */ "No such device or address\0"
+ /* 7: 143, 23 */ "Argument list too long\0"
+ /* 8: 166, 18 */ "Exec format error\0"
+ /* 9: 184, 20 */ "Bad file descriptor\0"
+ /* 10: 204, 19 */ "No child processes\0"
+ /* 11: 223, 33 */ "Resource temporarily unavailable\0"
+ /* 12: 256, 23 */ "Cannot allocate memory\0"
+ /* 13: 279, 18 */ "Permission denied\0"
+ /* 14: 297, 12 */ "Bad address\0"
+ /* 15: 309, 22 */ "Block device required\0"
+ /* 16: 331, 24 */ "Device or resource busy\0"
+ /* 17: 355, 12 */ "File exists\0"
+ /* 18: 367, 26 */ "Invalid cross-device link\0"
+ /* 19: 393, 15 */ "No such device\0"
+ /* 20: 408, 16 */ "Not a directory\0"
+ /* 21: 424, 15 */ "Is a directory\0"
+ /* 22: 439, 17 */ "Invalid argument\0"
+ /* 23: 456, 30 */ "Too many open files in system\0"
+ /* 24: 486, 20 */ "Too many open files\0"
+ /* 25: 506, 31 */ "Inappropriate ioctl for device\0"
+ /* 26: 537, 15 */ "Text file busy\0"
+ /* 27: 552, 15 */ "File too large\0"
+ /* 28: 567, 24 */ "No space left on device\0"
+ /* 29: 591, 13 */ "Illegal seek\0"
+ /* 30: 604, 22 */ "Read-only file system\0"
+ /* 31: 626, 15 */ "Too many links\0"
+ /* 32: 641, 12 */ "Broken pipe\0"
+ /* 33: 653, 33 */ "Numerical argument out of domain\0"
+ /* 34: 686, 30 */ "Numerical result out of range\0"
+ /* 35: 716, 26 */ "Resource deadlock avoided\0"
+ /* 36: 742, 19 */ "File name too long\0"
+ /* 37: 761, 19 */ "No locks available\0"
+ /* 38: 780, 25 */ "Function not implemented\0"
+ /* 39: 805, 20 */ "Directory not empty\0"
+ /* 40: 825, 34 */ "Too many levels of symbolic links\0"
+ /* 41: 859, 1 */ "\0"
+ /* 42: 860, 27 */ "No message of desired type\0"
+ /* 43: 887, 19 */ "Identifier removed\0"
+ /* 44: 906, 28 */ "Channel number out of range\0"
+ /* 45: 934, 25 */ "Level 2 not synchronized\0"
+ /* 46: 959, 15 */ "Level 3 halted\0"
+ /* 47: 974, 14 */ "Level 3 reset\0"
+ /* 48: 988, 25 */ "Link number out of range\0"
+ /* 49: 1013, 29 */ "Protocol driver not attached\0"
+ /* 50: 1042, 27 */ "No CSI structure available\0"
+ /* 51: 1069, 15 */ "Level 2 halted\0"
+ /* 52: 1084, 17 */ "Invalid exchange\0"
+ /* 53: 1101, 27 */ "Invalid request descriptor\0"
+ /* 54: 1128, 14 */ "Exchange full\0"
+ /* 55: 1142, 9 */ "No anode\0"
+ /* 56: 1151, 21 */ "Invalid request code\0"
+ /* 57: 1172, 13 */ "Invalid slot\0"
+ /* 58: 1185, 1 */ "\0"
+ /* 59: 1186, 21 */ "Bad font file format\0"
+ /* 60: 1207, 20 */ "Device not a stream\0"
+ /* 61: 1227, 18 */ "No data available\0"
+ /* 62: 1245, 14 */ "Timer expired\0"
+ /* 63: 1259, 25 */ "Out of streams resources\0"
+ /* 64: 1284, 30 */ "Machine is not on the network\0"
+ /* 65: 1314, 22 */ "Package not installed\0"
+ /* 66: 1336, 17 */ "Object is remote\0"
+ /* 67: 1353, 22 */ "Link has been severed\0"
+ /* 68: 1375, 16 */ "Advertise error\0"
+ /* 69: 1391, 14 */ "Srmount error\0"
+ /* 70: 1405, 28 */ "Communication error on send\0"
+ /* 71: 1433, 15 */ "Protocol error\0"
+ /* 72: 1448, 19 */ "Multihop attempted\0"
+ /* 73: 1467, 19 */ "RFS specific error\0"
+ /* 74: 1486, 12 */ "Bad message\0"
+ /* 75: 1498, 38 */ "Value too large for defined data type\0"
+ /* 76: 1536, 27 */ "Name not unique on network\0"
+ /* 77: 1563, 29 */ "File descriptor in bad state\0"
+ /* 78: 1592, 23 */ "Remote address changed\0"
+ /* 79: 1615, 39 */ "Can not access a needed shared library\0"
+ /* 80: 1654, 37 */ "Accessing a corrupted shared library\0"
+ /* 81: 1691, 32 */ ".lib section in a.out corrupted\0"
+ /* 82: 1723, 48 */ "Attempting to link in too many shared libraries\0"
+ /* 83: 1771, 38 */ "Cannot exec a shared library directly\0"
+ /* 84: 1809, 50 */ "Invalid or incomplete multibyte or wide character\0"
+ /* 85: 1859, 44 */ "Interrupted system call should be restarted\0"
+ /* 86: 1903, 19 */ "Streams pipe error\0"
+ /* 87: 1922, 15 */ "Too many users\0"
+ /* 88: 1937, 31 */ "Socket operation on non-socket\0"
+ /* 89: 1968, 29 */ "Destination address required\0"
+ /* 90: 1997, 17 */ "Message too long\0"
+ /* 91: 2014, 31 */ "Protocol wrong type for socket\0"
+ /* 92: 2045, 23 */ "Protocol not available\0"
+ /* 93: 2068, 23 */ "Protocol not supported\0"
+ /* 94: 2091, 26 */ "Socket type not supported\0"
+ /* 95: 2117, 24 */ "Operation not supported\0"
+ /* 96: 2141, 30 */ "Protocol family not supported\0"
+ /* 97: 2171, 41 */ "Address family not supported by protocol\0"
+ /* 98: 2212, 23 */ "Address already in use\0"
+ /* 99: 2235, 32 */ "Cannot assign requested address\0"
+ /* 100: 2267, 16 */ "Network is down\0"
+ /* 101: 2283, 23 */ "Network is unreachable\0"
+ /* 102: 2306, 36 */ "Network dropped connection on reset\0"
+ /* 103: 2342, 33 */ "Software caused connection abort\0"
+ /* 104: 2375, 25 */ "Connection reset by peer\0"
+ /* 105: 2400, 26 */ "No buffer space available\0"
+ /* 106: 2426, 40 */ "Transport endpoint is already connected\0"
+ /* 107: 2466, 36 */ "Transport endpoint is not connected\0"
+ /* 108: 2502, 46 */ "Cannot send after transport endpoint shutdown\0"
+ /* 109: 2548, 35 */ "Too many references: cannot splice\0"
+ /* 110: 2583, 21 */ "Connection timed out\0"
+ /* 111: 2604, 19 */ "Connection refused\0"
+ /* 112: 2623, 13 */ "Host is down\0"
+ /* 113: 2636, 17 */ "No route to host\0"
+ /* 114: 2653, 30 */ "Operation already in progress\0"
+ /* 115: 2683, 26 */ "Operation now in progress\0"
+ /* 116: 2709, 22 */ "Stale NFS file handle\0"
+ /* 117: 2731, 25 */ "Structure needs cleaning\0"
+ /* 118: 2756, 28 */ "Not a XENIX named type file\0"
+ /* 119: 2784, 30 */ "No XENIX semaphores available\0"
+ /* 120: 2814, 21 */ "Is a named type file\0"
+ /* 121: 2835, 17 */ "Remote I/O error\0"
+ /* 122: 2852, 20 */ "Disk quota exceeded\0"
+ /* 123: 2872, 16 */ "No medium found\0"
+ /* 124: 2888, 18 */ "Wrong medium type"
+};
+
+#endif
+/**********************************************************************/
+#ifdef L_sys_errlist
+
+link_warning(_sys_errlist, "sys_nerr and sys_errlist are obsolete and uClibc support for them (in at least some configurations) will probably be unavailable in the near future.")
+
+int sys_nerr = _SYS_NERR;
+
+const char *const sys_errlist[] = {
+ _string_syserrmsgs + 0,
+ _string_syserrmsgs + 8,
+ _string_syserrmsgs + 32,
+ _string_syserrmsgs + 58,
+ _string_syserrmsgs + 74,
+ _string_syserrmsgs + 98,
+ _string_syserrmsgs + 117,
+ _string_syserrmsgs + 143,
+ _string_syserrmsgs + 166,
+ _string_syserrmsgs + 184,
+ _string_syserrmsgs + 204,
+ _string_syserrmsgs + 223,
+ _string_syserrmsgs + 256,
+ _string_syserrmsgs + 279,
+ _string_syserrmsgs + 297,
+ _string_syserrmsgs + 309,
+ _string_syserrmsgs + 331,
+ _string_syserrmsgs + 355,
+ _string_syserrmsgs + 367,
+ _string_syserrmsgs + 393,
+ _string_syserrmsgs + 408,
+ _string_syserrmsgs + 424,
+ _string_syserrmsgs + 439,
+ _string_syserrmsgs + 456,
+ _string_syserrmsgs + 486,
+ _string_syserrmsgs + 506,
+ _string_syserrmsgs + 537,
+ _string_syserrmsgs + 552,
+ _string_syserrmsgs + 567,
+ _string_syserrmsgs + 591,
+ _string_syserrmsgs + 604,
+ _string_syserrmsgs + 626,
+ _string_syserrmsgs + 641,
+ _string_syserrmsgs + 653,
+ _string_syserrmsgs + 686,
+ _string_syserrmsgs + 716,
+ _string_syserrmsgs + 742,
+ _string_syserrmsgs + 761,
+ _string_syserrmsgs + 780,
+ _string_syserrmsgs + 805,
+ _string_syserrmsgs + 825,
+ /* _string_syserrmsgs + 859, */
+ NULL, /* glibc compatiblity :-( */
+ _string_syserrmsgs + 860,
+ _string_syserrmsgs + 887,
+ _string_syserrmsgs + 906,
+ _string_syserrmsgs + 934,
+ _string_syserrmsgs + 959,
+ _string_syserrmsgs + 974,
+ _string_syserrmsgs + 988,
+ _string_syserrmsgs + 1013,
+ _string_syserrmsgs + 1042,
+ _string_syserrmsgs + 1069,
+ _string_syserrmsgs + 1084,
+ _string_syserrmsgs + 1101,
+ _string_syserrmsgs + 1128,
+ _string_syserrmsgs + 1142,
+ _string_syserrmsgs + 1151,
+ _string_syserrmsgs + 1172,
+ /* _string_syserrmsgs + 1185, */
+ NULL, /* glibc compatiblity :-( */
+ _string_syserrmsgs + 1186,
+ _string_syserrmsgs + 1207,
+ _string_syserrmsgs + 1227,
+ _string_syserrmsgs + 1245,
+ _string_syserrmsgs + 1259,
+ _string_syserrmsgs + 1284,
+ _string_syserrmsgs + 1314,
+ _string_syserrmsgs + 1336,
+ _string_syserrmsgs + 1353,
+ _string_syserrmsgs + 1375,
+ _string_syserrmsgs + 1391,
+ _string_syserrmsgs + 1405,
+ _string_syserrmsgs + 1433,
+ _string_syserrmsgs + 1448,
+ _string_syserrmsgs + 1467,
+ _string_syserrmsgs + 1486,
+ _string_syserrmsgs + 1498,
+ _string_syserrmsgs + 1536,
+ _string_syserrmsgs + 1563,
+ _string_syserrmsgs + 1592,
+ _string_syserrmsgs + 1615,
+ _string_syserrmsgs + 1654,
+ _string_syserrmsgs + 1691,
+ _string_syserrmsgs + 1723,
+ _string_syserrmsgs + 1771,
+ _string_syserrmsgs + 1809,
+ _string_syserrmsgs + 1859,
+ _string_syserrmsgs + 1903,
+ _string_syserrmsgs + 1922,
+ _string_syserrmsgs + 1937,
+ _string_syserrmsgs + 1968,
+ _string_syserrmsgs + 1997,
+ _string_syserrmsgs + 2014,
+ _string_syserrmsgs + 2045,
+ _string_syserrmsgs + 2068,
+ _string_syserrmsgs + 2091,
+ _string_syserrmsgs + 2117,
+ _string_syserrmsgs + 2141,
+ _string_syserrmsgs + 2171,
+ _string_syserrmsgs + 2212,
+ _string_syserrmsgs + 2235,
+ _string_syserrmsgs + 2267,
+ _string_syserrmsgs + 2283,
+ _string_syserrmsgs + 2306,
+ _string_syserrmsgs + 2342,
+ _string_syserrmsgs + 2375,
+ _string_syserrmsgs + 2400,
+ _string_syserrmsgs + 2426,
+ _string_syserrmsgs + 2466,
+ _string_syserrmsgs + 2502,
+ _string_syserrmsgs + 2548,
+ _string_syserrmsgs + 2583,
+ _string_syserrmsgs + 2604,
+ _string_syserrmsgs + 2623,
+ _string_syserrmsgs + 2636,
+ _string_syserrmsgs + 2653,
+ _string_syserrmsgs + 2683,
+ _string_syserrmsgs + 2709,
+ _string_syserrmsgs + 2731,
+ _string_syserrmsgs + 2756,
+ _string_syserrmsgs + 2784,
+ _string_syserrmsgs + 2814,
+ _string_syserrmsgs + 2835,
+ _string_syserrmsgs + 2852,
+ _string_syserrmsgs + 2872,
+ _string_syserrmsgs + 2888,
+};
+
+#endif
+/**********************************************************************/
#ifdef L_wmemcpy
#define L_memcpy
#define Wmemcpy wmemcpy
@@ -255,7 +543,7 @@ Wchar *Wstrncat(Wchar * __restrict s1, register const Wchar * __restrict s2,
#ifdef L_memcmp
#ifndef L_wmemcmp
-weak_alias(memcmp,bcmp)
+weak_alias(memcmp,bcmp);
#endif
int Wmemcmp(const Wvoid *s1, const Wvoid *s2, size_t n)
@@ -418,7 +706,7 @@ Wvoid *Wmemchr(const Wvoid *s, Wint c, size_t n)
#ifdef L_strchr
#ifndef L_wcschr
-weak_alias(strchr,index)
+weak_alias(strchr,index);
#endif
Wchar *Wstrchr(register const Wchar *s, Wint c)
@@ -492,7 +780,7 @@ Wchar *Wstrpbrk(const Wchar *s1, const Wchar *s2)
#ifdef L_strrchr
#ifndef L_wcsrchr
-weak_alias(strrchr,rindex)
+weak_alias(strrchr,rindex);
#endif
Wchar *Wstrrchr(register const Wchar *s, Wint c)
@@ -548,7 +836,7 @@ size_t Wstrspn(const Wchar *s1, const Wchar *s2)
/* NOTE: This is the simple-minded O(len(s1) * len(s2)) worst-case approach. */
#ifdef L_wcsstr
-weak_alias(wcsstr,wcswcs)
+weak_alias(wcsstr,wcswcs);
#endif
Wchar *Wstrstr(const Wchar *s1, const Wchar *s2)
@@ -674,11 +962,6 @@ Wvoid *Wmemset(Wvoid *s, Wint c, size_t n)
#endif
/**********************************************************************/
-#ifdef L_strerror
-#error implement strerror
-/* char *strerror(int errnum); */
-#endif
-/**********************************************************************/
#ifdef L_wcslen
#define L_strlen
#define Wstrlen wcslen
@@ -890,8 +1173,90 @@ Wchar *Wstrdup(register const Wchar *s1)
#endif
/**********************************************************************/
+#ifdef L_strerror
+
+char *strerror(int errnum)
+{
+ static char buf[_SYS_ERRMSG_MAXLEN];
+
+ return (_susv3_strerror_r(errnum, buf, sizeof(buf)) == 0) ? buf : NULL;
+}
+
+#endif
+/**********************************************************************/
+/* SUSv3 functions. */
+/**********************************************************************/
+#ifdef L__susv3_strerror_r
+
+int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen)
+{
+ register char *s;
+ int i, retval;
+ char buf[_SYS_ERRMSG_MAXLEN];
+ static const char unknown[14] = {
+ 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
+ };
+
+ retval = EINVAL;
+
+ if (((unsigned int) errnum) < _SYS_NERR) {
+ /* Trade time for space. This function should rarely be called
+ * so rather than keeping an array of pointers for the different
+ * messages, just run through the buffer until we find the
+ * correct string. */
+ for (s = (char *) _string_syserrmsgs, i = errnum ; i ; ++s) {
+ if (!*s) {
+ --i;
+ }
+ }
+ if (*s) { /* Make sure we have an actual message. */
+ retval = 0;
+ goto GOT_MESG;
+ }
+ }
+
+ s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
+ memcpy(s, unknown, sizeof(unknown));
+
+ GOT_MESG:
+ if (!strerrbuf) { /* SUSv3 */
+ buflen = 0;
+ }
+ i = strlen(s) + 1;
+ if (i > buflen) {
+ i = buflen;
+ retval = ERANGE;
+ }
+
+ if (i) {
+ memcpy(strerrbuf, s, i);
+ strerrbuf[i-1] = 0; /* In case buf was too small. */
+ }
+
+ if (retval) {
+ __set_errno(retval);
+ }
+
+ return retval;
+}
+
+#endif
+/**********************************************************************/
/* GNU extension functions. */
/**********************************************************************/
+#ifdef L__glibc_strerror_r
+
+weak_alias(_glibc_strerror_r,__strerror_r);
+
+char *_glibc_strerror_r(int errnum, char *strerrbuf, size_t buflen)
+{
+ _susv3_strerror_r(errnum, strerrbuf, buflen);
+
+ return strerrbuf;
+}
+
+#endif
+/**********************************************************************/
#ifdef L_wmempcpy
#define L_mempcpy
#define Wmempcpy wmempcpy
@@ -903,7 +1268,7 @@ Wchar *Wstrdup(register const Wchar *s1)
#ifndef L_wmempcpy
/* uClibc's old string implementation did this to cater to some app. */
-weak_alias(mempcpy,__mempcpy)
+weak_alias(mempcpy,__mempcpy);
#endif
Wvoid *Wmempcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)