X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Flocale%2Fsetlocale.c;h=60e3353c9a7ac962cf5c94fa9fcb2d59251829eb;hb=7e399fabd3db2c528b5982803eeba2841f547695;hp=cbc0b5517f04dcd6ce20e721a3d0bc13ba7c9293;hpb=0bc03091bb674ebb9fa6fe69e4aec1da3ac484f2;p=oweals%2Fmusl.git diff --git a/src/locale/setlocale.c b/src/locale/setlocale.c index cbc0b551..60e3353c 100644 --- a/src/locale/setlocale.c +++ b/src/locale/setlocale.c @@ -5,63 +5,67 @@ #include "libc.h" #include "atomic.h" -static char buf[2+4*(LOCALE_NAME_MAX+1)]; +static char buf[LC_ALL*(LOCALE_NAME_MAX+1)]; + +static char *setlocale_one_unlocked(int cat, const char *name) +{ + const struct __locale_map *lm; + + if (name) libc.global_locale.cat[cat] = lm = __get_locale(cat, name); + else lm = libc.global_locale.cat[cat]; + + return lm ? (char *)lm->name : "C"; +} char *setlocale(int cat, const char *name) { - if (!libc.global_locale.messages_name) { - libc.global_locale.messages_name = - buf + 2 + 3*(LOCALE_NAME_MAX+1); - } + static volatile int lock[1]; if ((unsigned)cat > LC_ALL) return 0; + LOCK(lock); + /* For LC_ALL, setlocale is required to return a string which * encodes the current setting for all categories. The format of * this string is unspecified, and only the following code, which * performs both the serialization and deserialization, depends * on the format, so it can easily be changed if needed. */ if (cat == LC_ALL) { + int i; if (name) { - char part[LOCALE_NAME_MAX+1]; - int i, j; - if (name[0] && name[1]==';' - && strlen(name) > 2 + 3*(LOCALE_NAME_MAX+1)) { - part[0] = name[0]; - part[1] = 0; - setlocale(LC_CTYPE, part); - part[LOCALE_NAME_MAX] = 0; - for (i=LC_TIME; iname : "C"; + size_t l = strlen(part); + memcpy(s, part, l); + s[l] = ';'; + s += l+1; + } + *--s = 0; + UNLOCK(lock); + return same==LC_ALL ? (char *)part : buf; } - if (name) { - int adj = libc.global_locale.ctype_utf8; - __setlocalecat(&libc.global_locale, cat, name); - adj -= libc.global_locale.ctype_utf8; - if (adj) a_fetch_add(&libc.bytelocale_cnt_minus_1, adj); - } + char *ret = setlocale_one_unlocked(cat, name); - switch (cat) { - case LC_CTYPE: - return libc.global_locale.ctype_utf8 ? "C.UTF-8" : "C"; - case LC_MESSAGES: - return libc.global_locale.messages_name[0] - ? libc.global_locale.messages_name : "C"; - default: - return "C"; - } + UNLOCK(lock); + + return ret; }