Commit 6fdba8ce authored by Noah Misch's avatar Noah Misch

Always set the six locale category environment variables in main().

Typical server invocations already achieved that.  Invalid locale
settings in the initial postmaster environment interfered, as could
malloc() failure.  Setting "LC_MESSAGES=pt_BR.utf8 LC_ALL=invalid" in
the postmaster environment will now choose C-locale messages, not
Brazilian Portuguese messages.  Most localized programs, including all
PostgreSQL frontend executables, do likewise.  Users are unlikely to
observe changes involving locale categories other than LC_MESSAGES.
CheckMyDatabase() ensures that we successfully set LC_COLLATE and
LC_CTYPE; main() sets the remaining three categories to locale "C",
which almost cannot fail.  Back-patch to 9.0 (all supported versions).
parent e415b469
...@@ -43,6 +43,7 @@ const char *progname; ...@@ -43,6 +43,7 @@ const char *progname;
static void startup_hacks(const char *progname); static void startup_hacks(const char *progname);
static void init_locale(int category, const char *locale);
static void help(const char *progname); static void help(const char *progname);
static void check_root(const char *progname); static void check_root(const char *progname);
...@@ -115,31 +116,31 @@ main(int argc, char *argv[]) ...@@ -115,31 +116,31 @@ main(int argc, char *argv[])
char *env_locale; char *env_locale;
if ((env_locale = getenv("LC_COLLATE")) != NULL) if ((env_locale = getenv("LC_COLLATE")) != NULL)
pg_perm_setlocale(LC_COLLATE, env_locale); init_locale(LC_COLLATE, env_locale);
else else
pg_perm_setlocale(LC_COLLATE, ""); init_locale(LC_COLLATE, "");
if ((env_locale = getenv("LC_CTYPE")) != NULL) if ((env_locale = getenv("LC_CTYPE")) != NULL)
pg_perm_setlocale(LC_CTYPE, env_locale); init_locale(LC_CTYPE, env_locale);
else else
pg_perm_setlocale(LC_CTYPE, ""); init_locale(LC_CTYPE, "");
} }
#else #else
pg_perm_setlocale(LC_COLLATE, ""); init_locale(LC_COLLATE, "");
pg_perm_setlocale(LC_CTYPE, ""); init_locale(LC_CTYPE, "");
#endif #endif
#ifdef LC_MESSAGES #ifdef LC_MESSAGES
pg_perm_setlocale(LC_MESSAGES, ""); init_locale(LC_MESSAGES, "");
#endif #endif
/* /*
* We keep these set to "C" always, except transiently in pg_locale.c; see * We keep these set to "C" always, except transiently in pg_locale.c; see
* that file for explanations. * that file for explanations.
*/ */
pg_perm_setlocale(LC_MONETARY, "C"); init_locale(LC_MONETARY, "C");
pg_perm_setlocale(LC_NUMERIC, "C"); init_locale(LC_NUMERIC, "C");
pg_perm_setlocale(LC_TIME, "C"); init_locale(LC_TIME, "C");
/* /*
* Now that we have absorbed as much as we wish to from the locale * Now that we have absorbed as much as we wish to from the locale
...@@ -277,6 +278,23 @@ startup_hacks(const char *progname) ...@@ -277,6 +278,23 @@ startup_hacks(const char *progname)
} }
/*
* Make the initial permanent setting for a locale category. If that fails,
* perhaps due to LC_foo=invalid in the environment, use locale C. If even
* that fails, perhaps due to out-of-memory, the entire startup fails with it.
* When this returns, we are guaranteed to have a setting for the given
* category's environment variable.
*/
static void
init_locale(int category, const char *locale)
{
if (pg_perm_setlocale(category, locale) == NULL &&
pg_perm_setlocale(category, "C") == NULL)
elog(FATAL, "could not adopt C locale");
}
/* /*
* Help display should match the options accepted by PostmasterMain() * Help display should match the options accepted by PostmasterMain()
* and PostgresMain(). * and PostgresMain().
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment