On Mon, Sep 15, 2014 at 12:51:14AM -0400, Noah Misch wrote:
> 1. Fork, call setlocale(LC_x, "") in the child, pass back the effective locale
> name through a pipe, and pass that name to setlocale() in the original
> process. The short-lived child will get the extra threads, and the
> postmaster will remain clean.
Here's an implementation thereof covering both backend and frontend use of
setlocale(). A setlocale() wrapper, pg_setlocale(), injects use of the child
process where necessary. I placed the new function in src/common/exec.c,
because every executable already needed that file's code and translatable
strings for set_pglocale_pgservice() and callees. (Some executables do miss
exec.c translations; I did not update them.) src/port/chklocale.c was closer
in subject matter, but libpq imports it; this function does not belong in
libpq. Also, this function would benefit from a frontend ereport()
implementation, which is likely to land in libpgcommon if it lands at all.
The runtime changes are conditional on __darwin__ but not on --enable-nls.
NLS builds are the production norm; I'd like non-NLS builds to consistently
exercise this code rather than shave its bytes and cycles.
pg_setlocale() relies on main() setting all six LC_<category> environment
variables. The second attached patch seals the cracks in main()'s
longstanding attempt to do so. This improves preexisting user-visible
behavior in weird cases: "LANG=pt_BR.utf8 LC_ALL=invalid postgres -D nosuch"
will now print untranslated text, not pt_BR text.
Documentation for each of lc_monetary, lc_numeric and lc_time says "If this
variable is set to the empty string (which is the default) then the value is
inherited from the execution environment of the server in a system-dependent
way." Not so; by design, setlocale(LC_x, "") just re-selects the last value L
passed to pg_perm_setlocale(LC_x, L). I have not touched this; I mention it
for the sake of the archives.