summary refs log tree commit diff
path: root/locale
diff options
context:
space:
mode:
Diffstat (limited to 'locale')
-rw-r--r--locale/duplocale.c26
-rw-r--r--locale/freelocale.c11
-rw-r--r--locale/global-locale.c8
-rw-r--r--locale/localeinfo.h4
-rw-r--r--locale/localename.c15
-rw-r--r--locale/setlocale.c24
-rw-r--r--locale/xlocale.c8
-rw-r--r--locale/xlocale.h3
8 files changed, 64 insertions, 35 deletions
diff --git a/locale/duplocale.c b/locale/duplocale.c
index f8e8e7299e..df856a2a83 100644
--- a/locale/duplocale.c
+++ b/locale/duplocale.c
@@ -33,15 +33,39 @@ __locale_t
 __duplocale (__locale_t dataset)
 {
   __locale_t result;
+  int cnt;
 
   /* We modify global data.  */
   __libc_lock_lock (__libc_setlocale_lock);
 
   /* Get memory.  */
   result = (__locale_t) malloc (sizeof (struct __locale_struct));
+
+  if (result != NULL)
+    /* Duplicate the names in a separate loop first so we can
+       bail out if strdup fails and not have touched usage_counts.  */
+    for (cnt = 0; cnt < __LC_LAST; ++cnt)
+      if (cnt != LC_ALL)
+	{
+	  if (dataset->__names[cnt] == _nl_C_name)
+	    result->__names[cnt] = _nl_C_name;
+	  else
+	    {
+	      result->__names[cnt] = __strdup (dataset->__names[cnt]);
+	      if (result->__names[cnt] == NULL)
+		{
+		  while (cnt-- > 0)
+		    if (dataset->__names[cnt] != _nl_C_name)
+		      free ((char *) dataset->__names[cnt]);
+		  free (result);
+		  result = NULL;
+		  break;
+		}
+	    }
+	}
+
   if (result != NULL)
     {
-      int cnt;
       for (cnt = 0; cnt < __LC_LAST; ++cnt)
 	if (cnt != LC_ALL)
 	  {
diff --git a/locale/freelocale.c b/locale/freelocale.c
index de7e554c84..2ba1432a27 100644
--- a/locale/freelocale.c
+++ b/locale/freelocale.c
@@ -38,9 +38,14 @@ __freelocale (__locale_t dataset)
   __libc_lock_lock (__libc_setlocale_lock);
 
   for (cnt = 0; cnt < __LC_LAST; ++cnt)
-    if (cnt != LC_ALL && dataset->__locales[cnt]->usage_count != UNDELETABLE)
-      /* We can remove the data.  */
-      _nl_remove_locale (cnt, dataset->__locales[cnt]);
+    if (cnt != LC_ALL)
+      {
+	if (dataset->__locales[cnt]->usage_count != UNDELETABLE)
+	  /* We can remove the data.  */
+	  _nl_remove_locale (cnt, dataset->__locales[cnt]);
+	if (dataset->__names[cnt] != _nl_C_name)
+	  free ((char *) dataset->__names[cnt]);
+      }
 
   /* Free the locale_t handle itself.  */
   free (dataset);
diff --git a/locale/global-locale.c b/locale/global-locale.c
index bec7498dae..a5cae3c5d1 100644
--- a/locale/global-locale.c
+++ b/locale/global-locale.c
@@ -46,6 +46,14 @@ struct __locale_struct _nl_global_locale attribute_hidden =
 #include "categories.def"
 #undef	DEFINE_CATEGORY
     },
+    .__names =
+    {
+      [LC_ALL] = _nl_C_name,
+#define DEFINE_CATEGORY(category, category_name, items, a) \
+      [category] = _nl_C_name,
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+    },
     .__ctype_b = (const unsigned short int *) _nl_C_LC_CTYPE_class + 128,
     .__ctype_tolower = (const int *) _nl_C_LC_CTYPE_tolower + 128,
     .__ctype_toupper = (const int *) _nl_C_LC_CTYPE_toupper + 128
diff --git a/locale/localeinfo.h b/locale/localeinfo.h
index 186aa712c4..c235fb8740 100644
--- a/locale/localeinfo.h
+++ b/locale/localeinfo.h
@@ -177,10 +177,6 @@ extern const char _nl_POSIX_name[] attribute_hidden;
 /* The standard codeset.  */
 extern const char _nl_C_codeset[] attribute_hidden;
 
-/* Name of current locale for each individual category.
-   Each is malloc'd unless it is _nl_C_name.  */
-extern const char *_nl_current_names[] attribute_hidden;
-
 /* This is the internal locale_t object that holds the global locale
    controlled by calls to setlocale.  A thread's TSD locale pointer
    points to this when `uselocale (LC_GLOBAL_LOCALE)' is in effect.  */
diff --git a/locale/localename.c b/locale/localename.c
index 377ec296a6..845cfb0e71 100644
--- a/locale/localename.c
+++ b/locale/localename.c
@@ -19,22 +19,9 @@
 
 #include "localeinfo.h"
 
-/* Name of current locale for each individual category.
-   Each is malloc'd unless it is _nl_C_name.  */
-const char *_nl_current_names[] attribute_hidden =
-  {
-#define DEFINE_CATEGORY(category, category_name, items, a) \
-    [category] = _nl_C_name,
-#include "categories.def"
-#undef	DEFINE_CATEGORY
-    [LC_ALL] = _nl_C_name		/* For LC_ALL.  */
-  };
-
 const char *
 attribute_hidden
 __current_locale_name (int category)
 {
-  return (_NL_CURRENT_LOCALE == &_nl_global_locale
-	  ? _nl_current_names[category]
-	  : _NL_CURRENT_LOCALE->__locales[category]->name);
+  return _NL_CURRENT_LOCALE->__names[category];
 }
diff --git a/locale/setlocale.c b/locale/setlocale.c
index c64db08f05..a48f171c92 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -136,7 +136,7 @@ new_composite_name (int category, const char *newnames[__LC_LAST])
       {
 	const char *name = (category == LC_ALL ? newnames[i] :
 			    category == i ? newnames[0] :
-			    _nl_current_names[i]);
+			    _nl_global_locale.__names[i]);
 	last_len = strlen (name);
 	cumlen += _nl_category_name_sizes[i] + 1 + last_len + 1;
 	if (i > 0 && same && strcmp (name, newnames[0]) != 0)
@@ -165,7 +165,7 @@ new_composite_name (int category, const char *newnames[__LC_LAST])
 	/* Add "CATEGORY=NAME;" to the string.  */
 	const char *name = (category == LC_ALL ? newnames[i] :
 			    category == i ? newnames[0] :
-			    _nl_current_names[i]);
+			    _nl_global_locale.__names[i]);
 	p = __stpcpy (p, _nl_category_names[i]);
 	*p++ = '=';
 	p = __stpcpy (p, name);
@@ -176,17 +176,17 @@ new_composite_name (int category, const char *newnames[__LC_LAST])
 }
 
 
-/* Put NAME in _nl_current_names.  */
+/* Put NAME in _nl_global_locale.__names.  */
 static inline void
 setname (int category, const char *name)
 {
-  if (_nl_current_names[category] == name)
+  if (_nl_global_locale.__names[category] == name)
     return;
 
-  if (_nl_current_names[category] != _nl_C_name)
-    free ((char *) _nl_current_names[category]);
+  if (_nl_global_locale.__names[category] != _nl_C_name)
+    free ((char *) _nl_global_locale.__names[category]);
 
-  _nl_current_names[category] = name;
+  _nl_global_locale.__names[category] = name;
 }
 
 /* Put DATA in *_nl_current[CATEGORY].  */
@@ -216,11 +216,11 @@ setlocale (int category, const char *locale)
 
   /* Does user want name of current locale?  */
   if (locale == NULL)
-    return (char *) _nl_current_names[category];
+    return (char *) _nl_global_locale.__names[category];
 
-  if (strcmp (locale, _nl_current_names[category]) == 0)
+  if (strcmp (locale, _nl_global_locale.__names[category]) == 0)
     /* Changing to the same thing.  */
-    return (char *) _nl_current_names[category];
+    return (char *) _nl_global_locale.__names[category];
 
   /* We perhaps really have to load some data.  So we determine the
      path in which to look for the data now.  The environment variable
@@ -324,7 +324,7 @@ setlocale (int category, const char *locale)
 	    /* Make a copy of locale name.  */
 	    if (newnames[category] != _nl_C_name)
 	      {
-		newnames[category] = strdup (newnames[category]);
+		newnames[category] = __strdup (newnames[category]);
 		if (newnames[category] == NULL)
 		  break;
 	      }
@@ -389,7 +389,7 @@ setlocale (int category, const char *locale)
       /* Make a copy of locale name.  */
       if (newname[0] != _nl_C_name)
 	{
-	  newname[0] = strdup (newname[0]);
+	  newname[0] = __strdup (newname[0]);
 	  if (newname[0] == NULL)
 	    goto abort_single;
 	}
diff --git a/locale/xlocale.c b/locale/xlocale.c
index 2f9e198aef..d9d3442621 100644
--- a/locale/xlocale.c
+++ b/locale/xlocale.c
@@ -41,6 +41,14 @@ struct __locale_struct _nl_C_locobj attribute_hidden =
 #include "categories.def"
 #undef	DEFINE_CATEGORY
     },
+    .__names =
+    {
+      [LC_ALL] = _nl_C_name,
+#define DEFINE_CATEGORY(category, category_name, items, a) \
+      [category] = _nl_C_name,
+#include "categories.def"
+#undef	DEFINE_CATEGORY
+    },
     .__ctype_b = (const unsigned short int *) _nl_C_LC_CTYPE_class + 128,
     .__ctype_tolower = (const int *) _nl_C_LC_CTYPE_tolower + 128,
     .__ctype_toupper = (const int *) _nl_C_LC_CTYPE_toupper + 128
diff --git a/locale/xlocale.h b/locale/xlocale.h
index fa65e10a01..4fb557d3bf 100644
--- a/locale/xlocale.h
+++ b/locale/xlocale.h
@@ -1,5 +1,5 @@
 /* Definition of locale datatype.
-   Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997,2000,02 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -29,6 +29,7 @@ typedef struct __locale_struct
 {
   /* Note: LC_ALL is not a valid index into this array.  */
   struct locale_data *__locales[13]; /* 13 = __LC_LAST. */
+  const char *__names[13];
 
   /* To increase the speed of this solution we add some special members.  */
   const unsigned short int *__ctype_b;