about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--locale/loadarchive.c41
-rw-r--r--locale/localeinfo.h3
-rw-r--r--locale/setlocale.c11
4 files changed, 62 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index fc48660e9d..0b41d5cf37 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,10 @@
-2002-08-10  Ulrich Drepper  <drepper@redhat.com>
+2002-08-10  Roland McGrath  <roland@redhat.com>
 
-	* wctype/wcfuncs.c (iswalpha, iswdigit, iswlower, iswspace,
-	iswxdigit, iswtolower, iswtoupper): Add libc_hidden_def.
+	* locale/loadarchive.c (_nl_archive_subfreeres): New function.
+	* locale/localeinfo.h: Declare it.
+	* locale/setlocale.c (free_mem): Don't call _nl_unload_locale on the
+	current locale if it's not in the file list.
+	Call _nl_archive_subfreeres.
 
 2002-08-10  Andreas Jaeger  <aj@suse.de>
 
@@ -27,6 +30,11 @@
 
 2002-08-09  Jakub Jelinek  <jakub@redhat.com>
 
+	* include/wctype.h (iswalpha, iswdigit, iswlower, iswspace, iswxdigit,
+	towlower, towupper): Add prototypes here too.  Add libc_hidden_proto.
+	* wctype/wcfuncs.c (iswalpha, iswdigit, iswlower, iswspace, iswxdigit,
+	towlower, towupper): Add libc_hidden_weak.
+
 	* include/bits/dlfcn.h: New file.
 	* elf/dl-profstub.c (_dl_mcount_wrapper_check): Add libc_hidden_def.
 
@@ -42,11 +50,6 @@
 	* nss/nsswitch.h (__nss_hostname_digits_dots): Add libc_hidden_proto.
 	* nss/digits_dots.c (__nss_hostname_digits_dots): Add libc_hidden_def.
 
-	* include/wctype.h (iswalpha, iswdigit, iswlower, iswspace, iswxdigit,
-	towlower, towupper): Add prototypes here too.  Add libc_hidden_proto.
-	* wctype/wcfuncs ((iswalpha, iswdigit, iswlower, iswspace, iswxdigit,
-	towlower, towupper): Add libc_hidden_weak.
-
 	* libio/oldiopopen.c: Move #if SHLIB_COMPAT after _IO_HAVE_SYS_WAIT
 	#endif.
 
diff --git a/locale/loadarchive.c b/locale/loadarchive.c
index 08e5f94905..a9b5386ce8 100644
--- a/locale/loadarchive.c
+++ b/locale/loadarchive.c
@@ -445,3 +445,44 @@ _nl_load_locale_from_archive (int category, const char **namep)
   *namep = lia->name;
   return lia->data[category];
 }
+
+void
+_nl_archive_subfreeres (void)
+{
+  struct locale_in_archive *lia;
+  struct archmapped *am;
+
+  /* Toss out our cached locales.  */
+  lia = archloaded;
+  while (lia != NULL)
+    {
+      int category;
+      struct locale_in_archive *dead = lia;
+      lia = lia->next;
+
+      for (category = 0; category < __LC_LAST; ++category)
+	if (category != LC_ALL)
+	  /* _nl_unload_locale just does this free for the archive case.  */
+	  free (dead->data[category]);
+      free (dead);
+    }
+  archloaded = NULL;
+
+  if (archmapped != NULL)
+    {
+      /* Now toss all the mapping windows, which we know nothing is using any
+	 more because we just tossed all the locales that point into them.  */
+
+      assert (archmapped == &headmap);
+      archmapped = NULL;
+      (void) munmap (headmap.ptr, headmap.len);
+      am = headmap.next;
+      while (am != NULL)
+	{
+	  struct archmapped *dead = am;
+	  am = am->next;
+	  (void) munmap (dead->ptr, dead->len);
+	  free (dead);
+	}
+    }
+}
diff --git a/locale/localeinfo.h b/locale/localeinfo.h
index 31de4d0974..bcb5805854 100644
--- a/locale/localeinfo.h
+++ b/locale/localeinfo.h
@@ -261,6 +261,9 @@ extern struct locale_data *_nl_load_locale_from_archive (int category,
 							 const char **namep)
      internal_function attribute_hidden;
 
+/* Subroutine of setlocale's __libc_subfreeres hook.  */
+extern void _nl_archive_subfrees (void) attribute_hidden;
+
 /* Validate the contents of a locale file and set up the in-core
    data structure to point into the data.  This leaves the `alloc'
    and `name' fields uninitialized, for the caller to fill in.
diff --git a/locale/setlocale.c b/locale/setlocale.c
index 46af339eae..3c80379cf9 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -458,12 +458,10 @@ free_mem (void)
 	/* If this category is already "C" don't do anything.  */
 	if (here != _nl_C[category])
 	  {
-	    /* We have to be prepared that sometime later me still
+	    /* We have to be prepared that sometime later we still
 	       might need the locale information.  */
 	    setdata (category, _nl_C[category]);
 	    setname (category, _nl_C_name);
-
-	    _nl_unload_locale (here);
 	  }
 
 	while (runp != NULL)
@@ -471,7 +469,7 @@ free_mem (void)
 	    struct loaded_l10nfile *curr = runp;
 	    struct locale_data *data = (struct locale_data *) runp->data;
 
-	    if (data != NULL && data != here && data != _nl_C[category])
+	    if (data != NULL && data != _nl_C[category])
 	      _nl_unload_locale (data);
 	    runp = runp->next;
 	    free ((char *) curr->filename);
@@ -480,5 +478,10 @@ free_mem (void)
       }
 
   setname (LC_ALL, _nl_C_name);
+
+  /* This frees the data structures associated with the locale archive.
+     The locales from the archive are not in the file list, so we have
+     not called _nl_unload_locale on them above.  */
+  _nl_archive_subfreeres ();
 }
 text_set_element (__libc_subfreeres, free_mem);