--- old/usr/src/head/locale.h	Mon Jun  2 23:06:27 2014
+++ new/usr/src/head/locale.h	Mon Jun  2 23:06:27 2014
@@ -85,19 +85,19 @@
 #endif
 
 #if	defined(__STDC__)
-locale_t	duplocale(locale_t);
-void		freelocale(locale_t);
-locale_t	newlocale(int, const char *, locale_t);
-locale_t	uselocale(locale_t);
+extern locale_t	duplocale(locale_t);
+extern void	freelocale(locale_t);
+extern locale_t	newlocale(int, const char *, locale_t);
+extern locale_t	uselocale(locale_t);
 #else	/* __STDC__ */
-locale_t	duplocale();
-void		freelocale();
-locale_t	newlocale();
-locale_t	uselocale();
+extern locale_t	duplocale();
+extern void	freelocale();
+extern locale_t	newlocale();
+extern locale_t	uselocale();
 #endif	/* __STDC__ */
 
-#define	LC_GLOBAL_LOCALE	__global_locale
-extern locale_t			__global_locale;
+#define	LC_GLOBAL_LOCALE	(__global_locale())
+extern locale_t			__global_locale(void);
 
 #endif	/* defined(_XPG7) || !defined(_STRICT_SYMBOLS) */
 
--- old/usr/src/head/xlocale.h	Mon Jun  2 23:06:27 2014
+++ new/usr/src/head/xlocale.h	Mon Jun  2 23:06:27 2014
@@ -48,47 +48,47 @@
 typedef struct locale *locale_t;
 #endif
 
-int mbsinit_l(const mbstate_t *, locale_t);
+extern int mbsinit_l(const mbstate_t *, locale_t);
 
-size_t mbsrtowcs_l(wchar_t *_RESTRICT_KYWD, const char **_RESTRICT_KYWD,
+extern size_t mbsrtowcs_l(wchar_t *_RESTRICT_KYWD, const char **_RESTRICT_KYWD,
     size_t, mbstate_t *_RESTRICT_KYWD, locale_t);
 
-size_t mbsnrtowcs_l(wchar_t *_RESTRICT_KYWD, const char **_RESTRICT_KYWD,
+extern size_t mbsnrtowcs_l(wchar_t *_RESTRICT_KYWD, const char **_RESTRICT_KYWD,
     size_t, size_t, mbstate_t *_RESTRICT_KYWD, locale_t);
 
-char *strptime_l(const char *_RESTRICT_KYWD, const char *_RESTRICT_KYWD,
+extern char *strptime_l(const char *_RESTRICT_KYWD, const char *_RESTRICT_KYWD,
     struct tm *_RESTRICT_KYWD, locale_t);
 
-int wcwidth_l(wchar_t, locale_t);
+extern int wcwidth_l(wchar_t, locale_t);
 
-int wcswidth_l(const wchar_t *, size_t, locale_t);
+extern int wcswidth_l(const wchar_t *, size_t, locale_t);
 
-int iswspecial_l(wint_t, locale_t);
-int iswnumber_l(wint_t, locale_t);
-int iswhexnumber_l(wint_t, locale_t);
-int iswideogram_l(wint_t, locale_t);
-int iswphonogram_l(wint_t, locale_t);
+extern int iswspecial_l(wint_t, locale_t);
+extern int iswnumber_l(wint_t, locale_t);
+extern int iswhexnumber_l(wint_t, locale_t);
+extern int iswideogram_l(wint_t, locale_t);
+extern int iswphonogram_l(wint_t, locale_t);
 
-wint_t btowc_l(int, locale_t);
-int wctob_l(wint_t, locale_t);
-size_t mbrtowc_l(wchar_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD, size_t,
+extern wint_t btowc_l(int, locale_t);
+extern int wctob_l(wint_t, locale_t);
+extern size_t mbrtowc_l(wchar_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD,
+    size_t, mbstate_t *_RESTRICT_KYWD, locale_t);
+extern size_t mbstowcs_l(wchar_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD,
+    size_t, locale_t);
+extern int mblen_l(const char *, size_t, locale_t);
+extern size_t mbrlen_l(const char *_RESTRICT_KYWD, size_t,
     mbstate_t *_RESTRICT_KYWD, locale_t);
-size_t mbstowcs_l(wchar_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD, size_t,
+extern int mbtowc_l(wchar_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD, size_t,
     locale_t);
-int mblen_l(const char *, size_t, locale_t);
-size_t mbrlen_l(const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD,
-    locale_t);
-int mbtowc_l(wchar_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD, size_t,
-    locale_t);
-size_t wcsrtombs_l(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD,
+extern size_t wcsrtombs_l(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD,
     size_t len, mbstate_t *_RESTRICT_KYWD, locale_t);
-size_t wcrtomb_l(char *_RESTRICT_KYWD, wchar_t, mbstate_t *_RESTRICT_KYWD,
-    locale_t);
-size_t wcstombs_l(char *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD, size_t,
-    locale_t);
-int wctomb_l(char *, wchar_t, locale_t);
+extern size_t wcrtomb_l(char *_RESTRICT_KYWD, wchar_t,
+    mbstate_t *_RESTRICT_KYWD, locale_t);
+extern size_t wcstombs_l(char *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
+    size_t, locale_t);
+extern int wctomb_l(char *, wchar_t, locale_t);
 
-unsigned char __mb_cur_max_l(locale_t);
+extern unsigned char __mb_cur_max_l(locale_t);
 #ifndef	MB_CUR_MAX_L
 #define	MB_CUR_MAX_L(l)	(__mb_cur_max_l(l))
 #endif
@@ -99,8 +99,8 @@
 typedef __FILE FILE;
 #endif
 
-wint_t fgetwc_l(FILE *, locale_t);
-wint_t getwc_l(FILE *, locale_t);
+extern wint_t fgetwc_l(FILE *, locale_t);
+extern wint_t getwc_l(FILE *, locale_t);
 
 #ifndef getwchar_l
 #define	getwchar_l(l)	fgetwc_l(stdin, (l))
--- old/usr/src/lib/libc/port/locale/localeimpl.c	Mon Jun  2 23:06:27 2014
+++ new/usr/src/lib/libc/port/locale/localeimpl.c	Mon Jun  2 23:06:27 2014
@@ -114,8 +114,14 @@
 	.runelocale = &_DefaultRuneLocale,
 };
 
-locale_t __global_locale = &posix_locale;
+locale_t ___global_locale = &posix_locale;
 
+locale_t
+__global_locale(void)
+{
+	return (___global_locale);
+}
+
 /*
  * Category names for getenv()  Note that this was modified
  * for Solaris.  See <iso/locale_iso.h>.
@@ -396,7 +402,7 @@
 		errno = EINVAL;
 		return (NULL);
 	}
-	loc = duplocale(base != NULL ? base : __global_locale);
+	loc = duplocale(base != NULL ? base : ___global_locale);
 	if (loc == NULL) {
 		return (NULL);
 	}
@@ -418,7 +424,7 @@
 		__locdata_release(loc->locdata[i]);
 		loc->locdata[i] = ldata;
 	}
-	if (base && base != __global_locale) {
+	if (base && base != ___global_locale) {
 		freelocale(base);
 	}
 	loc->collate = loc->locdata[LC_COLLATE]->l_data[0];
@@ -434,7 +440,7 @@
 locale_t
 uselocale(locale_t loc)
 {
-	locale_t lastloc = __global_locale;
+	locale_t lastloc = ___global_locale;
 	locale_t *locptr;
 
 	locptr = tsdalloc(_T_SETLOCALE, sizeof (locale_t), freelocptr);
@@ -453,7 +459,7 @@
 		 * Set it to LC_GLOBAL_LOCAL to return to using
 		 * the global locale (setlocale).
 		 */
-		if (loc == __global_locale) {
+		if (loc == ___global_locale) {
 			*locptr = NULL;
 		} else {
 			/* No validation of the provided locale at present */
--- old/usr/src/lib/libc/port/locale/localeimpl.h	Mon Jun  2 23:06:28 2014
+++ new/usr/src/lib/libc/port/locale/localeimpl.h	Mon Jun  2 23:06:28 2014
@@ -99,5 +99,6 @@
 extern struct locdata	__posix_time_locdata;
 extern struct locdata	__posix_ctype_locdata;
 extern struct locdata	__posix_collate_locdata;
+extern locale_t ___global_locale; 
 
 #endif	/* _LOCALEIMPL_H_ */
--- old/usr/src/lib/libc/port/locale/setlocale.c	Mon Jun  2 23:06:28 2014
+++ new/usr/src/lib/libc/port/locale/setlocale.c	Mon Jun  2 23:06:28 2014
@@ -72,9 +72,9 @@
 	}
 
 	if (locname == NULL)
-		return (current_locale(__global_locale, category));
+		return (current_locale(___global_locale, category));
 
-	if ((oldloc = duplocale(__global_locale)) == NULL)
+	if ((oldloc = duplocale(___global_locale)) == NULL)
 		return (NULL);
 
 	mask = (category == LC_ALL ? LC_ALL_MASK : (1 << category));
@@ -85,8 +85,8 @@
 		return (NULL);
 	}
 
-	oldloc = __global_locale;
-	__global_locale = newloc;
+	oldloc = ___global_locale;
+	___global_locale = newloc;
 
 	install_legacy(newloc, mask);
 
--- old/usr/src/lib/libc/port/mapfile-vers	Mon Jun  2 23:06:28 2014
+++ new/usr/src/lib/libc/port/mapfile-vers	Mon Jun  2 23:06:28 2014
@@ -95,7 +95,9 @@
 
 SYMBOL_VERSION ILLUMOS_0.8 {	# POSIX 2008 newlocale and friends
     protected:
+	__global_locale;
 	__mb_cur_max;
+	__mb_cur_max_l;
 	btowc_l;
 	duplocale;
 	fgetwc_l;
--- /dev/null	Mon Jun  2 23:06:28 2014
+++ new/usr/src/pkg/manifests/system-test-libctest.mf	Mon Jun  2 23:06:28 2014
@@ -0,0 +1,37 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+set name=pkg.fmri value=pkg:/system/test/libctest@$(PKGVERS)
+set name=pkg.description value="C library Unit Tests"
+set name=pkg.summary value="C Library Unit Test Suite"
+set name=info.classification \
+    value=org.opensolaris.category.2008:Development/System
+set name=variant.arch value=$(ARCH)
+dir path=opt/libc-tests
+dir path=opt/libc-tests/bin
+dir path=opt/libc-tests/runfiles
+dir path=opt/libc-tests/tests
+file path=opt/libc-tests/README mode=0444
+file path=opt/libc-tests/bin/libctest mode=0555
+file path=opt/libc-tests/runfiles/default.run mode=0444
+file path=opt/libc-tests/tests/newlocale_test mode=0555
+license lic_CDDL license=lic_CDDL
+depend fmri=locale/de type=require
+depend fmri=locale/en type=require
+depend fmri=locale/ja type=require
+depend fmri=locale/ru type=require
+depend fmri=system/test/testrunner type=require
--- /dev/null	Mon Jun  2 23:06:28 2014
+++ new/usr/src/test/libc-tests/Makefile	Mon Jun  2 23:06:28 2014
@@ -0,0 +1,21 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+.PARALLEL: $(SUBDIRS)
+
+SUBDIRS = cmd runfiles tests doc
+
+include $(SRC)/test/Makefile.com
--- /dev/null	Mon Jun  2 23:06:28 2014
+++ new/usr/src/test/libc-tests/cmd/Makefile	Mon Jun  2 23:06:28 2014
@@ -0,0 +1,38 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+# Copyright (c) 2012 by Delphix. All rights reserved.
+#
+
+include $(SRC)/Makefile.master
+include $(SRC)/test/Makefile.com
+
+ROOTOPTPKG = $(ROOT)/opt/libc-tests
+ROOTBIN = $(ROOTOPTPKG)/bin
+
+PROGS = libctest
+
+CMDS = $(PROGS:%=$(ROOTBIN)/%)
+$(CMDS) := FILEMODE = 0555
+
+all lint clean clobber:
+
+install: $(CMDS)
+
+$(CMDS): $(ROOTBIN)
+
+$(ROOTBIN):
+	$(INS.dir)
+
+$(ROOTBIN)/%: %.ksh
+	$(INS.rename)
--- /dev/null	Mon Jun  2 23:06:28 2014
+++ new/usr/src/test/libc-tests/cmd/libctest.ksh	Mon Jun  2 23:06:28 2014
@@ -0,0 +1,63 @@
+#!/usr/bin/ksh
+
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+export MY_TESTS="/opt/libc-tests"
+runner="/opt/test-runner/bin/run"
+
+function fail
+{
+	echo $1
+	exit ${2:-1}
+}
+
+function find_runfile
+{
+	typeset distro=
+	if [[ -d /opt/delphix && -h /etc/delphix/version ]]; then
+		distro=delphix
+	elif [[ 0 -ne $(grep -c OpenIndiana /etc/release 2>/dev/null) ]]; then
+		distro=openindiana
+	elif [[ 0 -ne $(grep -c OmniOS /etc/release 2>/dev/null) ]]; then
+		distro=omnios
+	fi
+
+	if [[ ! -f $MY_TESTS/runfiles/$distro.run ]] && \
+	   [[ -f $MY_TESTS/runfiles/default.run ]]; then
+		distro=default
+	fi
+
+	[[ -n $distro ]] && echo $MY_TESTS/runfiles/$distro.run
+}
+
+while getopts c: c; do
+	case $c in
+	'c')
+		runfile=$OPTARG
+		[[ -f $runfile ]] || fail "Cannot read file: $runfile"
+		;;
+	esac
+done
+shift $((OPTIND - 1))
+
+[[ -z $runfile ]] && runfile=$(find_runfile)
+[[ -z $runfile ]] && fail "Couldn't determine distro"
+
+$runner -c $runfile
+
+exit $?
--- /dev/null	Mon Jun  2 23:06:28 2014
+++ new/usr/src/test/libc-tests/doc/Makefile	Mon Jun  2 23:06:28 2014
@@ -0,0 +1,36 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+# Copyright (c) 2012 by Delphix. All rights reserved.
+#
+
+include $(SRC)/Makefile.master
+
+READMES = README
+
+ROOTOPTPKG = $(ROOT)/opt/libc-tests
+
+FILES = $(READMES:%=$(ROOTOPTPKG)/%)
+$(FILES) := FILEMODE = 0444
+
+all: $(READMES)
+
+install: $(ROOTOPTPKG) $(FILES)
+
+clean lint clobber:
+
+$(ROOTOPTPKG):
+	$(INS.dir)
+
+$(ROOTOPTPKG)/%: %
+	$(INS.file)
--- /dev/null	Mon Jun  2 23:06:28 2014
+++ new/usr/src/test/libc-tests/doc/README	Mon Jun  2 23:06:28 2014
@@ -0,0 +1,70 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+# Copyright (c) 2012 by Delphix. All rights reserved.
+#
+
+libc Unit Test Suite README
+
+1. What this Unit Test Suite tests
+2. Building and installing this Unit Test Suite
+3. Running this Unit Test Suite
+4. Test results
+
+--------------------------------------------------------------------------------
+
+1. What this Unit Test Suite tests
+
+This Unit Test Suite is for testing various libc interfaces.
+
+2. Building and installing this Unit Test Suite
+
+This Test Suite runs under the testrunner framework (which can be installed
+as pkg:/system/test/testrunner). To build both this Unit Test Suite and the
+testrunner without running a full nightly:
+
+	build_machine$ bldenv [-d] <your_env_file>
+	build_machine$ cd $SRC/test
+	build_machine$ dmake install
+	build_machine$ cd $SRC/pkg
+	build_machine$ dmake install
+
+Then set the publisher on the test machine to point to your repository and
+install the Utils Unit Test Suite.
+
+	test_machine# pkg install pkg:/system/test/libctest
+
+Note, the framework will be installed automatically, as this test suite
+depends on it.
+
+Additionally some text locales are required, specifically, en_US.UTF-8,
+de_DE.UTF-8, ja_JP.UTF-8, and ru_RU.UTF-8.  Again, these are listed as
+dependencies and will be automatically installed.
+
+3. Running this Unit Test Suite
+
+The pre-requisites for running the this Unit Test Suite are:
+	- Any user may perform these tests.
+	- The en_US.UTF-8, ja_JP.UTF-8, de_DE.UTF-8, and ru_RU.UTF-8 locales
+          must be installed.
+
+Once the pre-requisites are satisfied, simply run the ostest script:
+
+	test_machine$ /opt/util-tests/bin/libctest
+
+4. Test results
+
+While the Unit Test Suite is running, one informational line is printed at
+the end of each test, and a results summary is printed at the end of the run.
+The results summary includes the location of the complete logs, which is of the
+form /var/tmp/test_results/<ISO 8601 date>.
--- /dev/null	Mon Jun  2 23:06:28 2014
+++ new/usr/src/test/libc-tests/runfiles/Makefile	Mon Jun  2 23:06:28 2014
@@ -0,0 +1,40 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+include $(SRC)/Makefile.master
+
+SRCS = default.run
+
+ROOTOPTPKG = $(ROOT)/opt/libc-tests
+RUNFILES = $(ROOTOPTPKG)/runfiles
+
+CMDS = $(SRCS:%=$(RUNFILES)/%)
+$(CMDS) := FILEMODE = 0444
+
+all: $(SRCS)
+
+install: $(CMDS)
+
+clean lint clobber:
+
+$(CMDS): $(RUNFILES) $(SRCS)
+
+$(RUNFILES):
+	$(INS.dir)
+
+$(RUNFILES)/%: %
+	$(INS.file)
--- /dev/null	Mon Jun  2 23:06:28 2014
+++ new/usr/src/test/libc-tests/runfiles/default.run	Mon Jun  2 23:06:28 2014
@@ -0,0 +1,25 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+[DEFAULT]
+pre =
+verbose = False
+quiet = False
+timeout = 60
+post =
+outputdir = /var/tmp/test_results
+
+[/opt/libc-tests/tests/newlocale_test]
--- /dev/null	Mon Jun  2 23:06:28 2014
+++ new/usr/src/test/libc-tests/tests/Makefile	Mon Jun  2 23:06:28 2014
@@ -0,0 +1,19 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+SUBDIRS = newlocale
+
+include $(SRC)/test/Makefile.com
--- /dev/null	Mon Jun  2 23:06:29 2014
+++ new/usr/src/test/libc-tests/tests/newlocale/Makefile	Mon Jun  2 23:06:29 2014
@@ -0,0 +1,58 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+include $(SRC)/cmd/Makefile.cmd
+include $(SRC)/test/Makefile.com
+
+PROG = newlocale_test
+OBJS = $(PROG:%=%.o)
+SRCS = $(OBJS:%.o=%.c)
+
+LDLIBS += -lpthread
+C99MODE = -xc99=%all
+
+ROOTOPTPKG = $(ROOT)/opt/libc-tests
+TESTDIR = $(ROOTOPTPKG)/tests
+
+CMDS = $(PROG:%=$(TESTDIR)/%)
+$(CMDS) := FILEMODE = 0555
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+	$(LINK.c) $(OBJS) -o $@ $(LDLIBS)
+	$(POST_PROCESS)
+
+%.o: ../%.c
+	$(COMPILE.c) $<
+
+install: all $(CMDS)
+
+lint: lint_SRCS
+
+clobber: clean
+	-$(RM) $(PROG)
+
+clean:
+	-$(RM) $(OBJS)
+
+$(CMDS): $(TESTDIR) $(PROG)
+
+$(TESTDIR):
+	$(INS.dir)
+
+$(TESTDIR)/%: %
+	$(INS.file)
--- /dev/null	Mon Jun  2 23:06:29 2014
+++ new/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c	Mon Jun  2 23:06:29 2014
@@ -0,0 +1,195 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
+ */
+
+/*
+ * This program tests that newlocale and uselocale work properly in
+ * multi-threaded programs.  In order for it to work, it requires that
+ * some additional locales be installed.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <langinfo.h>
+#include <nl_types.h>
+#include <err.h>
+#include <unistd.h>
+#include <pthread.h>
+
+int debug = 0;
+
+/*
+ * Note that on some platforms, different symbols are used.  For example,
+ * MacOS Mavericks uses "Eu" for Euro symbol, instead of €.  If the locale
+ * data changes, then this program will need to update to reflect that.
+ */
+struct ldata {
+	const char *locale;
+	const char *day1;
+	const char *cursym;
+} ldata[] = {
+	{ "C", "Sunday", "" },
+	{ "en_US.UTF-8", "Sunday", "$" },
+	{ "de_DE.UTF-8", "Sonntag", "€" },
+	{ "ru_RU.UTF-8", "воскресенье", "руб." },
+	{ "ja_JP.UTF-8", "日曜日", "￥" },
+};
+
+#define	NUM_LDATA	5
+#define	NUMTHR	20
+#define	NUMITR	200
+
+static void
+test_start(const char *testName, const char *format, ...)
+{
+	va_list args;
+
+	(void) printf("TEST STARTING %s: ", testName);
+
+	va_start(args, format);
+	(void) vprintf(format, args);
+	va_end(args);
+	(void) fflush(stdout);
+}
+
+static void
+test_failed(const char *testName, const char *format, ...)
+{
+	va_list args;
+
+	(void) printf("TEST FAILED %s: ", testName);
+
+	va_start(args, format);
+	(void) vprintf(format, args);
+	va_end(args);
+
+	(void) exit(-1);
+}
+
+static void
+test_passed(const char *testName)
+{
+	(void) printf("TEST PASS: %s\n", testName);
+	(void) fflush(stdout);
+}
+
+void *
+testlocale_thr(void *ptr)
+{
+	locale_t	cloc, loc;
+	struct lconv	*lc;
+	char		*day;
+	char		*tname = ptr;
+
+	for (int i = 0; i < NUMITR; i++) {
+		struct ldata *l = &ldata[i % NUM_LDATA];
+		cloc = uselocale(NULL);
+
+		loc = newlocale(LC_ALL_MASK, l->locale, NULL);
+		if (loc == NULL) {
+			test_failed("newlocale %s failed", l->locale);
+		}
+		day = nl_langinfo_l(DAY_1, loc);
+		if (strcmp(day, l->day1) != 0) {
+			test_failed(tname, "newlocale data mismatch (%s != %s)",
+			    day, l->day1);
+		}
+		if (debug)
+			(void) printf("DAY1: %s\n", day);
+
+		day = nl_langinfo(DAY_1);
+		if (strcmp(day, "Sunday") != 0) {
+			test_failed(tname, "C locale day wrong %s != Sunday",
+			    day);
+		}
+		lc = localeconv();
+		if (strcmp(lc->currency_symbol, "") != 0) {
+			test_failed(tname, "C cursym mismatch (%s != %s)",
+			    lc->currency_symbol, "");
+		}
+
+		/* we sleep a random bit to mix it up */
+		(void) usleep(rand() % 10);
+
+		(void) uselocale(loc);
+		day = nl_langinfo(DAY_1);
+		if (strcmp(day, l->day1) != 0) {
+			test_failed(tname, "uselocale data mismatch (%s != %s)",
+			    day, l->day1);
+		}
+
+		lc = localeconv();
+		if (strcmp(lc->currency_symbol, l->cursym) != 0) {
+			test_failed(tname, "uselocal cursym %s != %s",
+			    lc->currency_symbol, l->cursym);
+		}
+		if (debug)
+			(void) printf("CSYM: %s\n", lc->currency_symbol);
+
+		/* we sleep a random bit to mix it up */
+		(void) usleep(rand() % 10);
+
+		if (uselocale(cloc) != loc) {
+			test_failed(tname, "revert old locale mismatch");
+		}
+		freelocale(loc);
+		if (uselocale(LC_GLOBAL_LOCALE) != cloc) {
+			test_failed(tname, "revert GLOBAL_LOCALE mismatch");
+		}
+	}
+	return (NULL);
+}
+
+
+void
+testlocale(void)
+{
+	char		*tname = "newlocale/uselocale";
+	pthread_t	tid[NUMTHR];
+
+	test_start(tname, "running %d threads %d iterations\n", NUMTHR, NUMITR);
+
+	for (int i = 0; i < NUMTHR; i++) {
+		(void) pthread_create(&tid[i], NULL, testlocale_thr, tname);
+	}
+
+	for (int i = 0; i < NUMTHR; i++) {
+		(void) pthread_join(tid[i], NULL);
+	}
+	test_passed(tname);
+}
+
+int
+main(int argc, char **argv)
+{
+	int optc;
+
+	while ((optc = getopt(argc, argv, "d")) != EOF) {
+		switch (optc) {
+		case 'd':
+			debug++;
+			break;
+		default:
+			(void) fprintf(stderr, "Usage: %s [-d]\n", argv[0]);
+			exit(1);
+		}
+	}
+
+	testlocale();
+
+	exit(0);
+}
