mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
Use thread-safe nl_langinfo_l(), not nl_langinfo().
This gets rid of some setlocale() calls. The remaining call to setlocale() in pg_get_encoding_from_locale() is a query of the name of the current locale when none was provided (in a multi-threaded future that would need more work). All known non-Windows targets have nl_langinfo_l(), from POSIX 2008, and for Windows we already do something thread-safe. Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Discussion: https://postgr.es/m/CA%2BhUKGJqVe0%2BPv9dvC9dSums_PXxGo9SWcxYAMBguWJUGbWz-A%40mail.gmail.com
This commit is contained in:
parent
14c648ff00
commit
35eeea6230
@ -306,63 +306,34 @@ pg_get_encoding_from_locale(const char *ctype, bool write_message)
|
|||||||
char *sys;
|
char *sys;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
locale_t loc;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get the CODESET property, and also LC_CTYPE if not passed in */
|
/* Get the CODESET property, and also LC_CTYPE if not passed in */
|
||||||
if (ctype)
|
if (!ctype)
|
||||||
{
|
|
||||||
char *save;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
/* If locale is C or POSIX, we can allow all encodings */
|
|
||||||
if (pg_strcasecmp(ctype, "C") == 0 ||
|
|
||||||
pg_strcasecmp(ctype, "POSIX") == 0)
|
|
||||||
return PG_SQL_ASCII;
|
|
||||||
|
|
||||||
save = setlocale(LC_CTYPE, NULL);
|
|
||||||
if (!save)
|
|
||||||
return -1; /* setlocale() broken? */
|
|
||||||
/* must copy result, or it might change after setlocale */
|
|
||||||
save = strdup(save);
|
|
||||||
if (!save)
|
|
||||||
return -1; /* out of memory; unlikely */
|
|
||||||
|
|
||||||
name = setlocale(LC_CTYPE, ctype);
|
|
||||||
if (!name)
|
|
||||||
{
|
|
||||||
free(save);
|
|
||||||
return -1; /* bogus ctype passed in? */
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
sys = nl_langinfo(CODESET);
|
|
||||||
if (sys)
|
|
||||||
sys = strdup(sys);
|
|
||||||
#else
|
|
||||||
sys = win32_langinfo(name);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
setlocale(LC_CTYPE, save);
|
|
||||||
free(save);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* much easier... */
|
|
||||||
ctype = setlocale(LC_CTYPE, NULL);
|
ctype = setlocale(LC_CTYPE, NULL);
|
||||||
if (!ctype)
|
|
||||||
return -1; /* setlocale() broken? */
|
|
||||||
|
|
||||||
/* If locale is C or POSIX, we can allow all encodings */
|
|
||||||
if (pg_strcasecmp(ctype, "C") == 0 ||
|
/* If locale is C or POSIX, we can allow all encodings */
|
||||||
pg_strcasecmp(ctype, "POSIX") == 0)
|
if (pg_strcasecmp(ctype, "C") == 0 ||
|
||||||
return PG_SQL_ASCII;
|
pg_strcasecmp(ctype, "POSIX") == 0)
|
||||||
|
return PG_SQL_ASCII;
|
||||||
|
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
sys = nl_langinfo(CODESET);
|
loc = newlocale(LC_CTYPE_MASK, ctype, (locale_t) 0);
|
||||||
if (sys)
|
if (loc == (locale_t) 0)
|
||||||
sys = strdup(sys);
|
return -1; /* bogus ctype passed in? */
|
||||||
|
|
||||||
|
sys = nl_langinfo_l(CODESET, loc);
|
||||||
|
if (sys)
|
||||||
|
sys = strdup(sys);
|
||||||
|
|
||||||
|
freelocale(loc);
|
||||||
#else
|
#else
|
||||||
sys = win32_langinfo(ctype);
|
sys = win32_langinfo(ctype);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
if (!sys)
|
if (!sys)
|
||||||
return -1; /* out of memory; unlikely */
|
return -1; /* out of memory; unlikely */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user