summaryrefslogtreecommitdiff
path: root/time/tzfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'time/tzfile.c')
-rw-r--r--time/tzfile.c114
1 files changed, 31 insertions, 83 deletions
diff --git a/time/tzfile.c b/time/tzfile.c
index ea2d7cae4c..e95fd55f36 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -1,5 +1,4 @@
-/* Copyright (C) 1991-1993,1995-2001,2003,2004,2006
- Free Software Foundation, Inc.
+/* Copyright (C) 1991-1993,1995-2001,2003,2004 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
@@ -72,34 +71,24 @@ static inline int
__attribute ((always_inline))
decode (const void *ptr)
{
- if (BYTE_ORDER == BIG_ENDIAN && sizeof (int) == 4)
+ if ((BYTE_ORDER == BIG_ENDIAN) && sizeof (int) == 4)
return *(const int *) ptr;
- if (sizeof (int) == 4)
+ else if (BYTE_ORDER == LITTLE_ENDIAN && sizeof (int) == 4)
return bswap_32 (*(const int *) ptr);
+ else
+ {
+ const unsigned char *p = ptr;
+ int result = *p & (1 << (CHAR_BIT - 1)) ? ~0 : 0;
- const unsigned char *p = ptr;
- int result = *p & (1 << (CHAR_BIT - 1)) ? ~0 : 0;
-
- result = (result << 8) | *p++;
- result = (result << 8) | *p++;
- result = (result << 8) | *p++;
- result = (result << 8) | *p++;
-
- return result;
-}
-
+ result = (result << 8) | *p++;
+ result = (result << 8) | *p++;
+ result = (result << 8) | *p++;
+ result = (result << 8) | *p++;
-static inline int64_t
-__attribute ((always_inline))
-decode64 (const void *ptr)
-{
- if ((BYTE_ORDER == BIG_ENDIAN))
- return *(const int64_t *) ptr;
-
- return bswap_64 (*(const int64_t *) ptr);
+ return result;
+ }
}
-
void
__tzfile_read (const char *file, size_t extra, char **extrap)
{
@@ -113,10 +102,6 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
size_t types_idx;
size_t leaps_idx;
int was_using_tzfile = __use_tzfile;
- int trans_width = 4;
-
- if (sizeof (time_t) != 4 && sizeof (time_t) != 8)
- abort ();
__use_tzfile = 0;
@@ -200,10 +185,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
/* No threads reading this stream. */
__fsetlocking (f, FSETLOCKING_BYCALLER);
- read_again:
if (__builtin_expect (fread_unlocked ((void *) &tzhead, sizeof (tzhead),
- 1, f) != 1, 0)
- || memcmp (tzhead.tzh_magic, TZ_MAGIC, sizeof (tzhead.tzh_magic)) != 0)
+ 1, f) != 1, 0))
goto lose;
num_transitions = (size_t) decode (tzhead.tzh_timecnt);
@@ -213,26 +196,6 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
num_isstd = (size_t) decode (tzhead.tzh_ttisstdcnt);
num_isgmt = (size_t) decode (tzhead.tzh_ttisgmtcnt);
- /* For platforms with 64-bit time_t we use the new format if available. */
- if (sizeof (time_t) == 8 && trans_width == 4
- && tzhead.tzh_version[0] != '\0')
- {
- /* We use the 8-byte format. */
- trans_width = 8;
-
- /* Position the stream before the second header. */
- size_t to_skip = (num_transitions * (4 + 1)
- + num_types * 6
- + chars
- + num_leaps * 8
- + num_isstd
- + num_isgmt);
- if (fseek (f, to_skip, SEEK_CUR) != 0)
- goto lose;
-
- goto read_again;
- }
-
total_size = num_transitions * (sizeof (time_t) + 1);
total_size = ((total_size + __alignof__ (struct ttinfo) - 1)
& ~(__alignof__ (struct ttinfo) - 1));
@@ -242,10 +205,10 @@ __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);
+ /* This is for the extra memory required by the caller. */
+ total_size += extra;
- /* Allocate enough memory including the extra block requested by the
- caller. */
- transitions = (time_t *) malloc (total_size + extra);
+ transitions = (time_t *) malloc (total_size);
if (transitions == NULL)
goto lose;
@@ -257,11 +220,14 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
if (extra > 0)
*extrap = (char *) &leaps[num_leaps];
- if (sizeof (time_t) == 4 || trans_width == 8)
+ if (sizeof (time_t) < 4)
+ abort ();
+
+ if (sizeof (time_t) == 4)
{
- if (__builtin_expect (fread_unlocked (transitions, trans_width + 1,
- num_transitions, f)
- != num_transitions, 0))
+ if (__builtin_expect (fread_unlocked (transitions, 1,
+ (4 + 1) * num_transitions, f)
+ != (4 + 1) * num_transitions, 0))
goto lose;
}
else
@@ -279,9 +245,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
if (__builtin_expect (type_idxs[i] >= num_types, 0))
goto lose;
- if ((BYTE_ORDER != BIG_ENDIAN && (sizeof (time_t) == 4 || trans_width == 4))
- || (BYTE_ORDER == BIG_ENDIAN && sizeof (time_t) == 8
- && trans_width == 4))
+ if (BYTE_ORDER != BIG_ENDIAN || sizeof (time_t) != 4)
{
/* Decode the transition times, stored as 4-byte integers in
network (big-endian) byte order. We work from the end of
@@ -291,13 +255,6 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
while (i-- > 0)
transitions[i] = decode ((char *) transitions + i * 4);
}
- else if (BYTE_ORDER != BIG_ENDIAN && sizeof (time_t) == 8)
- {
- /* Decode the transition times, stored as 8-byte integers in
- network (big-endian) byte order. */
- for (i = 0; i < num_transitions; ++i)
- transitions[i] = decode64 ((char *) transitions + i * 8);
- }
for (i = 0; i < num_types; ++i)
{
@@ -323,16 +280,13 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
for (i = 0; i < num_leaps; ++i)
{
- unsigned char x[8];
- if (__builtin_expect (fread_unlocked (x, 1, trans_width, f)
- != trans_width, 0))
+ unsigned char x[4];
+ if (__builtin_expect (fread_unlocked (x, 1, sizeof (x), f) != sizeof (x),
+ 0))
goto lose;
- if (sizeof (time_t) == 4 || trans_width == 4)
- leaps[i].transition = (time_t) decode (x);
- else
- leaps[i].transition = (time_t) decode64 (x);
-
- if (__builtin_expect (fread_unlocked (x, 1, 4, f) != 4, 0))
+ leaps[i].transition = (time_t) decode (x);
+ if (__builtin_expect (fread_unlocked (x, 1, sizeof (x), f) != sizeof (x),
+ 0))
goto lose;
leaps[i].change = (long int) decode (x);
}
@@ -357,12 +311,6 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
while (i < num_types)
types[i++].isgmt = 0;
- /* XXX When a version 2 file is available it can contain a POSIX TZ-style
- formatted string which specifies how times past the last one specified
- are supposed to be handled. We might want to handle this at some
- point. But it might be overhead since most/all? files have an
- open-ended last entry. */
-
fclose (f);
/* First "register" all timezone names. */