bug in putenv()!

Chris Torek chris at mimsy.UUCP
Wed Feb 22 09:50:06 AEST 1989


In article <233 at tree.UUCP> asmodeus at tree.UUCP (Jonathan Ballard) writes:
>From what you people have been saying is that I can't pass in a automatic
>varible because putenv uses that space, right?

No, not right; see below.

>... Why doesn't putenv just alloc a new spot for the enviroment
>varible to go?

It expects *you* to do that, if it is necessary (often it is not).

>But if I do understand this right - I have to make several global or
>static varible just to handle space for the enviroment.

Not so.

A real treatment of the issue belongs in comp.lang.c.  The important
part, however, is the storage for the *characters* to which the thing
you hand to putenv() will point must remain undisturbed.  Thus, the
following is wrong (but may work, if you are unlucky, depending on
how much stack junk you might have:)

	main() {
		set();
		... refer to environment ...
	}

	set() {
		char env[30];

		strcpy(env, "FOO=bar");
		putenv(env);
	}

But if main() does not return to its caller (if it ends with exit(0)),
or if its caller (the C library startup code) does not look at the
environment, the following is correct:

	main() {
		char env[30];

		strcpy(env, "FOO=bar");
		putenv(env);
	}

In both examples, `env' provides space for 30 characters.  The
environment will retain a pointer to the first of those thirty
characters (the `F' in FOO=bar).  This space-for-30-chars is `alive'
(guaranteed to remain undisturbed) for the duration of main() and any
functions called by main()---in other words, for the entire program.
If `env' is declared in `set()', the space is alive only for the
duration of the call to set().  When set() returns to main(), the space
becomes dead and is free to be reused.  Whether it *is* reused is
compiler- and system-dependent (and may even vary from one run to
another).

As another example,

		putenv("FOO=bar");

would be correct whether it were in set() or in main().  This is
because a double-quoted string has static storage duration:  that is,
there is one copy of the characters making up that string, and it sits
somewhere in text or data space, never moving and (unless you do
something technically illegal) never changing.  You can make set()
work by changing it from

	set() {
		char env[30];

to

	set() {
		static char env[30];

Finally, at any time, you can always call

	p = strdup(pointer);
	if (p == NULL) ... error ...
	putenv(p);

(you may need to write strdup() first if you have an old support
library).  strdup() calls malloc() to allocate space for the string
at which `pointer' is assumed to point.  The space allocated by
malloc() will not be reused unless you allow it.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.unix.wizards mailing list