Print this page
locale stuff should use libc safe lmalloc. Other fixes from tests.
*** 156,170 ****
struct locdata *
__locdata_alloc(const char *name, size_t memsz)
{
struct locdata *ldata;
! if ((ldata = calloc(1, sizeof (*ldata))) == NULL) {
return (NULL);
}
! if ((ldata->l_data[0] = calloc(1, memsz)) == NULL) {
! free(ldata);
errno = ENOMEM;
return (NULL);
}
(void) strlcpy(ldata->l_lname, name, sizeof (ldata->l_lname));
--- 156,170 ----
struct locdata *
__locdata_alloc(const char *name, size_t memsz)
{
struct locdata *ldata;
! if ((ldata = lmalloc(sizeof (*ldata))) == NULL) {
return (NULL);
}
! if ((ldata->l_data[0] = libc_malloc(memsz)) == NULL) {
! lfree(ldata, sizeof (*ldata));
errno = ENOMEM;
return (NULL);
}
(void) strlcpy(ldata->l_lname, name, sizeof (ldata->l_lname));
*** 177,190 ****
*/
void
__locdata_free(struct locdata *ldata)
{
for (int i = 0; i < NLOCDATA; i++)
! free(ldata->l_data[i]);
if (ldata->l_map != NULL && ldata->l_map_len)
(void) munmap(ldata->l_map, ldata->l_map_len);
! free(ldata);
}
/*
* It turns out that for performance reasons we would really like to
* cache the most recently referenced locale data to avoid wasteful
--- 177,190 ----
*/
void
__locdata_free(struct locdata *ldata)
{
for (int i = 0; i < NLOCDATA; i++)
! libc_free(ldata->l_data[i]);
if (ldata->l_map != NULL && ldata->l_map_len)
(void) munmap(ldata->l_map, ldata->l_map_len);
! lfree(ldata, sizeof (*ldata));
}
/*
* It turns out that for performance reasons we would really like to
* cache the most recently referenced locale data to avoid wasteful
*** 248,268 ****
*/
if (loc == NULL) {
lmutex_unlock(&cache_lock);
loc = (*loaders[category])(locname);
lmutex_lock(&cache_lock);
! (void) strlcpy(loc->l_lname, locname, sizeof (loc->l_lname));
}
/*
* Assuming we got one, update the cache, and stick us on the list
* of loaded locale data. We insert into the head (more recent
* use is likely to win.)
*/
if (loc != NULL) {
cache_data[category] = loc;
! if (loc->l_next == NULL) {
loc->l_next = cat_data[category];
cat_data[category] = loc;
}
}
--- 248,271 ----
*/
if (loc == NULL) {
lmutex_unlock(&cache_lock);
loc = (*loaders[category])(locname);
lmutex_lock(&cache_lock);
! if (loc != NULL)
! (void) strlcpy(loc->l_lname, locname,
! sizeof (loc->l_lname));
}
/*
* Assuming we got one, update the cache, and stick us on the list
* of loaded locale data. We insert into the head (more recent
* use is likely to win.)
*/
if (loc != NULL) {
cache_data[category] = loc;
! if (!loc->l_cached) {
! loc->l_cached = 1;
loc->l_next = cat_data[category];
cat_data[category] = loc;
}
}
*** 372,382 ****
duplocale(locale_t src)
{
locale_t loc;
int i;
! loc = calloc(1, sizeof (*loc));
if (loc == NULL) {
return (NULL);
}
if (src == NULL) {
/* illumos extension: POSIX says LC_GLOBAL_LOCALE here */
--- 375,385 ----
duplocale(locale_t src)
{
locale_t loc;
int i;
! loc = lmalloc(sizeof (*loc));
if (loc == NULL) {
return (NULL);
}
if (src == NULL) {
/* illumos extension: POSIX says LC_GLOBAL_LOCALE here */
*** 402,413 ****
/*
* We take extra care never to free a saved locale created by
* setlocale(). This shouldn't be strictly necessary, but a little
* extra safety doesn't hurt here.
*/
! if ((loc != &posix_locale) && (!loc->on_list))
! free(loc);
}
locale_t
newlocale(int catmask, const char *locname, locale_t base)
{
--- 405,416 ----
/*
* We take extra care never to free a saved locale created by
* setlocale(). This shouldn't be strictly necessary, but a little
* extra safety doesn't hurt here.
*/
! if ((loc != NULL) && (loc != &posix_locale) && (!loc->on_list))
! lfree(loc, sizeof (*loc));
}
locale_t
newlocale(int catmask, const char *locname, locale_t base)
{
*** 424,434 ****
* but we allow it.
*/
if (base == NULL || base == ___global_locale) {
loc = duplocale(___global_locale);
} else {
! loc = base;
}
if (loc == NULL) {
return (NULL);
}
--- 427,437 ----
* but we allow it.
*/
if (base == NULL || base == ___global_locale) {
loc = duplocale(___global_locale);
} else {
! loc = duplocale(base);
}
if (loc == NULL) {
return (NULL);
}
*** 453,462 ****
--- 456,467 ----
loc->runelocale = loc->locdata[LC_CTYPE]->l_data[1];
loc->messages = loc->locdata[LC_MESSAGES]->l_data[0];
loc->monetary = loc->locdata[LC_MONETARY]->l_data[0];
loc->numeric = loc->locdata[LC_NUMERIC]->l_data[0];
loc->time = loc->locdata[LC_TIME]->l_data[0];
+ freelocale(base);
+
return (mklocname(loc));
}
locale_t
uselocale(locale_t loc)