summaryrefslogtreecommitdiffstats
path: root/lib/libc/string/strerror_r.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/string/strerror_r.c')
-rw-r--r--lib/libc/string/strerror_r.c110
1 files changed, 100 insertions, 10 deletions
diff --git a/lib/libc/string/strerror_r.c b/lib/libc/string/strerror_r.c
index aab6db5303c..db264bcf505 100644
--- a/lib/libc/string/strerror_r.c
+++ b/lib/libc/string/strerror_r.c
@@ -1,30 +1,120 @@
-/* $OpenBSD: strerror_r.c,v 1.1 2002/11/21 20:45:05 marc Exp $ */
+/* $OpenBSD: strerror_r.c,v 1.2 2004/05/03 05:07:34 espie Exp $ */
/* Public Domain <marc@snafu.org> */
#if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: strerror_r.c,v 1.1 2002/11/21 20:45:05 marc Exp $";
+static char *rcsid = "$OpenBSD: strerror_r.c,v 1.2 2004/05/03 05:07:34 espie Exp $";
#endif /* LIBC_SCCS and not lint */
+#ifdef NLS
+#define catclose _catclose
+#define catgets _catgets
+#define catopen _catopen
+#include <nl_types.h>
+#endif
+
+#define sys_errlist _sys_errlist
+#define sys_nerr _sys_nerr
+
#include <errno.h>
#include <limits.h>
#include <string.h>
-extern char *__strerror(int, char *);
+static size_t
+__digits10(unsigned int num)
+{
+ size_t i = 0;
+
+ do {
+ num /= 10;
+ i++;
+ } while (num != 0);
+
+ return i;
+}
+
+static void
+__itoa(int num, char *buffer, size_t start, size_t end)
+{
+ size_t pos;
+ unsigned int a;
+ int neg;
+
+ if (num < 0) {
+ a = -num;
+ neg = 1;
+ }
+ else {
+ a = num;
+ neg = 0;
+ }
+
+ pos = start + __digits10(a);
+ if (neg)
+ pos++;
+
+ if (pos < end)
+ buffer[pos] = '\0';
+ else {
+ if (end)
+ buffer[--end] = '\0'; /* XXX */
+ }
+ pos--;
+ do {
+
+ if (pos < end)
+ buffer[pos] = (a % 10) + '0';
+ pos--;
+ a /= 10;
+ } while (a != 0);
+ if (neg)
+ if (pos < end)
+ buffer[pos] = '-';
+}
+
+
+#define UPREFIX "Unknown error: "
int
strerror_r(int errnum, char *strerrbuf, size_t buflen)
{
int save_errno;
int ret_errno;
- char buf[NL_TEXTMAX];
+ size_t len;
+#ifdef NLS
+ nl_catd catd;
+#endif
save_errno = errno;
- errno = 0;
- __strerror(errnum, buf);
- if (strlcpy(strerrbuf, buf, buflen) >= buflen)
- errno = ERANGE;
- ret_errno = errno;
- errno = save_errno;
+ ret_errno = 0;
+
+#ifdef NLS
+ catd = catopen("libc", 0);
+#endif
+
+ if (errnum >= 0 && errnum < sys_nerr) {
+#ifdef NLS
+ len = strlcpy(strerrbuf, catgets(catd, 1, errnum,
+ (char *)sys_errlist[errnum]), buflen);
+#else
+ len = strlcpy(strerrbuf, sys_errlist[errnum], buflen);
+#endif
+ if (len >= buflen)
+ ret_errno = ERANGE;
+ } else {
+#ifdef NLS
+ len = strlcpy(strerrbuf, catgets(catd, 1, 0xffff, UPREFIX),
+ buflen);
+#else
+ len = strlcpy(strerrbuf, UPREFIX, buflen);
+#endif
+ __itoa(errnum, strerrbuf, len, buflen);
+ ret_errno = EINVAL;
+ }
+
+#ifdef NLS
+ catclose(catd);
+#endif
+ errno = ret_errno ? ret_errno : save_errno;
return (ret_errno);
}