Index: lib/libc/include/libc_private.h diff -u lib/libc/include/libc_private.h.orig lib/libc/include/libc_private.h --- lib/libc/include/libc_private.h.orig 2010-01-01 02:14:04.000000000 +0900 +++ lib/libc/include/libc_private.h 2010-01-24 03:39:20.480514921 +0900 @@ -211,4 +211,10 @@ /* execve() with PATH processing to implement posix_spawnp() */ int _execvpe(const char *, char * const *, char * const *); +#ifdef NLS +extern char *__cat_gets(int, int, const char *); +extern void __cat_lock(void); +extern void __cat_unlock(void); +#endif + #endif /* _LIBC_PRIVATE_H_ */ Index: lib/libc/net/gai_strerror.c diff -u -p lib/libc/net/gai_strerror.c.orig lib/libc/net/gai_strerror.c --- lib/libc/net/gai_strerror.c.orig 2009-11-23 02:05:46.000000000 +0900 +++ lib/libc/net/gai_strerror.c 2010-01-24 03:30:15.086490501 +0900 @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD: src/lib/libc/net/gai #include "reentrant.h" #endif #include "un-namespace.h" +#include "libc_private.h" /* Entries EAI_ADDRFAMILY (1) and EAI_NODATA (7) are obsoleted, but left */ /* for backward compatibility with userland code prior to 2553bis-02 */ @@ -79,7 +80,6 @@ const char * gai_strerror(int ecode) { #if defined(NLS) - nl_catd catd; char *buf; if (thr_main() != 0) @@ -98,17 +98,17 @@ gai_strerror(int ecode) } } - catd = catopen("libc", NL_CAT_LOCALE); + __cat_lock(); if (ecode > 0 && ecode < EAI_MAX) - strlcpy(buf, catgets(catd, 3, ecode, ai_errlist[ecode]), + strlcpy(buf, __cat_gets(3, ecode, ai_errlist[ecode]), sizeof(gai_buf)); else if (ecode == 0) - strlcpy(buf, catgets(catd, 3, NL_MSGMAX - 1, "Success"), + strlcpy(buf, __cat_gets(3, NL_MSGMAX - 1, "Success"), sizeof(gai_buf)); else - strlcpy(buf, catgets(catd, 3, NL_MSGMAX, "Unknown error"), + strlcpy(buf, __cat_gets(3, NL_MSGMAX, "Unknown error"), sizeof(gai_buf)); - catclose(catd); + __cat_unlock(); return buf; thr_err: Index: lib/libc/string/strerror.c diff -u -p lib/libc/string/strerror.c.orig lib/libc/string/strerror.c --- lib/libc/string/strerror.c.orig 2009-08-03 17:13:06.000000000 +0900 +++ lib/libc/string/strerror.c 2010-01-24 04:11:37.168662523 +0900 @@ -33,14 +33,16 @@ static char sccsid[] = "@(#)strerror.c 8 #include __FBSDID("$FreeBSD: src/lib/libc/string/strerror.c,v 1.16.10.1 2009/08/03 08:13:06 kensmith Exp $"); -#if defined(NLS) -#include -#endif - +#include "namespace.h" #include #include #include #include +#if defined(NLS) +#include +#include "reentrant.h" +#endif +#include "un-namespace.h" #define UPREFIX "Unknown error" @@ -52,6 +54,31 @@ __FBSDID("$FreeBSD: src/lib/libc/string/ */ #define EBUFSIZE (20 + 2 + sizeof(UPREFIX)) +#if defined(NLS) +static mutex_t catd_mutex = MUTEX_INITIALIZER; +static nl_catd catd; + +char * +__cat_gets(int set_id, int msg_id, const char *s) +{ + if (catd == NULL) + catd = catopen("libc", NL_CAT_LOCALE); + return (catgets(catd, set_id, msg_id, s)); +} + +void +__cat_lock(void) +{ + mutex_lock(&catd_mutex); +} + +void +__cat_unlock(void) +{ + mutex_unlock(&catd_mutex); +} +#endif + /* * Doing this by hand instead of linking with stdio(3) avoids bloat for * statically linked binaries. @@ -83,14 +110,14 @@ strerror_r(int errnum, char *strerrbuf, int retval = 0; #if defined(NLS) int saved_errno = errno; - nl_catd catd; - catd = catopen("libc", NL_CAT_LOCALE); + + __cat_lock(); #endif if (errnum < 1 || errnum >= sys_nerr) { errstr(errnum, #if defined(NLS) - catgets(catd, 1, 0xffff, UPREFIX), + __cat_gets(1, 0xffff, UPREFIX), #else UPREFIX, #endif @@ -99,7 +126,7 @@ strerror_r(int errnum, char *strerrbuf, } else { if (strlcpy(strerrbuf, #if defined(NLS) - catgets(catd, 1, errnum, sys_errlist[errnum]), + __cat_gets(1, errnum, sys_errlist[errnum]), #else sys_errlist[errnum], #endif @@ -108,7 +135,7 @@ strerror_r(int errnum, char *strerrbuf, } #if defined(NLS) - catclose(catd); + __cat_unlock(); errno = saved_errno; #endif