aboutsummaryrefslogtreecommitdiff
path: root/locale
diff options
context:
space:
mode:
Diffstat (limited to 'locale')
-rw-r--r--locale/loadarchive.c41
-rw-r--r--locale/localeinfo.h3
-rw-r--r--locale/setlocale.c11
3 files changed, 51 insertions, 4 deletions
diff --git a/locale/loadarchive.c b/locale/loadarchive.c
index 08e5f94..a9b5386 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 31de4d0..bcb5805 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 46af339..3c80379 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);