getenv returns same string as putenv?

M

Michael B Allen

Is the string returned by getenv guaranteed to be the same string supplied
to putenv plus the offset of the variable name and equals sign?

Because of API constraints I do not want to save a pointer to the string
passed to putenv but I need to be able to free it later or I will have
a memory leak.

The following code demponstrates that with at least glibc the same string
is in fact returned.

unsigned char *s1, *s2;

s2 = "SOMEVAR=whatever";
s1 = malloc(strlen(s2) + 1);
strcpy(s1, s2);

if (putenv(s1) == -1) {
PMNO(errno);
return -1;
}

s2 = getenv("SOMEVAR");

printf("s1=%p,s2 - 8=%p\n", s1, s2 - 8);

free(s2 - 8);

output: s1=0x9925828,s2 - 8=0x9925828

Mike
 
C

Chris Dollin

Michael said:
Is the string returned by getenv guaranteed to be the same string supplied
to putenv plus the offset of the variable name and equals sign?

There is no `putenv`, at least not in Standard C.

(fx:eek:t)

I see from `man putenv` on my Linux box that `putenv` is supposed there to
conform to SVID 3, POSIX, 4.3BSD. So it looks like you will have to
appeal to implementation-specific documentation or newsgroups.

That same man page says

int putenv(char *string);
....
The string pointed to by string becomes part of the environment,
so altering the string changes the environment.

(fx:bot)

Can you redesign to eliminate this use of `putenv` and eliminate the
problem? That's what I'd [try to] do.
 
E

Eric Sosman

Michael said:
Is the string returned by getenv guaranteed to be the same string supplied
to putenv plus the offset of the variable name and equals sign?

No, because there is no putenv() in the Standard C library.
As far as C is concerned, the environment is read-only.
Because of API constraints I do not want to save a pointer to the string
passed to putenv but I need to be able to free it later or I will have
a memory leak.

... and this may be one of the reasons the Standard doesn't
define putenv(): deciding who manages the memory could turn out
to be troublesome. Should putenv() copy the provided string,
or should it require that the string continue to exist? If it
copies, what should it do if unable to allocate memory to hold
the string (in particular, can it free() a prior value and then
fail to set the new one, or must it guarantee all-or-nothing)?

Questions like this can, of course, be settled, even if by
arbitrary choice. However, the Committee chose not to settle
it, writing (in the Rationale)

A corresponding putenv function was omitted from the
Standard, since its utility outside a multi-process
environment is questionable, and since its definition
is properly the domain of an operating system standard.

It's possible that this is face-saving language for "We couldn't
find a way to reconcile the conflicting behaviors of different
existing putenv() implementations, so we punted." But face-saving
or face-value, that's the state of affairs: There's no putenv() in
the C library, and systems that provide it as an extension have
defined their extensions in somewhat different ways.
 
B

Ben Pfaff

Michael B Allen said:
Is the string returned by getenv guaranteed to be the same string supplied
to putenv plus the offset of the variable name and equals sign?

No: the implementation is allowed to reuse a static buffer on
each call to getenv. (I am assuming that "putenv" is the "method
for altering the environment list" that the Standard says is
implementation-defined.)
 
M

Michael B Allen

Can you redesign to eliminate this use of `putenv` and eliminate the
problem? That's what I'd [try to] do.

Yeah, on second thought, even if getenv was guaranteed to return what
was supplied to putenv there would be no way to guarantee that putenv
was not called by code outside of my scope and therefore freeing the
result of getenv is inherently flawed.

I'll have to wrap them and use a global to ensure it doesn't leak.

Thanks,
Mike
 
R

Richard Bos

Eric Sosman said:
Questions like this can, of course, be settled, even if by
arbitrary choice. However, the Committee chose not to settle
it, writing (in the Rationale)

A corresponding putenv function was omitted from the
Standard, since its utility outside a multi-process
environment is questionable, and since its definition
is properly the domain of an operating system standard.

It's possible that this is face-saving language for "We couldn't
find a way to reconcile the conflicting behaviors of different
existing putenv() implementations, so we punted."

Possibly more like "We couldn't find a way to reconcile the conflicting
behaviours of different OSes, so we were forced to punt".

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top