Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)