char * setlocale(int category, const char *locale) { int i, loadlocale_success; size_t len; const char *env, *r; __mb_len_max_runtime = 32; if (issetugid() || (!_PathLocale && !(_PathLocale = getenv("PATH_LOCALE")))) _PathLocale = _PATH_LOCALE; if (category < 0 || category >= (int)__arysize(categories)) return(NULL); if (locale == NULL) return(category ? current_categories[category] : currentlocale()); /* * Default to the current locale for everything. */ for (i = 1; i < _LC_LAST; ++i) strlcpy(new_categories[i], current_categories[i], sizeof(new_categories[i])); /* * Now go fill up new_categories from the locale argument */ if (*locale == '\0') { if (category == LC_ALL) { for (i = 1; i < _LC_LAST; ++i) { env = __get_locale_env(i); strlcpy(new_categories[i], env, sizeof(new_categories[i])); } } else { env = __get_locale_env(category); strlcpy(new_categories[category], env, sizeof(new_categories[category])); } } else if (category) { strlcpy(new_categories[category], locale, sizeof(new_categories[category])); } else { if ((r = strchr(locale, '/')) == 0) { for (i = 1; i < _LC_LAST; ++i) { strlcpy(new_categories[i], locale, sizeof(new_categories[i])); } } else { for (i = 1;;) { _DIAGASSERT(*r == '/' || *r == 0); _DIAGASSERT(*locale != 0); if (*locale == '/') return(NULL); /* invalid format. */ len = r - locale; if (len + 1 > sizeof(new_categories[i])) return(NULL); /* too long */ memcpy(new_categories[i], locale, len); new_categories[i][len] = '\0'; if (*r == 0) break; _DIAGASSERT(*r == '/'); if (*(locale = ++r) == 0) /* slash followed by NUL */ return(NULL); /* skip until NUL or '/' */ while (*r && *r != '/') r++; if (++i == _LC_LAST) return(NULL); /* too many slashes. */ } if (i + 1 != _LC_LAST) return(NULL); /* too few slashes. */ } } if (category) return(loadlocale(category)); loadlocale_success = 0; for (i = 1; i < _LC_LAST; ++i) { if (loadlocale(i) != NULL) loadlocale_success = 1; } /* * If all categories failed, return NULL; we don't need to back * changes off, since none happened. */ if (!loadlocale_success) return(NULL); return(currentlocale()); }
char * setlocale(int category, const char *locale) { int i, loadlocale_success; size_t len; const char *env, *r; if (category < 0 || category >= _LC_LAST) return (NULL); if (!locale) return (category ? current_categories[category] : currentlocale()); /* * Default to the current locale for everything. */ for (i = 1; i < _LC_LAST; ++i) (void)strlcpy(new_categories[i], current_categories[i], sizeof(new_categories[i])); /* * Now go fill up new_categories from the locale argument */ if (!*locale) { if (category == LC_ALL) { for (i = 1; i < _LC_LAST; ++i) { env = __get_locale_env(i); (void)strlcpy(new_categories[i], env, sizeof(new_categories[i])); } } else { env = __get_locale_env(category); (void)strlcpy(new_categories[category], env, sizeof(new_categories[category])); } } else if (category) { (void)strlcpy(new_categories[category], locale, sizeof(new_categories[category])); } else { if ((r = strchr(locale, '/')) == 0) { for (i = 1; i < _LC_LAST; ++i) { (void)strlcpy(new_categories[i], locale, sizeof(new_categories[i])); } } else { for (i = 1;;) { if (*locale == '/') return (NULL); /* invalid format. */ len = r - locale; if (len + 1 > sizeof(new_categories[i])) return (NULL); /* too long */ (void)memcpy(new_categories[i], locale, len); new_categories[i][len] = '\0'; if (*r == 0) break; if (*(locale = ++r) == 0) /* slash followed by NUL */ return (NULL); /* skip until NUL or '/' */ while (*r && *r != '/') r++; if (++i == _LC_LAST) return (NULL); /* too many slashes. */ } if (i + 1 != _LC_LAST) return (NULL); /* too few slashes. */ } } if (category) return (loadlocale(category)); loadlocale_success = 0; for (i = 1; i < _LC_LAST; ++i) { if (loadlocale(i) != NULL) loadlocale_success = 1; } /* * If all categories failed, return NULL; we don't need to back * changes off, since none happened. */ if (!loadlocale_success) return NULL; return (currentlocale()); }
char * _setlocale_r (struct _reent *p, int category, const char *locale) { #ifndef _MB_CAPABLE if (locale) { if (strcmp (locale, "POSIX") && strcmp (locale, "C") && strcmp (locale, "")) return NULL; } return "C"; #else /* _MB_CAPABLE */ static char new_categories[_LC_LAST][ENCODING_LEN + 1]; static char saved_categories[_LC_LAST][ENCODING_LEN + 1]; int i, j, len, saverr; const char *env, *r; if (category < LC_ALL || category >= _LC_LAST) { p->_errno = EINVAL; return NULL; } if (locale == NULL) return category != LC_ALL ? __get_global_locale ()->categories[category] : currentlocale(); /* * Default to the current locale for everything. */ for (i = 1; i < _LC_LAST; ++i) strcpy (new_categories[i], __get_global_locale ()->categories[i]); /* * Now go fill up new_categories from the locale argument */ if (!*locale) { if (category == LC_ALL) { for (i = 1; i < _LC_LAST; ++i) { env = __get_locale_env (p, i); if (strlen (env) > ENCODING_LEN) { p->_errno = EINVAL; return NULL; } strcpy (new_categories[i], env); } } else { env = __get_locale_env (p, category); if (strlen (env) > ENCODING_LEN) { p->_errno = EINVAL; return NULL; } strcpy (new_categories[category], env); } } else if (category != LC_ALL) { if (strlen (locale) > ENCODING_LEN) { p->_errno = EINVAL; return NULL; } strcpy (new_categories[category], locale); } else { if ((r = strchr (locale, '/')) == NULL) { if (strlen (locale) > ENCODING_LEN) { p->_errno = EINVAL; return NULL; } for (i = 1; i < _LC_LAST; ++i) strcpy (new_categories[i], locale); } else { for (i = 1; r[1] == '/'; ++r) ; if (!r[1]) { p->_errno = EINVAL; return NULL; /* Hmm, just slashes... */ } do { if (i == _LC_LAST) break; /* Too many slashes... */ if ((len = r - locale) > ENCODING_LEN) { p->_errno = EINVAL; return NULL; } strlcpy (new_categories[i], locale, len + 1); i++; while (*r == '/') r++; locale = r; while (*r && *r != '/') r++; } while (*locale); while (i < _LC_LAST) { strcpy (new_categories[i], new_categories[i-1]); i++; } } } if (category != LC_ALL) return __loadlocale (__get_global_locale (), category, new_categories[category]); for (i = 1; i < _LC_LAST; ++i) { strcpy (saved_categories[i], __get_global_locale ()->categories[i]); if (__loadlocale (__get_global_locale (), i, new_categories[i]) == NULL) { saverr = p->_errno; for (j = 1; j < i; j++) { strcpy (new_categories[j], saved_categories[j]); if (__loadlocale (__get_global_locale (), j, new_categories[j]) == NULL) { strcpy (new_categories[j], "C"); __loadlocale (__get_global_locale (), j, new_categories[j]); } } p->_errno = saverr; return NULL; } } return currentlocale (); #endif /* _MB_CAPABLE */ }