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 > localtime with respect to TZ. Suppose I set TZ, call localtime, unset TZ, > and call localtime again. On Cygwin, the second call to localtime re-uses > the previous value of TZ. On Linux, localtime reverts to giving local > information, just as if TZ had never been set. Here's a Simple Test Case: > > #include <time.h> > #include <stdio.h> > > extern char **environ; > > void > unset_TZ (void) > { > char **from, **to; > for (to = from = environ; (*to = *from); from++) > if (! (to[0][0] == 'T' && to[0][1] == 'Z' && to[0][2] == '=')) > to++; > }
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. > > int > main (void) > { > time_t now = time ((time_t *) 0); > printf ("TZ is initially unset; hour = %d\n", localtime (&now)->tm_hour); > putenv ("TZ=GMT0"); > printf ("TZ=GMT0; hour = %d\n", localtime (&now)->tm_hour); > unset_TZ (); > printf ("TZ unset; hour = %d\n", localtime (&now)->tm_hour); > putenv ("TZ=PST8"); > printf ("TZ=PST8; hour = %d\n", localtime (&now)->tm_hour); > unset_TZ (); > printf ("TZ unset again; hour = %d\n", localtime (&now)->tm_hour); > } If properly using unsetenv("TZ") still causes problems, then we should investigate further. -- Eric Blake ebl...@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature