[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r3799 - in /fsf/trunk/libc: ./ intl/ libio/ nscd/ time/



Author: eglibc
Date: Sun Oct 14 00:03:34 2007
New Revision: 3799

Log:
Import glibc-mainline for 2007-10-14

Added:
    fsf/trunk/libc/libio/tst-ext2.c
Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/intl/dcigettext.c
    fsf/trunk/libc/libio/Makefile
    fsf/trunk/libc/libio/__freading.c
    fsf/trunk/libc/nscd/nscd_getai.c
    fsf/trunk/libc/nscd/nscd_getgr_r.c
    fsf/trunk/libc/nscd/nscd_gethst_r.c
    fsf/trunk/libc/nscd/nscd_getpw_r.c
    fsf/trunk/libc/nscd/nscd_getserv_r.c
    fsf/trunk/libc/nscd/nscd_helper.c
    fsf/trunk/libc/time/tzfile.c

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Sun Oct 14 00:03:34 2007
@@ -1,3 +1,46 @@
+2007-10-14  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	[BZ #1140]
+	* time/tzfile.c (__tzfile_compute): Compute tzname[] values based
+	on the specified time and not the last entries in the file.  Move
+	code to determine tzname[] to...
+	(find_transition): ...here.  Add ugly guess for times before the
+	first transition.
+
+2007-10-13  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	[BZ #3195]
+	* nscd/nscd_getai.c (__nscd_getai): Set errno to 0 in case we found
+	no entry.
+	* nscd/nscd_getgr.c (nscd_getgr_r): Likewise.
+	* nscd/nscd_gethst_r.c (nscd_gethst_r): Likewise.
+	* nscd/nscd_getpw_r.c (nscd_getpw_r): Likewise.
+	* nscd/nscd_getserv_r.c (nscd_getserv_r): Likewise.
+
+	* nscd/nscd_getgr_r.c (nscd_getgr_r): Optimize a bit: use simpler
+	read mechanism when there are no group members and avoid no-op
+	read syscall in this case.
+
+	[BZ #3242]
+	* nscd/nscd_helper.c (wait_on_socket): Take timeout as parameter.
+	(__readall): If reading failed due to EAGAIN error wait a bit
+	and possibly try again.
+	(__readvall): Likewise.
+
+2007-10-13  Bruno Haible  <bruno@xxxxxxxxx>
+
+	* intl/dcigettext.c (_nl_find_msg): Unlock the conversions_lock
+	when we cannot recode the message.
+
+2007-10-13  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	[BZ #4359]
+	* libio/__freading.c (__freading): Don't return true for
+	write-only streams.  For read/write streams, check whether we
+	performed a read operation already.
+	* libio/Makefile (tests): Add tst-ext2.
+	* libio/tst-ext2.c: New file.
+
 2007-10-12  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	* locale/programs/repertoire.c (repertoire_read): Always free

Modified: fsf/trunk/libc/intl/dcigettext.c
==============================================================================
--- fsf/trunk/libc/intl/dcigettext.c (original)
+++ fsf/trunk/libc/intl/dcigettext.c Sun Oct 14 00:03:34 2007
@@ -974,6 +974,7 @@
 			   translation at all.  */
 			if (__builtin_expect (r != __GCONV_NULCONV, 1))
 			  {
+			    __libc_rwlock_unlock (domain->conversions_lock);
 			    free ((char *) encoding);
 			    return NULL;
 			  }

Modified: fsf/trunk/libc/libio/Makefile
==============================================================================
--- fsf/trunk/libc/libio/Makefile (original)
+++ fsf/trunk/libc/libio/Makefile Sun Oct 14 00:03:34 2007
@@ -1,4 +1,4 @@
-# Copyright (C) 1995-2002,2003,2004,2006 Free Software Foundation, Inc.
+# Copyright (C) 1995-2002,2003,2004,2006,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
@@ -48,7 +48,7 @@
 	libc_fatal fmemopen
 
 tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
-	tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-fopenloc	      \
+	tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 tst-fopenloc \
 	tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf	      \
 	tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof          \
 	tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \

Modified: fsf/trunk/libc/libio/__freading.c
==============================================================================
--- fsf/trunk/libc/libio/__freading.c (original)
+++ fsf/trunk/libc/libio/__freading.c Sun Oct 14 00:03:34 2007
@@ -21,7 +21,7 @@
 int
 __freading (FILE *fp)
 {
-  return (((fp->_flags & _IO_NO_WRITES)
-	   || (fp->_flags & _IO_CURRENTLY_PUTTING) == 0)
-	  && (fp->_flags & _IO_NO_READS) == 0);
+  return ((fp->_flags & _IO_NO_WRITES)
+	  || ((fp->_flags & (_IO_CURRENTLY_PUTTING | _IO_NO_READS)) == 0
+	      && fp->_IO_read_base != NULL));
 }

Added: fsf/trunk/libc/libio/tst-ext2.c
==============================================================================
--- fsf/trunk/libc/libio/tst-ext2.c (added)
+++ fsf/trunk/libc/libio/tst-ext2.c Sun Oct 14 00:03:34 2007
@@ -1,0 +1,58 @@
+#include <stdio.h>
+#include <stdio_ext.h>
+
+
+static char *fname;
+
+#define PREPARE(argc, argv) \
+  do {									\
+    int fd = create_temp_file ("tst-ext2", &fname);			\
+    if (fd == -1)							\
+      {									\
+	puts ("cannot create temporary file");				\
+	exit (1);							\
+      }									\
+    close (fd);								\
+  } while (0)
+
+
+static int
+do_test (void)
+{
+  int res = 0;
+
+  FILE *fp;
+
+  fp = fopen (fname, "w");
+  printf ("Initial state for write-only stream: %d %d\n",
+          __freading (fp) != 0, __fwriting (fp) != 0);
+  res |= ((__freading (fp) != 0) != 0
+	  || (__fwriting (fp) != 0) != 1);
+  fclose (fp);
+
+  fp = fopen (fname, "r");
+  printf ("Initial state for read-only stream:  %d %d\n",
+          __freading (fp) != 0, __fwriting (fp) != 0);
+  res |= ((__freading (fp) != 0) != 1
+	  || (__fwriting (fp) != 0) != 0);
+  fclose (fp);
+
+  fp = fopen (fname, "r+");
+  printf ("Initial state for read-write stream: %d %d\n",
+          __freading (fp) != 0, __fwriting (fp) != 0);
+  res |= ((__freading (fp) != 0) != 0
+	  || (__fwriting (fp) != 0) != 0);
+  fclose (fp);
+
+  fp = fopen (fname, "w+");
+  printf ("Initial state for read-write stream: %d %d\n",
+          __freading (fp) != 0, __fwriting (fp) != 0);
+  res |= ((__freading (fp) != 0) != 0
+	  || (__fwriting (fp) != 0) != 0);
+  fclose (fp);
+
+  return res;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

Modified: fsf/trunk/libc/nscd/nscd_getai.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_getai.c (original)
+++ fsf/trunk/libc/nscd/nscd_getai.c Sun Oct 14 00:03:34 2007
@@ -168,8 +168,8 @@
       /* Store the error number.  */
       *h_errnop = ai_resp.error;
 
-      /* The `errno' to some value != ERANGE.  */
-      __set_errno (ENOENT);
+      /* Set errno to 0 to indicate no error, just no found record.  */
+      __set_errno (0);
       /* Even though we have not found anything, the result is zero.  */
       retval = 0;
     }

Modified: fsf/trunk/libc/nscd/nscd_getgr_r.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_getgr_r.c (original)
+++ fsf/trunk/libc/nscd/nscd_getgr_r.c Sun Oct 14 00:03:34 2007
@@ -190,26 +190,37 @@
       /* Read the length information, group name, and password.  */
       if (gr_name == NULL)
 	{
-	  /* Allocate array to store lengths.  */
-	  if (lensize == 0)
-	    {
-	      lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t);
-	      len = (uint32_t *) alloca (lensize);
-	    }
-	  else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize)
-	    len = extend_alloca (len, lensize,
-				 gr_resp.gr_mem_cnt * sizeof (uint32_t));
-
-	  vec[0].iov_base = (void *) len;
-	  vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t);
-	  vec[1].iov_base = resultbuf->gr_name;
-	  vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len;
-	  total_len = vec[0].iov_len + vec[1].iov_len;
-
-	  /* Get this data.  */
-	  size_t n = __readvall (sock, vec, 2);
-	  if (__builtin_expect (n != total_len, 0))
-	    goto out_close;
+	  /* Handle a simple, usual case: no group members.  */
+	  if (__builtin_expect (gr_resp.gr_mem_cnt == 0, 1))
+	    {
+	      size_t n = gr_resp.gr_name_len + gr_resp.gr_passwd_len;
+	      if (__builtin_expect (__readall (sock, resultbuf->gr_name, n)
+				    != (ssize_t) n, 0))
+		goto out_close;
+	    }
+	  else
+	    {
+	      /* Allocate array to store lengths.  */
+	      if (lensize == 0)
+		{
+		  lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t);
+		  len = (uint32_t *) alloca (lensize);
+		}
+	      else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize)
+		len = extend_alloca (len, lensize,
+				     gr_resp.gr_mem_cnt * sizeof (uint32_t));
+
+	      vec[0].iov_base = (void *) len;
+	      vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t);
+	      vec[1].iov_base = resultbuf->gr_name;
+	      vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len;
+	      total_len = vec[0].iov_len + vec[1].iov_len;
+
+	      /* Get this data.  */
+	      size_t n = __readvall (sock, vec, 2);
+	      if (__builtin_expect (n != total_len, 0))
+		goto out_close;
+	    }
 	}
       else
 	/* We already have the data.  Just copy the group name and
@@ -251,43 +262,48 @@
 	}
 
       retval = 0;
-      if (gr_name == NULL)
-	{
-	  size_t n = __readall (sock, resultbuf->gr_mem[0], total_len);
-	  if (__builtin_expect (n != total_len, 0))
-	    {
-	      /* The `errno' to some value != ERANGE.  */
-	      __set_errno (ENOENT);
-	      retval = ENOENT;
+
+      /* If there are no group members TOTAL_LEN is zero.  */
+      if (total_len > 0)
+	{
+	  if (gr_name == NULL)
+	    {
+	      size_t n = __readall (sock, resultbuf->gr_mem[0], total_len);
+	      if (__builtin_expect (n != total_len, 0))
+		{
+		  /* The `errno' to some value != ERANGE.  */
+		  __set_errno (ENOENT);
+		  retval = ENOENT;
+		}
+	      else
+		*result = resultbuf;
 	    }
 	  else
-	    *result = resultbuf;
-	}
-      else
-	{
-	  /* Copy the group member names.  */
-	  memcpy (resultbuf->gr_mem[0], gr_name + gr_name_len, total_len);
-
-	  /* Try to detect corrupt databases.  */
-	  if (resultbuf->gr_name[gr_name_len - 1] != '\0'
-	      || resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0'
-	      || ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt)
-		     if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0')
-		       break;
-	  	   cnt < gr_resp.gr_mem_cnt; }))
-	    {
-	      /* We cannot use the database.  */
-	      retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
-	      goto out_close;
-	    }
-
-	  *result = resultbuf;
+	    {
+	      /* Copy the group member names.  */
+	      memcpy (resultbuf->gr_mem[0], gr_name + gr_name_len, total_len);
+
+	      /* Try to detect corrupt databases.  */
+	      if (resultbuf->gr_name[gr_name_len - 1] != '\0'
+		  || resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0'
+		  || ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt)
+			if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0')
+			  break;
+		      cnt < gr_resp.gr_mem_cnt; }))
+		{
+		  /* We cannot use the database.  */
+		  retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
+		  goto out_close;
+		}
+
+	      *result = resultbuf;
+	    }
 	}
     }
   else
     {
-      /* The `errno' to some value != ERANGE.  */
-      __set_errno (ENOENT);
+      /* Set errno to 0 to indicate no error, just no found record.  */
+      __set_errno (0);
       /* Even though we have not found anything, the result is zero.  */
       retval = 0;
     }

Modified: fsf/trunk/libc/nscd/nscd_gethst_r.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_gethst_r.c (original)
+++ fsf/trunk/libc/nscd/nscd_gethst_r.c Sun Oct 14 00:03:34 2007
@@ -379,8 +379,8 @@
       /* Store the error number.  */
       *h_errnop = hst_resp.error;
 
-      /* The `errno' to some value != ERANGE.  */
-      __set_errno (ENOENT);
+      /* Set errno to 0 to indicate no error, just no found record.  */
+      __set_errno (0);
       /* Even though we have not found anything, the result is zero.  */
       retval = 0;
     }

Modified: fsf/trunk/libc/nscd/nscd_getpw_r.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_getpw_r.c (original)
+++ fsf/trunk/libc/nscd/nscd_getpw_r.c Sun Oct 14 00:03:34 2007
@@ -211,8 +211,8 @@
     }
   else
     {
-      /* The `errno' to some value != ERANGE.  */
-      __set_errno (ENOENT);
+      /* Set errno to 0 to indicate no error, just no found record.  */
+      __set_errno (0);
       /* Even though we have not found anything, the result is zero.  */
       retval = 0;
     }

Modified: fsf/trunk/libc/nscd/nscd_getserv_r.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_getserv_r.c (original)
+++ fsf/trunk/libc/nscd/nscd_getserv_r.c Sun Oct 14 00:03:34 2007
@@ -301,8 +301,8 @@
     }
   else
     {
-      /* The `errno' to some value != ERANGE.  */
-      __set_errno (ENOENT);
+      /* Set errno to 0 to indicate no error, just no found record.  */
+      __set_errno (0);
       /* Even though we have not found anything, the result is zero.  */
       retval = 0;
     }

Modified: fsf/trunk/libc/nscd/nscd_helper.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_helper.c (original)
+++ fsf/trunk/libc/nscd/nscd_helper.c Sun Oct 14 00:03:34 2007
@@ -38,6 +38,45 @@
 #include "nscd-client.h"
 
 
+/* Extra time we wait if the socket is still receiving data.  This
+   value is in milliseconds.  Note that the other side is nscd on the
+   local machine and it is already transmitting data.  So the wait
+   time need not be long.  */
+#define EXTRA_RECEIVE_TIME 200
+
+
+static int
+wait_on_socket (int sock, long int usectmo)
+{
+  struct pollfd fds[1];
+  fds[0].fd = sock;
+  fds[0].events = POLLIN | POLLERR | POLLHUP;
+  int n = __poll (fds, 1, usectmo);
+  if (n == -1 && __builtin_expect (errno == EINTR, 0))
+    {
+      /* Handle the case where the poll() call is interrupted by a
+	 signal.  We cannot just use TEMP_FAILURE_RETRY since it might
+	 lead to infinite loops.  */
+      struct timeval now;
+      (void) __gettimeofday (&now, NULL);
+      long int end = now.tv_sec * 1000 + usectmo + (now.tv_usec + 500) / 1000;
+      long int timeout = usectmo;
+      while (1)
+	{
+	  n = __poll (fds, 1, timeout);
+	  if (n != -1 || errno != EINTR)
+	    break;
+
+	  /* Recompute the timeout time.  */
+	  (void) __gettimeofday (&now, NULL);
+	  timeout = end - (now.tv_sec * 1000 + (now.tv_usec + 500) / 1000);
+	}
+    }
+
+  return n;
+}
+
+
 ssize_t
 __readall (int fd, void *buf, size_t len)
 {
@@ -45,9 +84,17 @@
   ssize_t ret;
   do
     {
+    again:
       ret = TEMP_FAILURE_RETRY (__read (fd, buf, n));
       if (ret <= 0)
-	break;
+	{
+	  if (__builtin_expect (ret < 0 && errno == EAGAIN, 0)
+	      /* The socket is still receiving data.  Wait a bit more.  */
+	      && wait_on_socket (fd, EXTRA_RECEIVE_TIME) > 0)
+	    goto again;
+
+	  break;
+	}
       buf = (char *) buf + ret;
       n -= ret;
     }
@@ -61,7 +108,15 @@
 {
   ssize_t ret = TEMP_FAILURE_RETRY (__readv (fd, iov, iovcnt));
   if (ret <= 0)
-    return ret;
+    {
+      if (__builtin_expect (ret == 0 || errno != EAGAIN, 1))
+	/* A genuine error or no data to read.  */
+	return ret;
+
+      /* The data has not all yet been received.  Do as if we have not
+	 read anything yet.  */
+      ret = 0;
+    }
 
   size_t total = 0;
   for (int i = 0; i < iovcnt; ++i)
@@ -83,9 +138,17 @@
 	    }
 	  iovp->iov_base = (char *) iovp->iov_base + r;
 	  iovp->iov_len -= r;
+	again:
 	  r = TEMP_FAILURE_RETRY (__readv (fd, iovp, iovcnt));
 	  if (r <= 0)
-	    break;
+	    {
+	      if (__builtin_expect (r < 0 && errno == EAGAIN, 0)
+		  /* The socket is still receiving data.  Wait a bit more.  */
+		  && wait_on_socket (fd, EXTRA_RECEIVE_TIME) > 0)
+		goto again;
+
+	      break;
+	    }
 	  ret += r;
 	}
       while (ret < total);
@@ -187,36 +250,6 @@
 }
 
 
-static int
-wait_on_socket (int sock)
-{
-  struct pollfd fds[1];
-  fds[0].fd = sock;
-  fds[0].events = POLLIN | POLLERR | POLLHUP;
-  int n = __poll (fds, 1, 5 * 1000);
-  if (n == -1 && __builtin_expect (errno == EINTR, 0))
-    {
-      /* Handle the case where the poll() call is interrupted by a
-	 signal.  We cannot just use TEMP_FAILURE_RETRY since it might
-	 lead to infinite loops.  */
-      struct timeval now;
-      (void) __gettimeofday (&now, NULL);
-      long int end = (now.tv_sec + 5) * 1000 + (now.tv_usec + 500) / 1000;
-      while (1)
-	{
-	  long int timeout = end - (now.tv_sec * 1000
-				    + (now.tv_usec + 500) / 1000);
-	  n = __poll (fds, 1, timeout);
-	  if (n != -1 || errno != EINTR)
-	    break;
-	  (void) __gettimeofday (&now, NULL);
-	}
-    }
-
-  return n;
-}
-
-
 /* Try to get a file descriptor for the shared meory segment
    containing the database.  */
 static struct mapped_database *
@@ -265,7 +298,7 @@
 
   msg.msg_controllen = cmsg->cmsg_len;
 
-  if (wait_on_socket (sock) <= 0)
+  if (wait_on_socket (sock, 5 * 1000) <= 0)
     goto out_close2;
 
 # ifndef MSG_CMSG_CLOEXEC
@@ -497,7 +530,7 @@
   if (sock >= 0)
     {
       /* Wait for data.  */
-      if (wait_on_socket (sock) > 0)
+      if (wait_on_socket (sock, 5 * 1000) > 0)
 	{
 	  ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, response,
 						       responselen));

Modified: fsf/trunk/libc/time/tzfile.c
==============================================================================
--- fsf/trunk/libc/time/tzfile.c (original)
+++ fsf/trunk/libc/time/tzfile.c Sun Oct 14 00:03:34 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1993,1995-2001,2003,2004,2006
+/* Copyright (C) 1991-1993,1995-2001,2003,2004,2006, 2007
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -50,7 +50,6 @@
     long int change;		/* Seconds of correction to apply.  */
   };
 
-static struct ttinfo *find_transition (time_t timer) internal_function;
 static void compute_tzname_max (size_t) internal_function;
 
 static size_t num_transitions;
@@ -537,6 +536,9 @@
 {
   size_t i;
 
+  __tzname[0] = NULL;
+  __tzname[1] = NULL;
+
   if (num_transitions == 0 || timer < transitions[0])
     {
       /* TIMER is before any transition (or there are no transitions).
@@ -544,12 +546,34 @@
 	 (or the first if they're all DST types).  */
       i = 0;
       while (i < num_types && types[i].isdst)
-	++i;
+	{
+	  if (__tzname[1] == NULL)
+	    __tzname[1] = __tzstring (&zone_names[types[i].idx]);
+
+	  ++i;
+	}
+
       if (i == num_types)
 	i = 0;
+      __tzname[0] = __tzstring (&zone_names[types[i].idx]);
+      if (__tzname[1] == NULL)
+	{
+	  size_t j = i;
+	  while (j < num_types)
+	    if (types[j].isdst)
+	      {
+		__tzname[1] = __tzstring (&zone_names[types[j].idx]);
+		break;
+	      }
+	    else
+	      ++j;
+	}
     }
   else if (timer >= transitions[num_transitions - 1])
-    i = type_idxs[num_transitions - 1];
+    {
+      i = num_transitions - 1;
+      goto found;
+    }
   else
     {
       /* Find the first transition after TIMER, and
@@ -602,6 +626,26 @@
 
     found:
       /* assert (timer >= transitions[i - 1] && timer < transitions[i]); */
+      __tzname[types[type_idxs[i - 1]].isdst]
+	= __tzstring (&zone_names[types[type_idxs[i - 1]].idx]);
+      size_t j = i;
+      while (j < num_transitions)
+	{
+	  int type = type_idxs[j];
+	  int dst = types[type].isdst;
+	  int idx = types[type].idx;
+
+	  if (__tzname[dst] == NULL)
+	    {
+	      __tzname[dst] = __tzstring (&zone_names[idx]);
+
+	      if (__tzname[1 - dst] != NULL)
+		break;
+	    }
+
+	  ++j;
+	}
+
       i = type_idxs[i - 1];
     }
 
@@ -620,22 +664,7 @@
       struct ttinfo *info = find_transition (timer);
       __daylight = rule_stdoff != rule_dstoff;
       __timezone = -rule_stdoff;
-      __tzname[0] = NULL;
-      __tzname[1] = NULL;
-      for (i = num_transitions; i > 0; )
-	{
-	  int type = type_idxs[--i];
-	  int dst = types[type].isdst;
-	  int idx = types[type].idx;
-
-	  if (__tzname[dst] == NULL)
-	    {
-	      __tzname[dst] = __tzstring (&zone_names[idx]);
-
-	      if (__tzname[1 - dst] != NULL)
-		break;
-	    }
-	}
+
       if (__tzname[0] == NULL)
 	{
 	  /* This should only happen if there are no transition rules.
@@ -647,7 +676,8 @@
 	/* There is no daylight saving time.  */
 	__tzname[1] = __tzname[0];
       tp->tm_isdst = info->isdst;
-      tp->tm_zone = __tzstring (&zone_names[info->idx]);
+      assert (strcmp (&zone_names[info->idx], __tzname[tp->tm_isdst]) == 0);
+      tp->tm_zone = __tzname[tp->tm_isdst];
       tp->tm_gmtoff = info->offset;
     }