X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=-6.8 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Message-ID: <4CCB439B.7060602@redhat.com> Date: Fri, 29 Oct 2010 15:58:51 -0600 From: Eric Blake User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.9) Gecko/20100921 Fedora/3.1.4-1.fc13 Mnenhy/0.8.3 Thunderbird/3.1.4 MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Re: localtime and TZ References: <4CCB4025 DOT 6070405 AT cornell DOT edu> <4CCB42AF DOT 2090907 AT redhat DOT com> In-Reply-To: <4CCB42AF.2090907@redhat.com> OpenPGP: url=http://people.redhat.com/eblake/eblake.gpg Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="------------enig14FC5DD63D273FA8BBCB21EF" X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com --------------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 >> #include >> >> extern char **environ; Also, you should be including 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--