Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitab51bba

Browse files
committed
Arrange to set the LC_XXX environment variables to match our locale
setup. This protects against undesired changes in locale behaviorif someone carelessly does setlocale(LC_ALL, "") (and we know whoyou are, perl guys).
1 parentb6c881c commitab51bba

File tree

4 files changed

+146
-51
lines changed

4 files changed

+146
-51
lines changed

‎src/backend/access/transam/xlog.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.223 2005/11/22 18:17:07 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.224 2005/12/28 23:22:50 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -45,6 +45,7 @@
4545
#include"utils/builtins.h"
4646
#include"utils/guc.h"
4747
#include"utils/nabstime.h"
48+
#include"utils/pg_locale.h"
4849
#include"utils/relcache.h"
4950

5051

@@ -3619,14 +3620,14 @@ ReadControlFile(void)
36193620
" but the server was compiled with LOCALE_NAME_BUFLEN %d.",
36203621
ControlFile->localeBuflen,LOCALE_NAME_BUFLEN),
36213622
errhint("It looks like you need to recompile or initdb.")));
3622-
if (setlocale(LC_COLLATE,ControlFile->lc_collate)==NULL)
3623+
if (pg_perm_setlocale(LC_COLLATE,ControlFile->lc_collate)==NULL)
36233624
ereport(FATAL,
36243625
(errmsg("database files are incompatible with operating system"),
36253626
errdetail("The database cluster was initialized with LC_COLLATE \"%s\","
36263627
" which is not recognized by setlocale().",
36273628
ControlFile->lc_collate),
36283629
errhint("It looks like you need to initdb or install locale support.")));
3629-
if (setlocale(LC_CTYPE,ControlFile->lc_ctype)==NULL)
3630+
if (pg_perm_setlocale(LC_CTYPE,ControlFile->lc_ctype)==NULL)
36303631
ereport(FATAL,
36313632
(errmsg("database files are incompatible with operating system"),
36323633
errdetail("The database cluster was initialized with LC_CTYPE \"%s\","

‎src/backend/main/main.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.97 2005/11/22 18:17:11 momjian Exp $
16+
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.98 2005/12/28 23:22:51 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
2020
#include"postgres.h"
2121

22-
#include<errno.h>
2322
#include<pwd.h>
2423
#include<unistd.h>
2524

@@ -40,6 +39,7 @@
4039
#include"postmaster/postmaster.h"
4140
#include"tcop/tcopprot.h"
4241
#include"utils/help_config.h"
42+
#include"utils/pg_locale.h"
4343
#include"utils/ps_status.h"
4444
#ifdefWIN32
4545
#include"libpq/pqsignal.h"
@@ -162,30 +162,37 @@ main(int argc, char *argv[])
162162
*/
163163

164164
if ((env_locale=getenv("LC_COLLATE"))!=NULL)
165-
setlocale(LC_COLLATE,env_locale);
165+
pg_perm_setlocale(LC_COLLATE,env_locale);
166166
else
167-
setlocale(LC_COLLATE,"");
167+
pg_perm_setlocale(LC_COLLATE,"");
168168

169169
if ((env_locale=getenv("LC_CTYPE"))!=NULL)
170-
setlocale(LC_CTYPE,env_locale);
170+
pg_perm_setlocale(LC_CTYPE,env_locale);
171171
else
172-
setlocale(LC_CTYPE,"");
172+
pg_perm_setlocale(LC_CTYPE,"");
173173
#else
174-
setlocale(LC_COLLATE,"");
175-
setlocale(LC_CTYPE,"");
174+
pg_perm_setlocale(LC_COLLATE,"");
175+
pg_perm_setlocale(LC_CTYPE,"");
176176
#endif
177177

178178
#ifdefLC_MESSAGES
179-
setlocale(LC_MESSAGES,"");
179+
pg_perm_setlocale(LC_MESSAGES,"");
180180
#endif
181181

182182
/*
183183
* We keep these set to "C" always, except transiently in pg_locale.c; see
184184
* that file for explanations.
185185
*/
186-
setlocale(LC_MONETARY,"C");
187-
setlocale(LC_NUMERIC,"C");
188-
setlocale(LC_TIME,"C");
186+
pg_perm_setlocale(LC_MONETARY,"C");
187+
pg_perm_setlocale(LC_NUMERIC,"C");
188+
pg_perm_setlocale(LC_TIME,"C");
189+
190+
/*
191+
* Now that we have absorbed as much as we wish to from the locale
192+
* environment, remove any LC_ALL setting, so that the environment
193+
* variables installed by pg_perm_setlocale have force.
194+
*/
195+
unsetenv("LC_ALL");
189196

190197
/*
191198
* Skip permission checks if we're just trying to do --help or --version;

‎src/backend/utils/adt/pg_locale.c

Lines changed: 120 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Portions Copyright (c) 2002-2005, PostgreSQL Global Development Group
66
*
7-
* $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.32 2005/10/15 02:49:29 momjian Exp $
7+
* $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.33 2005/12/28 23:22:51 tgl Exp $
88
*
99
*-----------------------------------------------------------------------
1010
*/
@@ -50,20 +50,129 @@
5050

5151
#include<locale.h>
5252

53+
#include"catalog/pg_control.h"
5354
#include"utils/pg_locale.h"
5455

5556

56-
/* indicated whether locale information cache is valid */
57-
staticboolCurrentLocaleConvValid= false;
58-
59-
6057
/* GUC storage area */
6158

6259
char*locale_messages;
6360
char*locale_monetary;
6461
char*locale_numeric;
6562
char*locale_time;
6663

64+
/* indicates whether locale information cache is valid */
65+
staticboolCurrentLocaleConvValid= false;
66+
67+
/* Environment variable storage area */
68+
69+
#defineLC_ENV_BUFSIZE (LOCALE_NAME_BUFLEN + 20)
70+
71+
staticcharlc_collate_envbuf[LC_ENV_BUFSIZE];
72+
staticcharlc_ctype_envbuf[LC_ENV_BUFSIZE];
73+
#ifdefLC_MESSAGES
74+
staticcharlc_messages_envbuf[LC_ENV_BUFSIZE];
75+
#endif
76+
staticcharlc_monetary_envbuf[LC_ENV_BUFSIZE];
77+
staticcharlc_numeric_envbuf[LC_ENV_BUFSIZE];
78+
staticcharlc_time_envbuf[LC_ENV_BUFSIZE];
79+
80+
81+
/*
82+
* pg_perm_setlocale
83+
*
84+
* This is identical to the libc function setlocale(), with the addition
85+
* that if the operation is successful, the corresponding LC_XXX environment
86+
* variable is set to match. By setting the environment variable, we ensure
87+
* that any subsequent use of setlocale(..., "") will preserve the settings
88+
* made through this routine. Of course, LC_ALL must also be unset to fully
89+
* ensure that, but that has to be done elsewhere after all the individual
90+
* LC_XXX variables have been set correctly. (Thank you Perl for making this
91+
* kluge necessary.)
92+
*/
93+
char*
94+
pg_perm_setlocale(intcategory,constchar*locale)
95+
{
96+
char*result;
97+
constchar*envvar;
98+
char*envbuf;
99+
100+
#ifndefWIN32
101+
result=setlocale(category,locale);
102+
#else
103+
/*
104+
* On Windows, setlocale(LC_MESSAGES) does not work, so just assume
105+
* that the given value is good and set it in the environment variables.
106+
* We must ignore attempts to set to "", which means "keep using the
107+
* old environment value".
108+
*/
109+
if (category!=LC_MESSAGES)
110+
result=setlocale(category,locale);
111+
else
112+
{
113+
result= (char*)locale;
114+
if (locale==NULL||locale[0]=='\0')
115+
returnresult;
116+
}
117+
#endif
118+
119+
if (result==NULL)
120+
returnresult;/* fall out immediately on failure */
121+
122+
switch (category)
123+
{
124+
caseLC_COLLATE:
125+
envvar="LC_COLLATE";
126+
envbuf=lc_collate_envbuf;
127+
break;
128+
caseLC_CTYPE:
129+
envvar="LC_CTYPE";
130+
envbuf=lc_ctype_envbuf;
131+
break;
132+
#ifdefLC_MESSAGES
133+
caseLC_MESSAGES:
134+
envvar="LC_MESSAGES";
135+
envbuf=lc_messages_envbuf;
136+
break;
137+
#endif
138+
caseLC_MONETARY:
139+
envvar="LC_MONETARY";
140+
envbuf=lc_monetary_envbuf;
141+
break;
142+
caseLC_NUMERIC:
143+
envvar="LC_NUMERIC";
144+
envbuf=lc_numeric_envbuf;
145+
break;
146+
caseLC_TIME:
147+
envvar="LC_TIME";
148+
envbuf=lc_time_envbuf;
149+
break;
150+
default:
151+
elog(FATAL,"unrecognized LC category: %d",category);
152+
envvar=NULL;/* keep compiler quiet */
153+
envbuf=NULL;
154+
break;
155+
}
156+
157+
snprintf(envbuf,LC_ENV_BUFSIZE-1,"%s=%s",envvar,result);
158+
159+
#ifndefWIN32
160+
if (putenv(envbuf))
161+
returnNULL;
162+
#else
163+
/*
164+
* On Windows, we need to modify both the process environment and the
165+
* cached version in msvcrt
166+
*/
167+
if (!SetEnvironmentVariable(envvar,result))
168+
returnNULL;
169+
if (_putenv(envbuf))
170+
returnNULL;
171+
#endif
172+
173+
returnresult;
174+
}
175+
67176

68177
/* GUC assign hooks */
69178

@@ -123,48 +232,24 @@ locale_time_assign(const char *value, bool doit, GucSource source)
123232
constchar*
124233
locale_messages_assign(constchar*value,booldoit,GucSourcesource)
125234
{
126-
#ifndefWIN32
127-
128235
/*
129236
* LC_MESSAGES category does not exist everywhere, but accept it anyway
237+
*
238+
* On Windows, we can't even check the value, so the non-doit case
239+
* is a no-op
130240
*/
131241
#ifdefLC_MESSAGES
132242
if (doit)
133243
{
134-
if (!setlocale(LC_MESSAGES,value))
244+
if (!pg_perm_setlocale(LC_MESSAGES,value))
135245
returnNULL;
136246
}
247+
#ifndefWIN32
137248
else
138249
value=locale_xxx_assign(LC_MESSAGES,value, false,source);
250+
#endif/* WIN32 */
139251
#endif/* LC_MESSAGES */
140252
returnvalue;
141-
#else/* WIN32 */
142-
143-
/*
144-
* Win32 does not have working setlocale() for LC_MESSAGES. We can only
145-
* use environment variables to change it (per gettext FAQ). This means
146-
* we can't actually check the supplied value, so always assume it's good.
147-
* Also, ignore attempts to set to "", which really means "keep using the
148-
* old value". (Actually it means "use the environment value", but we are
149-
* too lazy to try to implement that exactly.)
150-
*/
151-
if (doit&&value[0])
152-
{
153-
/*
154-
* We need to modify both the process environment and the cached
155-
* version in msvcrt
156-
*/
157-
staticcharenv[128];
158-
159-
if (!SetEnvironmentVariable("LC_MESSAGES",value))
160-
returnNULL;
161-
162-
snprintf(env,sizeof(env)-1,"LC_MESSAGES=%s",value);
163-
if (_putenv(env))
164-
returnNULL;
165-
}
166-
returnvalue;
167-
#endif/* WIN32 */
168253
}
169254

170255

‎src/include/utils/pg_locale.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
*
33
* PostgreSQL locale utilities
44
*
5-
* $PostgreSQL: pgsql/src/include/utils/pg_locale.h,v 1.20 2005/03/16 00:02:49 momjian Exp $
5+
* $PostgreSQL: pgsql/src/include/utils/pg_locale.h,v 1.21 2005/12/28 23:22:51 tgl Exp $
66
*
77
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
88
*
@@ -31,6 +31,8 @@ extern const char *locale_numeric_assign(const char *value,
3131
externconstchar*locale_time_assign(constchar*value,
3232
booldoit,GucSourcesource);
3333

34+
externchar*pg_perm_setlocale(intcategory,constchar*locale);
35+
3436
externboollc_collate_is_c(void);
3537
externboollc_ctype_is_c(void);
3638

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp