aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2024-08-13 22:27:16 +1200
committerThomas Munro <tmunro@postgresql.org>2024-08-13 22:34:53 +1200
commit35eeea62302260ec07fd11b287e488768d4543e2 (patch)
treed87f1f8947caebead60df4a62fed4c0e0ced6630 /src
parent14c648ff009438830d15de7c8a93c2b29114eb1c (diff)
downloadpostgresql-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.c67
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 */