about summary refs log tree commit diff
path: root/time/tzfile.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-07-31 13:33:18 +0000
committerJakub Jelinek <jakub@redhat.com>2007-07-31 13:33:18 +0000
commit32c075e1f01849e161724bbd400ba77244e482cc (patch)
tree5f083a3f352104f32bb6c902d57fa3f294bd8d4d /time/tzfile.c
parentd6220e9ee38c1c9285221b023346201ec5f511b3 (diff)
downloadglibc-32c075e1f01849e161724bbd400ba77244e482cc.tar.gz
glibc-32c075e1f01849e161724bbd400ba77244e482cc.tar.xz
glibc-32c075e1f01849e161724bbd400ba77244e482cc.zip
.
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.  */