summaryrefslogtreecommitdiff
path: root/lib/libc/string
diff options
context:
space:
mode:
authorjoerg <joerg@NetBSD.org>2013-08-19 13:03:12 +0000
committerjoerg <joerg@NetBSD.org>2013-08-19 13:03:12 +0000
commit7eedb4cf86cb0931b4cfe28e8d0c40b491540294 (patch)
tree6192600cfc2b792fca333df6e96fad439226f049 /lib/libc/string
parent5c78e34a232f5e4846fd1b34e67185351280355e (diff)
Add strerror_l.
Diffstat (limited to 'lib/libc/string')
-rw-r--r--lib/libc/string/strerror.c66
-rw-r--r--lib/libc/string/strerror_r.c45
2 files changed, 72 insertions, 39 deletions
diff --git a/lib/libc/string/strerror.c b/lib/libc/string/strerror.c
index 99e2bd18f61..935b6182bac 100644
--- a/lib/libc/string/strerror.c
+++ b/lib/libc/string/strerror.c
@@ -1,4 +1,4 @@
-/* $NetBSD: strerror.c,v 1.14 2006/01/26 11:13:42 kleink Exp $ */
+/* $NetBSD: strerror.c,v 1.15 2013/08/19 13:03:12 joerg Exp $ */
/*
* Copyright (c) 1988 Regents of the University of California.
@@ -30,30 +30,64 @@
*/
#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char *sccsid = "@(#)strerror.c 5.6 (Berkeley) 5/4/91";
-#else
-__RCSID("$NetBSD: strerror.c,v 1.14 2006/01/26 11:13:42 kleink Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
+__RCSID("$NetBSD: strerror.c,v 1.15 2013/08/19 13:03:12 joerg Exp $");
+
+#define __SETLOCALE_SOURCE__
#include "namespace.h"
-#include <string.h>
-#include <limits.h>
#include <errno.h>
-#include "extern.h"
+#include <limits.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
-/*
- * Since perror() is not allowed to change the contents of strerror()'s
- * static buffer, both functions supply their own buffers to strerror_r()
- */
+#include "extern.h"
+#ifdef _REENTRANT
+#include "reentrant.h"
+#endif
+#include "setlocale_local.h"
__aconst char *
strerror(int num)
{
+
+ return strerror_l(num, _current_locale());
+}
+
+#ifdef _REENTRANT
+static thread_key_t strerror_key;
+static once_t strerror_once = ONCE_INITIALIZER;
+
+static void
+strerror_setup(void)
+{
+
+ thr_keycreate(&strerror_key, free);
+}
+#endif
+
+__aconst char *
+strerror_l(int num, locale_t loc)
+{
+#ifdef _REENTRANT
+ int error;
+ char *buf;
+
+ thr_once(&strerror_once, strerror_setup);
+ buf = thr_getspecific(strerror_key);
+ if (buf == NULL) {
+ buf = malloc(NL_TEXTMAX);
+ if (buf == NULL) {
+ static char fallback_buf[NL_TEXTMAX];
+ buf = fallback_buf;
+ }
+ thr_setspecific(strerror_key, buf);
+ }
+#else
static char buf[NL_TEXTMAX];
- int error = strerror_r(num, buf, sizeof(buf));
+#endif
+
+ error = _strerror_lr(num, buf, NL_TEXTMAX, loc);
if (error)
errno = error;
return buf;
diff --git a/lib/libc/string/strerror_r.c b/lib/libc/string/strerror_r.c
index a900036ea6c..948b06aee2e 100644
--- a/lib/libc/string/strerror_r.c
+++ b/lib/libc/string/strerror_r.c
@@ -1,4 +1,4 @@
-/* $NetBSD: strerror_r.c,v 1.2 2005/07/30 15:21:21 christos Exp $ */
+/* $NetBSD: strerror_r.c,v 1.3 2013/08/19 13:03:12 joerg Exp $ */
/*
* Copyright (c) 1988 Regents of the University of California.
@@ -30,38 +30,27 @@
*/
#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char *sccsid = "@(#)strerror.c 5.6 (Berkeley) 5/4/91";
-#else
-__RCSID("$NetBSD: strerror_r.c,v 1.2 2005/07/30 15:21:21 christos Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
+__RCSID("$NetBSD: strerror_r.c,v 1.3 2013/08/19 13:03:12 joerg Exp $");
#include "namespace.h"
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
#ifdef NLS
#include <limits.h>
#include <nl_types.h>
+#define __SETLOCALE_SOURCE__
+#include <locale.h>
+#include "setlocale_local.h"
#endif
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
#include "extern.h"
-#ifdef _LIBC
-# ifdef __weak_alias
__weak_alias(strerror_r, _strerror_r)
-# endif
-#endif
int
-#ifdef _LIBC
-_strerror_r(int num, char *buf, size_t buflen)
-#else
-strerror_r(int num, char *buf, size_t buflen)
-#endif
+_strerror_lr(int num, char *buf, size_t buflen, locale_t loc)
{
#define UPREFIX "Unknown error: %u"
unsigned int errnum = num;
@@ -70,7 +59,7 @@ strerror_r(int num, char *buf, size_t buflen)
#ifdef NLS
int saved_errno = errno;
nl_catd catd;
- catd = catopen("libc", NL_CAT_LOCALE);
+ catd = catopen_l("libc", NL_CAT_LOCALE, loc);
#endif
_DIAGASSERT(buf != NULL);
@@ -83,7 +72,7 @@ strerror_r(int num, char *buf, size_t buflen)
#endif
} else {
#ifdef NLS
- slen = snprintf(buf, buflen,
+ slen = snprintf_l(buf, buflen, loc,
catgets(catd, 1, 0xffff, UPREFIX), errnum);
#else
slen = snprintf(buf, buflen, UPREFIX, errnum);
@@ -101,3 +90,13 @@ strerror_r(int num, char *buf, size_t buflen)
return retval;
}
+
+int
+strerror_r(int num, char *buf, size_t buflen)
+{
+#ifdef NLS
+ return _strerror_lr(num, buf, buflen, _current_locale());
+#else
+ return _strerror_lr(num, buf, buflen, NULL);
+#endif
+}