X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Flocale%2Fsetlocale.c;h=360c4437644b88f86ac8b9f0db5d92915019c8d7;hb=d055e6a45a17673b8dd3ec16e786bb2fe1700dd5;hp=28f29b80414618ff81f15e18789e869c03f3f1cf;hpb=0b44a0315b47dd8eced9f3b7f31580cf14bbfc01;p=musl diff --git a/src/locale/setlocale.c b/src/locale/setlocale.c index 28f29b80..360c4437 100644 --- a/src/locale/setlocale.c +++ b/src/locale/setlocale.c @@ -1,9 +1,78 @@ #include +#include +#include +#include "locale_impl.h" +#include "libc.h" +#include "lock.h" -char *setlocale(int category, const char *locale) +static char buf[LC_ALL*(LOCALE_NAME_MAX+1)]; + +char *setlocale(int cat, const char *name) { - /* Note: plain "C" would be better, but puts some broken - * software into legacy 8-bit-codepage mode, ignoring - * the standard library's multibyte encoding */ - return "C.UTF-8"; + const struct __locale_map *lm; + + if ((unsigned)cat > LC_ALL) return 0; + + LOCK(__locale_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) { + struct __locale_struct tmp_locale; + char part[LOCALE_NAME_MAX+1] = "C.UTF-8"; + const char *p = name; + for (i=0; iname : "C"; + size_t l = strlen(part); + memcpy(s, part, l); + s[l] = ';'; + s += l+1; + } + *--s = 0; + UNLOCK(__locale_lock); + return same==LC_ALL ? (char *)part : buf; + } + + if (name) { + lm = __get_locale(cat, name); + if (lm == LOC_MAP_FAILED) { + UNLOCK(__locale_lock); + return 0; + } + libc.global_locale.cat[cat] = lm; + } else { + lm = libc.global_locale.cat[cat]; + } + char *ret = lm ? (char *)lm->name : "C"; + + UNLOCK(__locale_lock); + + return ret; }