This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] locale: Make _nl_C_locobj_ptr usable outside of libc

I need something like this to fix incorrect locale dependence in libresolv (bug 19687).

I tested this with the fixes, including one for nscd, which uses
__libc_C_locobj@GLIBC_PRIVATE.  libresolv uses _nl_C_locobj@GLIBC_PRIVATE.

I'm not entirely sure if we should use the function approach everywhere instead. But as far as I can tell, this patch does not lead to the allocation of space for a _nl_C_locobj copy in libresolv (which we would not want because it is wasteful).

An alternative would add of functions such as those in <ctype.h> and strcasecmp/strncasecmp which are always tied to the C locale. This would be more efficient because access to the locale object is easier, or the variants can even be optimized inline (such as isblank).

locale: Make _nl_C_locobj_ptr usable outside of libc

To avoid a copy relocation if the access happens from the main program,
the __libc_C_locobj function returns a pointer to the hidden locale
object in libc.

2016-09-16  Florian Weimer  <>

	* include/locale.h (__libc_C_locobj): Declare.
	[IS_IN (libc) || SHARED] (_nl_C_locobj): Export and add hidden
	[!IS_IN (libc) && !SHARED] (_nl_C_locobj_ptr): Call
	* locale/xlocale.c (_nl_C_locobj): Export and add hidden alias.
	* locale/Makefile (routines): Add C_locobj.
	(shared-only-routines): Likewise.
	* locale/C_locobj.c: New file.
	* locale/Versions (GLIBC_PRIVATE): Add _nl_C_locobj and

diff --git a/include/locale.h b/include/locale.h
index 8091e1d..68425f9 100644
--- a/include/locale.h
+++ b/include/locale.h
@@ -13,8 +13,15 @@ libc_hidden_proto (__uselocale)
 extern struct loaded_l10nfile *_nl_locale_file_list[] attribute_hidden;
 /* Locale object for C locale.  */
-extern const struct __locale_struct _nl_C_locobj attribute_hidden;
-#define _nl_C_locobj_ptr ((struct __locale_struct *) &_nl_C_locobj)
+struct __locale_struct *__libc_C_locobj (void)
+     __attribute__ ((const)) internal_function;
+# if IS_IN (libc) || defined SHARED
+extern const struct __locale_struct _nl_C_locobj;
+libc_hidden_proto (_nl_C_locobj)
+#  define _nl_C_locobj_ptr ((struct __locale_struct *) &_nl_C_locobj)
+# else
+#  define _nl_C_locobj_ptr __libc_C_locobj ()
+# endif
 /* Now define the internal interfaces.  */
 extern struct lconv *__localeconv (void);
diff --git a/locale/C_locobj.c b/locale/C_locobj.c
new file mode 100644
index 0000000..ae80abf
--- /dev/null
+++ b/locale/C_locobj.c
@@ -0,0 +1,26 @@
+/* Access to the C locale object outside of libc.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   Lesser General Public License for more details.
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <>.  */
+#include <locale.h>
+__attribute__ ((const)) internal_function
+struct __locale_struct *
+__libc_C_locobj (void)
+  return _nl_C_locobj_ptr;
diff --git a/locale/Makefile b/locale/Makefile
index c5379e6..784a2c6 100644
--- a/locale/Makefile
+++ b/locale/Makefile
@@ -25,7 +25,8 @@ include ../Makeconfig
 headers		= locale.h bits/locale.h langinfo.h xlocale.h
 routines	= setlocale findlocale loadlocale loadarchive \
 		  localeconv nl_langinfo nl_langinfo_l mb_cur_max \
-		  newlocale duplocale freelocale uselocale
+		  newlocale duplocale freelocale uselocale C_locobj
+shared-only-routines = C_locobj
 tests		= tst-C-locale tst-locname tst-duplocale
 categories	= ctype messages monetary numeric time paper name \
 		  address telephone measurement identification collate
diff --git a/locale/Versions b/locale/Versions
index 7211934..d2a3d37 100644
--- a/locale/Versions
+++ b/locale/Versions
@@ -70,5 +70,8 @@ libc {
     # global variables
     __collate_element_hash; __collate_element_strings;
     __collate_symbol_classes; __collate_symbol_hash; __collate_symbol_strings;
+    # Access to the C locale objects for other parts of glibc.
+    _nl_C_locobj; __libc_C_locobj;
diff --git a/locale/xlocale.c b/locale/xlocale.c
index 18faaf1..10f760a 100644
--- a/locale/xlocale.c
+++ b/locale/xlocale.c
@@ -31,7 +31,7 @@ extern const char _nl_C_LC_CTYPE_toupper[] attribute_hidden;
 extern const char _nl_C_LC_CTYPE_tolower[] attribute_hidden;
-const struct __locale_struct _nl_C_locobj attribute_hidden =
+const struct __locale_struct _nl_C_locobj =
     .__locales =
@@ -52,3 +52,5 @@ const struct __locale_struct _nl_C_locobj attribute_hidden =
     .__ctype_tolower = (const int *) _nl_C_LC_CTYPE_tolower + 128,
     .__ctype_toupper = (const int *) _nl_C_LC_CTYPE_toupper + 128
+libc_hidden_data_def (_nl_C_locobj)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]