summaryrefslogtreecommitdiff
path: root/time
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-10-17 20:24:59 +0000
committerJakub Jelinek <jakub@redhat.com>2007-10-17 20:24:59 +0000
commite2ff293ba10d38af29b08307d6bf90d11143596f (patch)
tree4f57da23acb1a50b8fcc4940d173195fd44d21d3 /time
parent378e8bab9688c447e7567b5066ef26482a4fd8f1 (diff)
Updated to fedora-glibc-20071017T2007
Diffstat (limited to 'time')
-rw-r--r--time/strftime_l.c70
-rw-r--r--time/tzfile.c76
-rw-r--r--time/tzset.c7
3 files changed, 107 insertions, 46 deletions
diff --git a/time/strftime_l.c b/time/strftime_l.c
index 0fd3f7764f..4a57b1599d 100644
--- a/time/strftime_l.c
+++ b/time/strftime_l.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -84,6 +84,7 @@ extern char *tzname[];
# include <stddef.h>
# include <stdlib.h>
# include <string.h>
+# include <stdbool.h>
#else
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy ((s), (d), (n))
@@ -453,27 +454,9 @@ static CHAR_T const month_name[][10] =
# define ut 0
#endif
-#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
- /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
- Work around this bug by copying *tp before it might be munged. */
- size_t _strftime_copytm (char *, size_t, const char *,
- const struct tm * ut_argument_spec_iso) __THROW;
- size_t
- my_strftime (s, maxsize, format, tp ut_argument)
- CHAR_T *s;
- size_t maxsize;
- const CHAR_T *format;
- const struct tm *tp;
- ut_argument_spec
- {
- struct tm tmcopy;
- tmcopy = *tp;
- return _strftime_copytm (s, maxsize, format, &tmcopy ut_argument);
- }
-# undef my_strftime
-# define my_strftime _strftime_copytm
-#endif
-
+static size_t __strftime_internal (CHAR_T *, size_t, const CHAR_T *,
+ const struct tm *, bool ut_argument_spec_iso
+ LOCALE_PARAM_PROTO) __THROW;
/* Write information from TP into S according to the format
string FORMAT, writing no more that MAXSIZE characters
@@ -481,12 +464,38 @@ static CHAR_T const month_name[][10] =
characters written. If S is NULL, nothing will be written
anywhere, so to determine how many characters would be
written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
+
size_t
my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
+ CHAR_T *s;
+ size_t maxsize;
+ const CHAR_T *format;
+ const struct tm *tp;
+ ut_argument_spec
+ LOCALE_PARAM_DECL
+{
+#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
+ /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
+ Work around this bug by copying *tp before it might be munged. */
+ struct tm tmcopy;
+ tmcopy = *tp;
+ tp = &tmcopy;
+#endif
+ return __strftime_internal (s, maxsize, format, tp, false
+ ut_argument LOCALE_ARG);
+}
+#ifdef _LIBC
+libc_hidden_def (my_strftime)
+#endif
+
+static size_t
+__strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
+ LOCALE_PARAM)
CHAR_T *s;
size_t maxsize;
const CHAR_T *format;
const struct tm *tp;
+ bool tzset_called;
ut_argument_spec
LOCALE_PARAM_DECL
{
@@ -559,7 +568,9 @@ my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
/* POSIX.1 requires that local time zone information is used as
though strftime called tzset. */
# if HAVE_TZSET
- tzset ();
+ if (!tzset_called)
+ tzset ();
+ tzset_called = true;
# endif
}
#endif
@@ -834,10 +845,12 @@ my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
subformat:
{
CHAR_T *old_start = p;
- size_t len = my_strftime (NULL, (size_t) -1, subfmt,
- tp ut_argument LOCALE_ARG);
- add (len, my_strftime (p, maxsize - i, subfmt,
- tp ut_argument LOCALE_ARG));
+ size_t len = __strftime_internal (NULL, (size_t) -1, subfmt,
+ tp, tzset_called ut_argument
+ LOCALE_ARG);
+ add (len, __strftime_internal (p, maxsize - i, subfmt,
+ tp, tzset_called ut_argument
+ LOCALE_ARG));
if (to_uppcase)
while (old_start < p)
@@ -1409,9 +1422,6 @@ my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
*p = L_('\0');
return i;
}
-#ifdef _LIBC
-libc_hidden_def (my_strftime)
-#endif
#ifdef emacs
diff --git a/time/tzfile.c b/time/tzfile.c
index 44d6614771..d19b7e9b4f 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -243,7 +243,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
& ~(__alignof__ (struct leap) - 1));
leaps_idx = total_size;
total_size += num_leaps * sizeof (struct leap);
- tzspec_len = (trans_width == 8
+ tzspec_len = (sizeof (time_t) == 8 && trans_width == 8
? st.st_size - (ftello (f)
+ num_transitions * (8 + 1)
+ num_types * 6
@@ -263,14 +263,14 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
types = (struct ttinfo *) ((char *) transitions + types_idx);
zone_names = (char *) types + num_types * sizeof (struct ttinfo);
leaps = (struct leap *) ((char *) transitions + leaps_idx);
- if (trans_width == 8)
- tzspec = (char *) leaps + num_leaps * sizeof (struct leap);
+ if (sizeof (time_t) == 8 && trans_width == 8)
+ tzspec = (char *) leaps + num_leaps * sizeof (struct leap) + extra;
else
tzspec = NULL;
if (extra > 0)
*extrap = (char *) &leaps[num_leaps];
- if (sizeof (time_t) == 4 || trans_width == 8)
+ if (sizeof (time_t) == 4 || __builtin_expect (trans_width == 8, 1))
{
if (__builtin_expect (fread_unlocked (transitions, trans_width + 1,
num_transitions, f)
@@ -371,15 +371,53 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
types[i++].isgmt = 0;
/* Read the POSIX TZ-style information if possible. */
- if (tzspec != NULL)
+ if (sizeof (time_t) == 8 && tzspec != NULL)
{
/* Skip over the newline first. */
if (getc_unlocked (f) != '\n'
- || fread_unlocked (tzspec, 1, tzspec_len - 1, f) != tzspec_len - 1)
+ || (fread_unlocked (tzspec, 1, tzspec_len - 1, f)
+ != tzspec_len - 1))
tzspec = NULL;
else
tzspec[tzspec_len - 1] = '\0';
}
+ else if (sizeof (time_t) == 4 && tzhead.tzh_version != '\0')
+ {
+ /* Get the TZ string. */
+ if (__builtin_expect (fread_unlocked ((void *) &tzhead, sizeof (tzhead),
+ 1, f) != 1, 0)
+ || (memcmp (tzhead.tzh_magic, TZ_MAGIC, sizeof (tzhead.tzh_magic))
+ != 0))
+ goto lose;
+
+ size_t num_transitions2 = (size_t) decode (tzhead.tzh_timecnt);
+ size_t num_types2 = (size_t) decode (tzhead.tzh_typecnt);
+ size_t chars2 = (size_t) decode (tzhead.tzh_charcnt);
+ size_t num_leaps2 = (size_t) decode (tzhead.tzh_leapcnt);
+ size_t num_isstd2 = (size_t) decode (tzhead.tzh_ttisstdcnt);
+ size_t num_isgmt2 = (size_t) decode (tzhead.tzh_ttisgmtcnt);
+
+ /* Position the stream before the second header. */
+ size_t to_skip = (num_transitions2 * (8 + 1)
+ + num_types2 * 6
+ + chars2
+ + num_leaps2 * 12
+ + num_isstd2
+ + num_isgmt2);
+ off_t off;
+ if (fseek (f, to_skip, SEEK_CUR) != 0
+ || (off = ftello (f)) < 0
+ || st.st_size < off + 2)
+ goto lose;
+
+ tzspec_len = st.st_size - off - 1;
+ char *tzstr = alloca (tzspec_len);
+ if (getc_unlocked (f) != '\n'
+ || (fread_unlocked (tzstr, 1, tzspec_len - 1, f) != tzspec_len - 1))
+ goto lose;
+ tzstr[tzspec_len - 1] = '\0';
+ tzspec = __tzstring (tzstr);
+ }
fclose (f);
@@ -561,7 +599,7 @@ __tzfile_compute (time_t timer, int use_localtime,
__tzname[0] = NULL;
__tzname[1] = NULL;
- if (num_transitions == 0 || timer < transitions[0])
+ if (__builtin_expect (num_transitions == 0 || timer < transitions[0], 0))
{
/* TIMER is before any transition (or there are no transitions).
Choose the first non-DST type
@@ -591,12 +629,12 @@ __tzfile_compute (time_t timer, int use_localtime,
++j;
}
}
- else if (timer >= transitions[num_transitions - 1])
+ else if (__builtin_expect (timer >= transitions[num_transitions - 1], 0))
{
- if (tzspec == NULL)
+ if (__builtin_expect (tzspec == NULL, 0))
{
use_last:
- i = num_transitions - 1;
+ i = num_transitions;
goto found;
}
@@ -605,12 +643,22 @@ __tzfile_compute (time_t timer, int use_localtime,
/* Convert to broken down structure. If this fails do not
use the string. */
- if (! __offtime (&timer, 0, tp))
+ if (__builtin_expect (! __offtime (&timer, 0, tp), 0))
goto use_last;
/* Use the rules from the TZ string to compute the change. */
__tz_compute (timer, tp, 1);
+ /* If tzspec comes from posixrules loaded by __tzfile_default,
+ override the STD and DST zone names with the ones user
+ requested in TZ envvar. */
+ if (__builtin_expect (zone_names == (char *) &leaps[num_leaps], 0))
+ {
+ assert (num_types == 2);
+ __tzname[0] = __tzstring (zone_names);
+ __tzname[1] = __tzstring (&zone_names[strlen (zone_names) + 1]);
+ }
+
*leap_correct = 0L;
*leap_hit = 0;
return;
@@ -666,7 +714,8 @@ __tzfile_compute (time_t timer, int use_localtime,
i = hi;
found:
- /* assert (timer >= transitions[i - 1] && timer < transitions[i]); */
+ /* assert (timer >= transitions[i - 1]
+ && (i == num_transitions || timer < transitions[i])); */
__tzname[types[type_idxs[i - 1]].isdst]
= __tzstring (&zone_names[types[type_idxs[i - 1]].idx]);
size_t j = i;
@@ -687,6 +736,9 @@ __tzfile_compute (time_t timer, int use_localtime,
++j;
}
+ if (__builtin_expect (__tzname[0] == NULL, 0))
+ __tzname[0] = __tzname[1];
+
i = type_idxs[i - 1];
}
diff --git a/time/tzset.c b/time/tzset.c
index 27efef0f7a..0d54202185 100644
--- a/time/tzset.c
+++ b/time/tzset.c
@@ -401,7 +401,7 @@ tzset_internal (always, explicit)
if (tz && *tz == ':')
++tz;
- /* Check whether the value changes since the last run. */
+ /* Check whether the value changed since the last run. */
if (old_tz != NULL && tz != NULL && strcmp (tz, old_tz) == 0)
/* No change, simply return. */
return;
@@ -606,9 +606,8 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
/* Update internal database according to current TZ setting.
POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname.
- This is a good idea since this allows at least a bit more parallelism.
- By analogy we apply the same rule to gmtime_r. */
- tzset_internal (tp == &_tmbuf, 0);
+ This is a good idea since this allows at least a bit more parallelism. */
+ tzset_internal (tp == &_tmbuf && use_localtime, 1);
if (__use_tzfile)
__tzfile_compute (*timer, use_localtime, &leap_correction,