diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-10-17 20:24:59 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2007-10-17 20:24:59 +0000 |
commit | e2ff293ba10d38af29b08307d6bf90d11143596f (patch) | |
tree | 4f57da23acb1a50b8fcc4940d173195fd44d21d3 /time | |
parent | 378e8bab9688c447e7567b5066ef26482a4fd8f1 (diff) |
Updated to fedora-glibc-20071017T2007
Diffstat (limited to 'time')
-rw-r--r-- | time/strftime_l.c | 70 | ||||
-rw-r--r-- | time/tzfile.c | 76 | ||||
-rw-r--r-- | time/tzset.c | 7 |
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, |