Mail Archives: cygwin/2010/10/29/17:59:05
--------------enig14FC5DD63D273FA8BBCB21EF
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On 10/29/2010 03:54 PM, Eric Blake wrote:
> On 10/29/2010 03:44 PM, Ken Brown wrote:
>> While trying to debug a timezone problem in the Cygwin build of emacs, I=
've come across a difference between Cygwin and Linux in the behavior of lo=
caltime with respect to TZ. Suppose I set TZ, call localtime, unset TZ, an=
d call localtime again. On Cygwin, the second call to localtime re-uses th=
e previous value of TZ. On Linux, localtime reverts to giving local inform=
ation, just as if TZ had never been set. Here's a Simple Test Case:
>>
>> #include <time.h>
>> #include <stdio.h>
>>
>> extern char **environ;
Also, you should be including <unistd.h> for the declaration of environ,
rather than declaring it yourself.
>>
>> void
>> unset_TZ (void)
>> {
>> char **from, **to;
>> for (to =3D from =3D environ; (*to =3D *from); from++)
>> if (! (to[0][0] =3D=3D 'T' && to[0][1] =3D=3D 'Z' && to[0][2] =3D=3D=
'=3D'))
>> to++;
>> }
>=20
> Messing directly with environ is your problem. POSIX says that it is
> only portable to traverse (but not modify) environ's contents, or to
> completely assign a new array to environ. By going behind cygwin's
> back, and not using unsetenv(), you have violated POSIX and can't expect
> sane results.
In particular:
http://austingroupbugs.net/view.php?id=3D167
If the application modifies the pointers to which environ
points, the behavior of all interfaces described in the System
Interfaces volume of POSIX.1-2008 is undefined.
Conforming applications are required not to directly modify the
pointers to which environ points, but to use only the setenv(),
unsetenv() and putenv() functions, or assignment to environ
itself, to manipulate the process environment. This constraint
allows the implementation to properly manage the memory it
allocates. This enables the implementation to free any space it
has allocated to 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. If the application
switches to a complete new environment by assigning a new value
to environ, this can be detected by getenv(), setenv(), unsetenv()
or putenv() and the implementation can at that point reinitialize
based on the new environment. (This may include copying the
environment strings into a new array and assigning environ to
point to it.)
In fact, for higher performance of getenv(), implementations
that do not provide putenv() 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. On implementations that do
provide putenv(), such a copy might still be worthwhile but
would need to allow for the fact that applications can directly
modify the content of environment strings added with putenv().
For example, if an environment string found by searching the
copy is one that was added using putenv(), the implementation
would need to check that the string in environ still has the
same name (and value, if the copy includes values), and whenever
searching the copy produces no match the implementation would
then need to search each environment string in environ that
was added using putenv() in case any of them have changed their
names and now match. Thus each use of putenv() to add to the
environment would reduce the speed advantage of having the copy.
After page 772 line 25712 section exec, add two new paragraphs:
Applications can change the entire environment in a single
operation by assigning the environ variable to point to an array
of character pointers to the new environment strings.
After assigning a new value to environ, applications should
not rely on the new environment strings remaining part of the
environment, as a call to getenv(), [XSI]putenv(),[/XSI]
setenv(), unsetenv() or any function that is dependent on an
environment variable may, on noticing that environ has changed,
copy the environment strings to a new array and assign environ
to point to it.
Any application that directly modifies the pointers to which the
environ variable points has undefined behavior.
--=20
Eric Blake eblake AT redhat DOT com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
--------------enig14FC5DD63D273FA8BBCB21EF
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Public key at http://people.redhat.com/eblake/eblake.gpg
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iQEcBAEBCAAGBQJMy0ObAAoJEKeha0olJ0Nqu4QH/iTvjsJLU2bllPRZbkG1MqQ0
vCVm5se/N2QPG3S0pPT+TF8HUDHhHQIl+5tZoNTWbLxoNhWI+230gtfQbFceaPvk
W2BJmyKmKZ0rF+9BvW+W4k6eY1oHOwuqPAhLXkXCpp6bPNyGa+k9OMUOJOZCMVxZ
uNryXYOjX548XuE9gS4iEjbl2vA/pYLymzhyDyajmlKS6//647HTYCdC6B451DfQ
UO3CFaChMVY/p1wms60noOn/AotwRNJYFrxiRFI7OaaN0umSlkYsSZmgGyXSl70Q
w/YpL2uCOAbFMoQg2eKvj+o4meMQf5CnfcF95evHR9gtAKWgBiIfmmTZqGDkuws=
=VLze
-----END PGP SIGNATURE-----
--------------enig14FC5DD63D273FA8BBCB21EF--
- Raw text -