aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/string/strerror.c
diff options
context:
space:
mode:
authorAlexey Zelkin <phantom@FreeBSD.org>2005-02-27 16:58:28 +0000
committerAlexey Zelkin <phantom@FreeBSD.org>2005-02-27 16:58:28 +0000
commitfba5c5fa090c65e6dc3c736f5507a63892bab7bf (patch)
tree1c69c860555dd91411dd040d396b2d9cbcf9dec9 /lib/libc/string/strerror.c
parent8c4346e3e87833205cf0979128924b900108dd53 (diff)
Add NLS catalogs support to strerror(), strerror_r() and strsignal().
Controlled by NLS define, currently disabled by default. Idea obtained from: NetBSD
Notes
Notes: svn path=/head/; revision=142667
Diffstat (limited to 'lib/libc/string/strerror.c')
-rw-r--r--lib/libc/string/strerror.c61
1 files changed, 46 insertions, 15 deletions
diff --git a/lib/libc/string/strerror.c b/lib/libc/string/strerror.c
index 02fba0cfcd39..30894aab4aca 100644
--- a/lib/libc/string/strerror.c
+++ b/lib/libc/string/strerror.c
@@ -37,25 +37,31 @@ static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93";
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#if defined(NLS)
+#include <limits.h>
+#include <nl_types.h>
+#endif
+
#include <errno.h>
-#include <stdio.h>
#include <string.h>
+#include <stdio.h>
-#define UPREFIX "Unknown error: "
+#define UPREFIX "Unknown error"
/*
* Define a buffer size big enough to describe a 64-bit signed integer
* converted to ASCII decimal (19 bytes), with an optional leading sign
- * (1 byte); finally, we get the prefix and a trailing NUL from UPREFIX.
+ * (1 byte); finally, we get the prefix, delimiter (": ") and a trailing
+ * NUL from UPREFIX.
*/
-#define EBUFSIZE (20 + sizeof(UPREFIX))
+#define EBUFSIZE (20 + 2 + sizeof(UPREFIX))
/*
* Doing this by hand instead of linking with stdio(3) avoids bloat for
* statically linked binaries.
*/
static void
-errstr(int num, char *buf, size_t len)
+errstr(int num, char *uprefix, char *buf, size_t len)
{
char *t;
unsigned int uerr;
@@ -69,31 +75,56 @@ errstr(int num, char *buf, size_t len)
} while (uerr /= 10);
if (num < 0)
*--t = '-';
- strlcpy(buf, UPREFIX, len);
+ *--t = ' ';
+ *--t = ':';
+ strlcpy(buf, uprefix, len);
strlcat(buf, t, len);
}
int
strerror_r(int errnum, char *strerrbuf, size_t buflen)
{
+ int retval = 0;
+#if defined(NLS)
+ int saved_errno = errno;
+ nl_catd catd;
+ catd = catopen("libc", NL_CAT_LOCALE);
+#endif
if (errnum < 1 || errnum >= sys_nerr) {
- errstr(errnum, strerrbuf, buflen);
- return (EINVAL);
+ errstr(errnum,
+#if defined(NLS)
+ catgets(catd, 1, 0xffff, UPREFIX),
+#else
+ UPREFIX,
+#endif
+ strerrbuf, buflen);
+ retval = EINVAL;
+ } else {
+ if (strlcpy(strerrbuf,
+#if defined(NLS)
+ catgets(catd, 1, errnum, sys_errlist[errnum]),
+#else
+ sys_errlist[errnum],
+#endif
+ buflen) >= buflen)
+ retval = ERANGE;
}
- if (strlcpy(strerrbuf, sys_errlist[errnum], buflen) >= buflen)
- return (ERANGE);
- return (0);
+
+#if defined(NLS)
+ catclose(catd);
+ errno = saved_errno;
+#endif
+
+ return (retval);
}
char *
strerror(int num)
{
- static char ebuf[EBUFSIZE];
+ static char ebuf[NL_TEXTMAX];
- if (num > 0 && num < sys_nerr)
- return ((char *)sys_errlist[num]);
+ if (strerror_r(num, ebuf, sizeof(ebuf)) != 0)
errno = EINVAL;
- errstr(num, ebuf, sizeof(ebuf));
return (ebuf);
}