From: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
---|---|
To: | PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: initdb failure in CVS |
Date: | 2004-05-05 20:09:52 |
Message-ID: | 40994A10.7090802@dunslane.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | 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
From | Date | Subject | |
---|---|---|---|
Next Message | scott.marlowe | 2004-05-05 20:14:39 | Re: PostgreSQL pre-fork speedup |
Previous Message | Shachar Shemesh | 2004-05-05 19:59:44 | Multiple "selects" returned from a single stored procedure |