summaryrefslogtreecommitdiff
path: root/libguile/posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/posix.c')
-rw-r--r--libguile/posix.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/libguile/posix.c b/libguile/posix.c
index 8a83a1e7e..8129c6413 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -40,7 +40,7 @@
#include "libguile/validate.h"
#include "libguile/posix.h"
-#include "libguile/i18n.h"
+#include "libguile/gettext.h"
#include "libguile/threads.h"
@@ -115,6 +115,10 @@ extern char ** environ;
#include <locale.h>
#endif
+#if (defined HAVE_NEWLOCALE) && (defined HAVE_STRCOLL_L)
+# define USE_GNU_LOCALE_API
+#endif
+
#if HAVE_CRYPT_H
# include <crypt.h>
#endif
@@ -1380,7 +1384,15 @@ SCM_DEFINE (scm_putenv, "putenv", 1, 0, 0,
}
#undef FUNC_NAME
+#ifndef USE_GNU_LOCALE_API
+/* This mutex is used to serialize invocations of `setlocale ()' on non-GNU
+ systems (i.e., systems where a reentrant locale API is not available).
+ See `i18n.c' for details. */
+scm_i_pthread_mutex_t scm_i_locale_mutex;
+#endif
+
#ifdef HAVE_SETLOCALE
+
SCM_DEFINE (scm_setlocale, "setlocale", 1, 1, 0,
(SCM category, SCM locale),
"If @var{locale} is omitted, return the current value of the\n"
@@ -1409,7 +1421,14 @@ SCM_DEFINE (scm_setlocale, "setlocale", 1, 1, 0,
scm_dynwind_free (clocale);
}
+#ifndef USE_GNU_LOCALE_API
+ scm_i_pthread_mutex_lock (&scm_i_locale_mutex);
+#endif
rv = setlocale (scm_i_to_lc_category (category, 1), clocale);
+#ifndef USE_GNU_LOCALE_API
+ scm_i_pthread_mutex_unlock (&scm_i_locale_mutex);
+#endif
+
if (rv == NULL)
{
/* POSIX and C99 don't say anything about setlocale setting errno, so
@@ -1943,9 +1962,13 @@ SCM_DEFINE (scm_gethostname, "gethostname", 0, 0, 0,
#endif /* HAVE_GETHOSTNAME */
-void
+void
scm_init_posix ()
{
+#ifndef USE_GNU_LOCALE_API
+ scm_i_pthread_mutex_init (&scm_i_locale_mutex, NULL);
+#endif
+
scm_add_feature ("posix");
#ifdef HAVE_GETEUID
scm_add_feature ("EIDs");