Re: initdb failure in CVS - Mailing list pgsql-hackers
| From | Andrew Dunstan |
|---|---|
| Subject | Re: initdb failure in CVS |
| Date | |
| Msg-id | 40994A10.7090802@dunslane.net Whole thread Raw |
| In response to | initdb failure in CVS (Bruce Momjian <pgman@candle.pha.pa.us>) |
| Responses |
Re: initdb failure in CVS
|
| List | pgsql-hackers |
Bruce Momjian wrote:
>I am seeing the following failure of initdb in CVS:
>
> The files belonging to this database system will be owned by user "postgres".
> This user must also own the server process.
>
> The database cluster will be initialized with locale C.
>
> creating directory /u/pg/data ... ok
> creating directory /u/pg/data/global ... ok
> creating directory /u/pg/data/pg_xlog ... ok
> creating directory /u/pg/data/pg_clog ... ok
> creating directory /u/pg/data/base ... ok
> creating directory /u/pg/data/base/1 ... ok
> selecting default max_connections ... 100
> selecting default shared_buffers ... 1000
> creating configuration files ... ok
>
> creating template1 database in /u/pg/data/base/1 ...
>
> FATAL: invalid value for parameter "client_encoding": ""
>
> initdb: child process exited with exit code 1
> initdb: failed
> initdb: removing data directory "/u/pg/data"
>
>The problem seems to be related to a commit made to initdb a few days
>ago.
>
> revision 1.24
> date: 2004/05/05 16:09:31; author: tgl; state: Exp; lines: +23 -2
> Use a more portable technique for unsetting environment variables,
> and unset PGCLIENTENCODING to prevent backend from dying if it's set
> to something incompatible with the -E option.
>
>I don't have any encoding set in my system.
>
>
>
The change is based on this code from here (backend/commands/variable.c):
/*
* unsetenv() works fine, but is BSD, not POSIX, and is not available
* under Solaris, among others. Apparently putenv() called as below
* clears the process-specific environment variables. Other
* reasonable arguments to putenv() (e.g. "TZ=", "TZ", "") result in a
* core dump (under Linux anyway). - thomas 1998-01-26
*/
if (tzbuf[0] == 'T')
{
strcpy(tzbuf, "=");
if (putenv(tzbuf) != 0)
elog(LOG, "could not clear TZ environment variable");
tzset();
}
The Linux man page for putenv says this:
Description for libc4, libc5, glibc: If the argument string is of the
form name, and does not contain an ‘=’ character, then the variable
name is removed from the environment. If putenv() has to allocate a
new array environ, and the previous array was also allocated by
putenv(), then it will be freed. In no case will the old storage asso-
ciated to the environment variable itself be freed.
The libc4 and libc5 and glibc 2.1.2 versions conform to SUSv2: the
pointer string given to putenv() is used. In particular, this string
becomes part of the environment; changing it later will change the
environment. (Thus, it is an error is to call putenv() with an auto-
matic variable as the argument, then return from the calling function
while string is still part of the environment.) However, glibc
2.0-2.1.1 differs: a copy of the string is used. On the one hand this
causes a memory leak, and on the other hand it violates SUSv2. This has
been fixed in glibc2.1.2.
The BSD4.4 version, like glibc 2.0, uses a copy.
I suspect you have seen this latter effect, i.e. it in effect did
putenv("PGCLIENTENCODING=");
putenv("=");
leaving you with an empty string as the env value rather than unsetting it.
Did we actually find a current system where it broke with a straight
putenv("LC_ALL")?
cheers
andrew
pgsql-hackers by date: