Date: Fri, 13 Jul 2007 19:08:37 -0500 (CDT) From: "Sean C. Farley" <scf@FreeBSD.org> To: Andrey Chernov <ache@nagual.pp.ru> Cc: freebsd-current <freebsd-current@FreeBSD.org> Subject: Re: Environment handling broken in /bin/sh with changes to t,set,put}env() Message-ID: <20070713184543.A26096@thor.farley.org> In-Reply-To: <20070713224608.GB21695@nagual.pp.ru> References: <20070707133102.C14065@thor.farley.org> <20070707191835.GA4368@nagual.pp.ru> <20070707205410.B14065@thor.farley.org> <20070708020940.GA80166@nagual.pp.ru> <20070708171727.GA90490@nagual.pp.ru> <20070713162742.GA16260@nagual.pp.ru> <20070713142545.K26096@thor.farley.org> <20070713202433.GA19856@nagual.pp.ru> <20070713203915.GA20270@nagual.pp.ru> <20070713171942.Q26096@thor.farley.org> <20070713224608.GB21695@nagual.pp.ru>
next in thread | previous in thread | raw e-mail | index | archive | help
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@FreeBSD.org
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070713184543.A26096>