diff options
author | Thomas Munro <tmunro@postgresql.org> | 2024-08-13 22:27:16 +1200 |
---|---|---|
committer | Thomas Munro <tmunro@postgresql.org> | 2024-08-13 22:34:53 +1200 |
commit | 35eeea62302260ec07fd11b287e488768d4543e2 (patch) | |
tree | d87f1f8947caebead60df4a62fed4c0e0ced6630 /src | |
parent | 14c648ff009438830d15de7c8a93c2b29114eb1c (diff) | |
download | postgresql-35eeea62302260ec07fd11b287e488768d4543e2.tar.gz postgresql-35eeea62302260ec07fd11b287e488768d4543e2.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/port/chklocale.c | 67 |
1 files changed, 19 insertions, 48 deletions
diff --git a/src/port/chklocale.c b/src/port/chklocale.c index a0cc52c38df..14d0e2c5579 100644 --- a/src/port/chklocale.c +++ b/src/port/chklocale.c @@ -306,63 +306,34 @@ pg_get_encoding_from_locale(const char *ctype, bool write_message) char *sys; int i; - /* Get the CODESET property, and also LC_CTYPE if not passed in */ - 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); + locale_t loc; #endif - setlocale(LC_CTYPE, save); - free(save); - } - else - { - /* much easier... */ + /* Get the CODESET property, and also LC_CTYPE if not passed in */ + if (!ctype) 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 || - pg_strcasecmp(ctype, "POSIX") == 0) - return PG_SQL_ASCII; + + /* 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; + #ifndef WIN32 - sys = nl_langinfo(CODESET); - if (sys) - sys = strdup(sys); + loc = newlocale(LC_CTYPE_MASK, ctype, (locale_t) 0); + if (loc == (locale_t) 0) + return -1; /* bogus ctype passed in? */ + + sys = nl_langinfo_l(CODESET, loc); + if (sys) + sys = strdup(sys); + + freelocale(loc); #else - sys = win32_langinfo(ctype); + sys = win32_langinfo(ctype); #endif - } if (!sys) return -1; /* out of memory; unlikely */ |