Bug 18256

Summary: putenv declared as putenv(char*) and not as putenv(const char*)
Product: [Retired] Red Hat Linux Reporter: peter.stamfest
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 7.0CC: dr
Target Milestone: ---   
Target Release: ---   
Hardware: i686   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2000-10-03 19:11:22 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description peter.stamfest 2000-10-03 19:05:41 UTC
$ grep putenv /usr/include/*  2>/dev/null   # throw away error msg due to
dirs
/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
dependencies)

Comment 1 Jakub Jelinek 2000-10-03 21:35:45 UTC
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.

Comment 2 peter.stamfest 2000-10-04 03:48:24 UTC
I do understand what you mean
So why do both the man page and the info files always refer to putenv(const
char*)? 
Should that have been a problem all the time? It definitely IS a  change.WRT
earlier libcs.

On my RH6 system I have (glibc-2.1.2-11):

extern int putenv __P ((__const char *__string));

in /usr/include/stdlib.h

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
implicitely.

So there is a documentation problem somewhere. And a lot of "buggy" code.


Comment 3 Jakub Jelinek 2000-10-04 11:16:00 UTC
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.

and

       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.