Email List: Xaustin-group-lX
[All Lists]

Re: Clearing environ

To: austin-group-l@xxxxxxxxxxxxx
Subject: Re: Clearing environ
From: "Sean C. Farley" <scf@xxxxxxxxxxx>
Date: Fri, 1 Aug 2008 10:16:54 -0500 (CDT)
References: <alpine.BSF.1.10.0807311820120.1078@xxxxxx> <1217555255.5538.94.camel@amstaff2.msbit.com>
On Thu, 31 Jul 2008, Nick Stoughton wrote:

POSIX defines the environ variable, and the putenv(), setenv() and
unsetenv() functions.

In the rationale for getenv(), there is the following warning (2008
edition):

<quote>
Conforming applications are required not to modify environ directly, but
to use only the functions described here to manipulate the process
environment as an abstract object. Thus, the implementation of the
environment access functions has complete control over the data
structure used to represent the environment (subject to the requirement
that environ be maintained as a list of strings with embedded
<equals-sign> characters for applications that wish to scan the
environment). This constraint allows the implementation to properly
manage the memory it allocates, either by using allocated storage for
all variables (copying them on the first invocation of setenv( ) or
unsetenv( )), or keeping track of which strings are currently in
allocated space and which are not, via a separate table or some other
means. This enables the implementation to free any allocated space used
by strings (and perhaps the pointers to them) stored in environ when
unsetenv( ) is called. A C runtime start-up procedure (that which
invokes main( ) and perhaps initializes environ) can also initialize a
flag indicating that none of the environment has yet been copied to
allocated storage, or that the separate table has not yet been
initialized.

In fact, for higher performance of getenv( ), the implementation could
also maintain a separate copy of the environment in a data structure
that could be searched much more quickly (such as an indexed hash table,
or a binary tree), and update both it and the linear list at environ
when setenv( ) or unsetenv( ) is invoked.
</quote>
I agree with the rationale, yet I wish environ was completely hidden
from direct contact by applications.

Really, the only defined ways of clearing the environment are:
1. execve/execle/fexecve a new program with the environ set to NULL
2. Use the "env -i" utility to do the same thing
3. somehow get a list of all the currently set environment variables
   and unsetenv() each one in turn.
Actually, mention of these defined methods somewhere with environ and/or
getenv() would be nice.  As can be seen with the use of various methods
to clear the environment by assorted applications.

Sendmail uses method 3.  Dovecot and Postfix use method 2.  FreeBSD's
env uses method 3.

On Thu, 2008-07-31 at 18:21 -0500, Sean C. Farley wrote:

Here are all the methods to clear environ that I know:
1. environ = NULL
2. environ[0] = NULL
3. static char *emptyenv[1] = { NULL };
   environ = emptyenv;
4. environ = calloc(1, sizeof(*environ));
5. clearenv()

Questions:
1. Are these the only methods applications may (or should) attempt?
None of these methods is portable
Unfortunately, applications are using these different methods.  I would
agree with saying the applications need to be fixed, yet I would like to
point the developers at a specification that explicitly states how they
should do it.

2. What methods must be, should be and may be supported?
An implementation is *permitted* to allow these, but not required to.
So, to answer this question ... none, none, and all.
OK.  That sounds good.  I will patch the implementation to definitely
support the first four and possibly the fifth depending upon consensus
on freebsd-arch (FreeBSD architecture mailing list).

My feeling is that the first four should be supported until the time
comes when applications cannot touch environ directly.  That is
basically when "... the requirement that environ be maintained as a list
of strings with embedded <equals-sign> characters for applications that
wish to scan the environment" is removed.

3. Will clearenv() be considered, or has a firm decision been made to
   not have it?
The clearenv( ) function was considered but rejected (I do not recall
why).
It would be nice to know.  Maybe there is a collection of rejections, so
someone may learn from history before (re)implementing something?

4. If not clearenv(), what about a API call to provide the environ
   implementation with a new environ to use or copy at its
   discretion?

We don't invent ... that's your job! If you can develop such an API,
have it widely implemented, and bring us the details to add to a new
revision, it would be considered.
I may give it a shot.  Would you define "widely implemented"?  Is it a
complete implementation or many OS's using it?

(My personal opinions only ...)
Regardless, thank you for your help.

Sean
--
scf@xxxxxx

<Prev in Thread] Current Thread [Next in Thread>