Re: Environment handling broken in /bin/sh with changes to t,set,put}env()

From: Sean C. Farley <scf_at_FreeBSD.org>
Date: Fri, 13 Jul 2007 19:08:37 -0500 (CDT)
On Sat, 14 Jul 2007, Andrey Chernov wrote:

> On Fri, Jul 13, 2007 at 05:27:58PM -0500, Sean C. Farley wrote:
>> Does that mean that environ is untouched or that the environment is
>> unchanged?  They seem to use both words (environ and environment) in
>> the documentation making me think they are not necessarily the same
>> thing.  Currently, non-getenv() calls rebuilds the environ array if
>> having never been changed before, but the "environment" is
>> "unchanged" if the variable does not exist.  Should that not meet
>> that requirement?
>
> IMHO by the environment they means environ contents, not pointers,
> because they say:
>
> "The setenv() function shall update the list of pointers to which
> environ points."

I want to make certain what you mean.  Upon the first call to setenv()
or unsetenv(), the environ is rebuilt.  The contents are the same.
Before and after execution if no data was changed, environ will look
like this.  The addresses to environ and to each pointer will be
different.  Are you saying that the addresses should not change for
environ, environ[0-1] or all?

environ[0] = "PATH=/bin"
environ[1] = "USER=root"
environ[2] = NULL

I found this in the "Rationale" for getenv():

     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 equal signs 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.

It does not distinguish between whether or not any data changed when
changing environ.  It just says "first invocation of setenv() or
unsetenv()".

Sean
-- 
scf_at_FreeBSD.org
Received on Fri Jul 13 2007 - 22:08:56 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:14 UTC