Red Hat Bugzilla – Bug 18256
putenv declared as putenv(char*) and not as putenv(const char*)
Last modified: 2008-05-01 11:37:59 EDT
$ grep putenv /usr/include/* 2>/dev/null # throw away error msg due to
/usr/include/stdlib.h:extern int putenv (char *__string) __THROW;
This breaks the rebuild of my very own RPMs for 7.0 (needed due to kernel
putenv is intentionally declared with char *, not const char *,
because unlike setenv, it puts that string directly into environment,
meaning anyone changing environment can change your string passed
to putenv. That's e.g. why UNIX98 declares putenv char * as well,
and AFAIK all glibcs did it that way.
If you have a buggy program which passes a constant string to putenv,
you should fix it or cast it to (char *) if you can ensure noone
will temper with it.
I do understand what you mean
So why do both the man page and the info files always refer to putenv(const
Should that have been a problem all the time? It definitely IS a change.WRT
On my RH6 system I have (glibc-2.1.2-11):
extern int putenv __P ((__const char *__string));
Interestingly enough, ENOMEM is listed as possible error code for putenv in my
glibc-2.1.2-11, something that indicates that there is some allocation going on.
Users might guess from this information that a copy of their string is made
So there is a documentation problem somewhere. And a lot of "buggy" code.
Well, if you look at info libc in 7.0, you'll see putenv(char *).
If you look at putenv(3) manpage, the prototype is written there as
putenv(const char *), yes, but if you read on, you'll see that:
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 automatic 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.
SUSv2 removes the `const' from the prototype, and so does glibc 2.1.3.
If you check RHL 6.2, putenv already has (char *) prototype, so this is nothing
new in glibc 2.1.9x.