This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Another tzset.c issue


Hi!

#define _GNU_SOURCE
#include <time.h>
#include <stdio.h>

int main ()
{
  tzset ();
  printf ("daylight %d %s %s\n", daylight, tzname[0], tzname[daylight ? 1 : 0]);
}

run with
TZ=EST+5EDT+6,3.1.0,10.5.0
prints
daylight 0 EST EST
instead of the correct
daylight 1 EST EDT

The problem is that __daylight and __tzname are computed strangely
in tz_compute, not in tzset_internal which actually changes the fields
this info is computed from.
tzset() is required to set daylight etc. though (and doesn't
call tz_compute), similarly __tzname_max() when called as the first thing
in the program with TZ=EST+5EDT+6,3.1.0,10.5.0 will return 0, not 3.

2002-03-06  Jakub Jelinek  <jakub@redhat.com>

	* time/tzset.c (tz_compute): Move __daylight, __tzname and
	__tzname_cur_max setting...
	(tzset_internal): ...here.

--- libc/time/tzset.c.jj	Wed Mar  6 16:56:32 2002
+++ libc/time/tzset.c	Wed Mar  6 23:43:55 2002
@@ -121,6 +121,23 @@ __tzstring (const char *s)
   return new->data;
 }
 
+/* Maximum length of a timezone name.  tzset_internal keeps this up to date
+   (never decreasing it) when ! __use_tzfile.
+   tzfile.c keeps it up to date when __use_tzfile.  */
+size_t __tzname_cur_max;
+
+long int
+__tzname_max ()
+{
+  __libc_lock_lock (tzset_lock);
+
+  tzset_internal (0);
+
+  __libc_lock_unlock (tzset_lock);
+
+  return __tzname_cur_max;
+}
+
 static char *old_tz;
 
 /* Interpret the TZ envariable.  */
@@ -186,7 +203,7 @@ tzset_internal (always)
       tz_rules[0].offset = tz_rules[1].offset = 0L;
       tz_rules[0].change = tz_rules[1].change = (time_t) -1;
       tz_rules[0].computed_for = tz_rules[1].computed_for = 0;
-      return;
+      goto out;
     }
 
   /* Clear out old state and reset to unnamed UTC.  */
@@ -198,7 +215,7 @@ tzset_internal (always)
 
   if (sscanf (tz, "%[^0-9,+-]", tzbuf) != 1 ||
       (l = strlen (tzbuf)) < 3)
-    return;
+    goto out;
 
   tz_rules[0].name = __tzstring (tzbuf);
 
@@ -206,7 +223,7 @@ tzset_internal (always)
 
   /* Figure out the standard offset from UTC.  */
   if (*tz == '\0' || (*tz != '+' && *tz != '-' && !isdigit (*tz)))
-    return;
+    goto out;
 
   if (*tz == '-' || *tz == '+')
     tz_rules[0].offset = *tz++ == '-' ? 1L : -1L;
@@ -215,7 +232,7 @@ tzset_internal (always)
   switch (sscanf (tz, "%hu:%hu:%hu", &hh, &mm, &ss))
     {
     default:
-      return;
+      goto out;
     case 1:
       mm = 0;
     case 2:
@@ -387,25 +404,20 @@ tzset_internal (always)
     }
 
  out:
-  /* We know the offset now, set `__timezone'.  */
+  __daylight = tz_rules[0].offset != tz_rules[1].offset;
   __timezone = -tz_rules[0].offset;
-}
-
-/* Maximum length of a timezone name.  __tz_compute keeps this up to date
-   (never decreasing it) when ! __use_tzfile.
-   tzfile.c keeps it up to date when __use_tzfile.  */
-size_t __tzname_cur_max;
-
-long int
-__tzname_max ()
-{
-  __libc_lock_lock (tzset_lock);
-
-  tzset_internal (0);
-
-  __libc_lock_unlock (tzset_lock);
+  __tzname[0] = (char *) tz_rules[0].name;
+  __tzname[1] = (char *) tz_rules[1].name;
 
-  return __tzname_cur_max;
+  {
+    /* Keep __tzname_cur_max up to date.  */
+    size_t len0 = strlen (__tzname[0]);
+    size_t len1 = strlen (__tzname[1]);
+    if (len0 > __tzname_cur_max)
+      __tzname_cur_max = len0;
+    if (len1 > __tzname_cur_max)
+      __tzname_cur_max = len1;
+  }
 }
 
 /* Figure out the exact time (as a time_t) in YEAR
@@ -509,21 +521,6 @@ tz_compute (tm)
 {
   compute_change (&tz_rules[0], 1900 + tm->tm_year);
   compute_change (&tz_rules[1], 1900 + tm->tm_year);
-
-  __daylight = tz_rules[0].offset != tz_rules[1].offset;
-  __timezone = -tz_rules[0].offset;
-  __tzname[0] = (char *) tz_rules[0].name;
-  __tzname[1] = (char *) tz_rules[1].name;
-
-  {
-    /* Keep __tzname_cur_max up to date.  */
-    size_t len0 = strlen (__tzname[0]);
-    size_t len1 = strlen (__tzname[1]);
-    if (len0 > __tzname_cur_max)
-      __tzname_cur_max = len0;
-    if (len1 > __tzname_cur_max)
-      __tzname_cur_max = len1;
-  }
 }
 
 /* Reinterpret the TZ environment variable and set `tzname'.  */


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]