Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6fdba8c

Browse files
committed
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).
1 parent e415b46 commit 6fdba8c

File tree

1 file changed

+28
-10
lines changed

1 file changed

+28
-10
lines changed

src/backend/main/main.c

+28-10
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const char *progname;
4343

4444

4545
static void startup_hacks(const char *progname);
46+
static void init_locale(int category, const char *locale);
4647
static void help(const char *progname);
4748
static void check_root(const char *progname);
4849

@@ -115,31 +116,31 @@ main(int argc, char *argv[])
115116
char *env_locale;
116117

117118
if ((env_locale = getenv("LC_COLLATE")) != NULL)
118-
pg_perm_setlocale(LC_COLLATE, env_locale);
119+
init_locale(LC_COLLATE, env_locale);
119120
else
120-
pg_perm_setlocale(LC_COLLATE, "");
121+
init_locale(LC_COLLATE, "");
121122

122123
if ((env_locale = getenv("LC_CTYPE")) != NULL)
123-
pg_perm_setlocale(LC_CTYPE, env_locale);
124+
init_locale(LC_CTYPE, env_locale);
124125
else
125-
pg_perm_setlocale(LC_CTYPE, "");
126+
init_locale(LC_CTYPE, "");
126127
}
127128
#else
128-
pg_perm_setlocale(LC_COLLATE, "");
129-
pg_perm_setlocale(LC_CTYPE, "");
129+
init_locale(LC_COLLATE, "");
130+
init_locale(LC_CTYPE, "");
130131
#endif
131132

132133
#ifdef LC_MESSAGES
133-
pg_perm_setlocale(LC_MESSAGES, "");
134+
init_locale(LC_MESSAGES, "");
134135
#endif
135136

136137
/*
137138
* We keep these set to "C" always, except transiently in pg_locale.c; see
138139
* that file for explanations.
139140
*/
140-
pg_perm_setlocale(LC_MONETARY, "C");
141-
pg_perm_setlocale(LC_NUMERIC, "C");
142-
pg_perm_setlocale(LC_TIME, "C");
141+
init_locale(LC_MONETARY, "C");
142+
init_locale(LC_NUMERIC, "C");
143+
init_locale(LC_TIME, "C");
143144

144145
/*
145146
* Now that we have absorbed as much as we wish to from the locale
@@ -277,6 +278,23 @@ startup_hacks(const char *progname)
277278
}
278279

279280

281+
/*
282+
* Make the initial permanent setting for a locale category. If that fails,
283+
* perhaps due to LC_foo=invalid in the environment, use locale C. If even
284+
* that fails, perhaps due to out-of-memory, the entire startup fails with it.
285+
* When this returns, we are guaranteed to have a setting for the given
286+
* category's environment variable.
287+
*/
288+
static void
289+
init_locale(int category, const char *locale)
290+
{
291+
if (pg_perm_setlocale(category, locale) == NULL &&
292+
pg_perm_setlocale(category, "C") == NULL)
293+
elog(FATAL, "could not adopt C locale");
294+
}
295+
296+
297+
280298
/*
281299
* Help display should match the options accepted by PostmasterMain()
282300
* and PostgresMain().

0 commit comments

Comments
 (0)