+?RCS: $Id$
+?RCS:
+?RCS: Copyright (c) 2017 Karl Williamson
+?RCS:
+?RCS: You may distribute under the terms of either the GNU General Public
+?RCS: License or the Artistic License, as specified in the README file.
+?RCS:
+?MAKE:d_thread_safe_nl_langinfo_l: Compile cat rm_try Oldconfig \
+ i_pthread i_stdlib i_string i_langinfo i_locale \
+ usethreads run
+?MAKE: -pick add $@ %<
+?S:d_thread_safe_nl_langinfo_l:
+?S: This variable contains the eventual value of the
+?S: HAS_THREAD_SAFE_NL_LANGINFO_L symbol, which indicates if the
+?S: nl_langinfo_l() function exists and is thread-safe.
+?S:.
+?C:HAS_THREAD_SAFE_NL_LANGINFO_L:
+?C: This symbol, when defined, indicates presence of the nl_langinfo_l()
+?C: function, and that it is thread-safe.
+?C:.
+?H:#$d_thread_safe_nl_langinfo_l HAS_THREAD_SAFE_NL_LANGINFO_L /**/
+?H:.
+?F:!try
+: check for thread_safe_nl_langinfo_l item
+$cat <<EOM
+
+Checking to see if you have nl_langinfo_l() and that it is thread-safe
+EOM
+?X: Despite claiming that nl_langinfo_l() is thread-safe, the POSIX 2008
+?X: standard allows for a non-safe implementation:
+?X:
+?X: "nl_langinfo_l() uses an internal per-thread buffer, and nl_langinfo()
+?X: uses (in all threads) the same buffer that nl_langinfo_l() uses in the
+?X: initial thread. There can be interactions, but only when
+?X: nl_langinfo_l() is called in the initial thread"
+?X:
+?X: If nl_langinfo_l() isn't thread safe, might as well just use plain
+?X: nl_langinfo().
+?X:
+?X: This program calls nl_langinfo_l(), then creates a thread, calling plain
+?X: nl_langinfo() from within it, then sees if the buffer in the original
+?X: thread was changed.
+$cat >try.c <<EOCP
+#$i_stdlib I_STDLIB
+#ifdef I_STDLIB
+# include <stdlib.h>
+#endif
+#$i_string I_STRING
+#ifdef I_STRING
+# include <string.h>
+#endif
+#$i_langinfo I_LANGINFO
+#ifdef I_LANGINFO
+# include <langinfo.h>
+#endif
+#$i_pthread I_PTHREAD
+#ifdef I_PTHREAD
+# include <pthread.h>
+#endif
+#$i_locale I_LOCALE
+#ifdef I_LOCALE
+# include <locale.h>
+#endif
+
+void *
+thread_start(void * arg)
+{
+ nl_langinfo(RADIXCHAR);
+}
+
+int main() {
+ char * main_buffer;
+ char save_main_buffer[1000];
+ pthread_t subthread;
+ pthread_attr_t attr;
+
+ main_buffer = nl_langinfo_l(CODESET, newlocale(LC_ALL_MASK, "C", 0));
+
+ /* If too large for our generous allowance, just assume we don't have
+ * it. */
+ if (strlen(main_buffer) >= sizeof(save_main_buffer)) {
+ exit(1);
+ }
+
+ strcpy(save_main_buffer, main_buffer);
+
+ if (pthread_attr_init(&attr) != 0) {
+ exit(1);
+ }
+
+ if (pthread_create(&subthread, &attr, thread_start, NULL) != 0) {
+ exit(1);
+ }
+
+ if (pthread_join(subthread, NULL) != 0) {
+ exit(1);
+ }
+
+ exit(! (strcmp(main_buffer, save_main_buffer) == 0));
+}
+EOCP
+case "$usethreads" in
+ define)
+ set try
+ if eval $compile; then
+ echo "Your system has nl_langinfo_l()..." >&4
+ if $run ./try; then
+ echo "and it is thread-safe (just as I'd hoped)." >&4
+ d_thread_safe_nl_langinfo_l="$define"
+ echo "$d_thread_safe_nl_langinfo_l" >&4
+ else
+ echo "but it isn't thread-safe, so we won't use it." >&4
+ fi
+ else
+ echo "your system does not have nl_langinfo_l()" >&4
+ fi
+ ;;
+ *) echo "Since threads aren't selected, we won't bother looking for nl_langinfo_l()" >&4
+ esac
+$rm_try
+