[PATCH] Another tzset.c issue
Jakub Jelinek
jakub@redhat.com
Wed Mar 6 14:48:00 GMT 2002
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
More information about the Libc-hacker
mailing list