Skip to content

Commit 35eeea6

Browse files
committed
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
1 parent 14c648f commit 35eeea6

File tree

1 file changed

+19
-48
lines changed

1 file changed

+19
-48
lines changed

src/port/chklocale.c

Lines changed: 19 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -306,63 +306,34 @@ pg_get_encoding_from_locale(const char *ctype, bool write_message)
306306
char *sys;
307307
int i;
308308

309-
/* Get the CODESET property, and also LC_CTYPE if not passed in */
310-
if (ctype)
311-
{
312-
char *save;
313-
char *name;
314-
315-
/* If locale is C or POSIX, we can allow all encodings */
316-
if (pg_strcasecmp(ctype, "C") == 0 ||
317-
pg_strcasecmp(ctype, "POSIX") == 0)
318-
return PG_SQL_ASCII;
319-
320-
save = setlocale(LC_CTYPE, NULL);
321-
if (!save)
322-
return -1; /* setlocale() broken? */
323-
/* must copy result, or it might change after setlocale */
324-
save = strdup(save);
325-
if (!save)
326-
return -1; /* out of memory; unlikely */
327-
328-
name = setlocale(LC_CTYPE, ctype);
329-
if (!name)
330-
{
331-
free(save);
332-
return -1; /* bogus ctype passed in? */
333-
}
334-
335309
#ifndef WIN32
336-
sys = nl_langinfo(CODESET);
337-
if (sys)
338-
sys = strdup(sys);
339-
#else
340-
sys = win32_langinfo(name);
310+
locale_t loc;
341311
#endif
342312

343-
setlocale(LC_CTYPE, save);
344-
free(save);
345-
}
346-
else
347-
{
348-
/* much easier... */
313+
/* Get the CODESET property, and also LC_CTYPE if not passed in */
314+
if (!ctype)
349315
ctype = setlocale(LC_CTYPE, NULL);
350-
if (!ctype)
351-
return -1; /* setlocale() broken? */
352316

353-
/* If locale is C or POSIX, we can allow all encodings */
354-
if (pg_strcasecmp(ctype, "C") == 0 ||
355-
pg_strcasecmp(ctype, "POSIX") == 0)
356-
return PG_SQL_ASCII;
317+
318+
/* If locale is C or POSIX, we can allow all encodings */
319+
if (pg_strcasecmp(ctype, "C") == 0 ||
320+
pg_strcasecmp(ctype, "POSIX") == 0)
321+
return PG_SQL_ASCII;
322+
357323

358324
#ifndef WIN32
359-
sys = nl_langinfo(CODESET);
360-
if (sys)
361-
sys = strdup(sys);
325+
loc = newlocale(LC_CTYPE_MASK, ctype, (locale_t) 0);
326+
if (loc == (locale_t) 0)
327+
return -1; /* bogus ctype passed in? */
328+
329+
sys = nl_langinfo_l(CODESET, loc);
330+
if (sys)
331+
sys = strdup(sys);
332+
333+
freelocale(loc);
362334
#else
363-
sys = win32_langinfo(ctype);
335+
sys = win32_langinfo(ctype);
364336
#endif
365-
}
366337

367338
if (!sys)
368339
return -1; /* out of memory; unlikely */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy