Updated to fedora-glibc-20071014T1847
authorjakub <jakub>
Sun, 14 Oct 2007 20:56:49 +0000 (20:56 +0000)
committerjakub <jakub>
Sun, 14 Oct 2007 20:56:49 +0000 (20:56 +0000)
29 files changed:
ChangeLog
elf/cache.c
fedora/branch.mk
fedora/glibc.spec.in
iconv/gconv_simple.c
include/features.h
include/stdio.h
include/time.h
intl/dcigettext.c
libio/Makefile
libio/__freading.c
libio/ftello.c
libio/tst-ext2.c [new file with mode: 0644]
locale/programs/ld-collate.c
locale/programs/repertoire.c
misc/Makefile
nscd/nscd_getai.c
nscd/nscd_getgr_r.c
nscd/nscd_gethst_r.c
nscd/nscd_getpw_r.c
nscd/nscd_getserv_r.c
nscd/nscd_helper.c
posix/fnmatch_loop.c
posix/regcomp.c
posix/regexec.c
sysdeps/posix/getaddrinfo.c
time/tzfile.c
time/tzset.c
timezone/tst-timezone.c

index b9a90cd..619b6f2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,101 @@
+2007-10-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/posix/getaddrinfo.c (struct sort_result): Add
+       service_order.
+       (rfc3484_sort): Make sure that even of qsort doesn't support
+       stable sorting it is stable by comparing service_order.
+       (getaddrinfo): Initialize service_order.
+
+       * include/time.h: Declare __tzset_parse_tz and __tzset_compute.
+       * time/tzset.c (tzset_internal): Break TZ string parsing out into
+       __tzset_parse_tz and updating of daylight, timezone, tzname into
+       update_vars.
+       (__tz_compute): Renamed from tz_compute.  Take additional parameters.
+       (__tz_convert): Updating of tm_isdst, tm_zone, and tm_gmtoff now
+       happens in __tz_compute.
+       * time/tzfile.c (__tzfile_read): Also read TZ string.
+       (find_transition): Fold into __tzfile_compute.
+       (__tzfile_compute): For times beyond the last transition try to
+       use the TZ string.
+       * timezone/tst-timezone.c: Information in daylight and tzname does
+       change for Asia/Tokyo timezone with more concrete information.
+       Remove the test.
+
+       * include/stdio.h: Add libc_hidden_proto for ftello.
+       * libio/ftello.c: Add libc_hidden_def.
+
+       [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@redhat.com>
+
+       [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@clisp.org>
+
+       * intl/dcigettext.c (_nl_find_msg): Unlock the conversions_lock
+       when we cannot recode the message.
+
+2007-10-13  Ulrich Drepper  <drepper@redhat.com>
+
+       [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@redhat.com>
+
+       * locale/programs/repertoire.c (repertoire_read): Always free
+       memory for repertoire file name [Coverity CID 270].
+
+       * elf/cache.c (save_aux_cache): Free memory allocated for
+       temporary file name [Coverity CID 267].
+
+2007-10-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * misc/Makefile (headers): Add bits/error.h.
+
+2007-10-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * posix/fnmatch_loop.c: Take rule index returned as part of
+       findidx return value into account when accessing weights.
+       * posix/regcomp.c: Likewise.
+       * posix/regexec.c: Likewise.
+
+       * locale/programs/ld-collate.c (collate_read): Optimize a bit.
+       (skip_to): Fix problems with parameter of elifdef/elifndef.
+
+2007-10-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * iconv/gconv_simple.c: Add some branch prediction.
+
+2007-10-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * locale/programs/ld-collate.c (collate_read): If ignore_content
+       and nowtok is tok_define, eat any tok_eol tokens.
+
 2007-10-11  Jakub Jelinek  <jakub@redhat.com>
 
        * sysdeps/gnu/netinet/tcp.h: Include sys/socket.h if __USE_MISC.
index 9a600ea..b8561e4 100644 (file)
@@ -800,5 +800,6 @@ save_aux_cache (const char *aux_cache_name)
 
 out_fail:
   /* Free allocated memory.  */
+  free (temp_name);
   free (file_entries);
 }
index ac6349e..c905679 100644 (file)
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-f8
-fedora-sync-date := 2007-10-11 16:36 UTC
-fedora-sync-tag := fedora-glibc-20071011T1636
+fedora-sync-date := 2007-10-14 18:47 UTC
+fedora-sync-tag := fedora-glibc-20071014T1847
index 11d7d0e..084231c 100644 (file)
@@ -1,4 +1,4 @@
-%define glibcrelease 19
+%define glibcrelease 20
 %define run_glibc_tests 1
 %define auxarches i586 i686 athlon sparcv9v sparc64v alphaev6
 %define xenarches i686 athlon
@@ -1010,6 +1010,12 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Sun Oct 14 2007 Jakub Jelinek <jakub@redhat.com> 2.6.90-20
+- install <bits/error.h> (#330031)
+- disable -D_FORTIFY_SOURCE{,=2} support (with a warning) for
+  GCC 3.4.x and earlier(#327641)
+- misc fixes (BZ#1140, BZ#3195, BZ#3242, BZ#4359)
+
 * Thu Oct 11 2007 Jakub Jelinek <jakub@redhat.com> 2.6.90-19
 - fix <netinet/tcp.h>
 - simple preprocessor in localedef, fix de_DE collation with it
index 343c275..ec8f38a 100644 (file)
@@ -1,5 +1,5 @@
 /* Simple transformations functions.
-   Copyright (C) 1997-2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1997-2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -880,7 +880,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step,
   {                                                                          \
     uint32_t wc = *((const uint32_t *) inptr);                               \
                                                                              \
-    if (wc < 0x80)                                                           \
+    if (__builtin_expect (wc < 0x80, 1))                                     \
       /* It's an one byte sequence.  */                                              \
       *outptr++ = (unsigned char) wc;                                        \
     else if (__builtin_expect (wc <= 0x7fffffff, 1))                         \
@@ -940,21 +940,19 @@ ucs4le_internal_loop_single (struct __gconv_step *step,
 #define LOOPFCT                        FROM_LOOP
 #define BODY \
   {                                                                          \
-    uint32_t ch;                                                             \
-    uint_fast32_t cnt;                                                       \
-    uint_fast32_t i;                                                         \
-                                                                             \
     /* Next input byte.  */                                                  \
-    ch = *inptr;                                                             \
+    uint32_t ch = *inptr;                                                    \
                                                                              \
-    if (ch < 0x80)                                                           \
+    if (__builtin_expect (ch < 0x80, 1))                                     \
       {                                                                              \
        /* One byte sequence.  */                                             \
-       cnt = 1;                                                              \
        ++inptr;                                                              \
       }                                                                              \
     else                                                                     \
       {                                                                              \
+       uint_fast32_t cnt;                                                    \
+       uint_fast32_t i;                                                      \
+                                                                             \
        if (ch >= 0xc2 && ch < 0xe0)                                          \
          {                                                                   \
            /* We expect two bytes.  The first byte cannot be 0xc0 or 0xc1,   \
index 0e47187..3ab68b6 100644 (file)
 #endif
 
 #if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0 \
-    && defined __OPTIMIZE__ && __OPTIMIZE__ > 0 \
-    && (__GNUC_PREREQ (4, 1) \
-        || (defined __GNUC_RH_RELEASE__ && __GNUC_PREREQ (4, 0)) \
-        || (defined __GNUC_RH_RELEASE__ && __GNUC_PREREQ (3, 4) \
-            && __GNUC_MINOR__ == 4 \
-            && (__GNUC_PATCHLEVEL__ > 2 \
-                || (__GNUC_PATCHLEVEL__ == 2 && __GNUC_RH_RELEASE__ >= 8))))
-# if _FORTIFY_SOURCE > 1
+    && defined __OPTIMIZE__ && __OPTIMIZE__ > 0
+# if !__GNUC_PREREQ (4, 1)
+#  ifdef __GNUC_RH_RELEASE__
+#   warning _FORTIFY_SOURCE supported only with GCC 4.1 and later
+#  endif
+#  define __USE_FORTIFY_LEVEL 0
+# elif _FORTIFY_SOURCE > 1
 #  define __USE_FORTIFY_LEVEL 2
 # else
 #  define __USE_FORTIFY_LEVEL 1
index 084c02e..3c11037 100644 (file)
@@ -138,6 +138,7 @@ libc_hidden_proto (rewind)
 libc_hidden_proto (fileno)
 libc_hidden_proto (fwrite)
 libc_hidden_proto (fseek)
+libc_hidden_proto (ftello)
 libc_hidden_proto (fflush_unlocked)
 libc_hidden_proto (fread_unlocked)
 libc_hidden_proto (fwrite_unlocked)
index ed6cb36..e896406 100644 (file)
@@ -46,6 +46,9 @@ extern void __tzfile_compute (time_t timer, int use_localtime,
                              struct tm *tp);
 extern void __tzfile_default (const char *std, const char *dst,
                              long int stdoff, long int dstoff);
+extern void __tzset_parse_tz (const char *tz);
+extern void __tz_compute (time_t timer, struct tm *tm, int use_localtime)
+     __THROW internal_function;
 
 /* Subroutine of `mktime'.  Return the `time_t' representation of TP and
    normalize TP, given that a `struct tm *' maps to a `time_t' as performed
index 55dcaab..a2cd801 100644 (file)
@@ -974,6 +974,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
                           translation at all.  */
                        if (__builtin_expect (r != __GCONV_NULCONV, 1))
                          {
+                           __libc_rwlock_unlock (domain->conversions_lock);
                            free ((char *) encoding);
                            return NULL;
                          }
index 553fbda..31fac70 100644 (file)
@@ -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 @@ routines      :=                                                            \
        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 \
index 37200bb..43e50bc 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2002, 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
@@ -22,5 +22,6 @@ int
 __freading (FILE *fp)
 {
   return ((fp->_flags & _IO_NO_WRITES)
-         || (fp->_flags & _IO_CURRENTLY_PUTTING) == 0);
+         || ((fp->_flags & (_IO_CURRENTLY_PUTTING | _IO_NO_READS)) == 0
+             && fp->_IO_read_base != NULL));
 }
index e58daac..d250e55 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995-2001, 2002, 2003, 2004
+/* Copyright (C) 1993, 1995-2001, 2002, 2003, 2004, 2007
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -63,3 +63,4 @@ ftello (fp)
     }
   return pos;
 }
+libc_hidden_def (ftello)
diff --git a/libio/tst-ext2.c b/libio/tst-ext2.c
new file mode 100644 (file)
index 0000000..ed72efa
--- /dev/null
@@ -0,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"
index 6d8f3fb..bf22a2c 100644 (file)
@@ -2662,13 +2662,16 @@ skip_to (struct linereader *ldfile, struct locale_collate_t *collate,
          if (nowtok == tok_eof || nowtok == tok_end)
            return nowtok;
        }
-      else if ((!to_endif && (nowtok == tok_else || nowtok == tok_elifdef
-                             || nowtok == tok_elifndef))
-              || nowtok == tok_endif)
+      else if (nowtok == tok_endif || (!to_endif && nowtok == tok_else))
        {
          lr_ignore_rest (ldfile, 1);
          return nowtok;
        }
+      else if (!to_endif && (nowtok == tok_elifdef || nowtok == tok_elifndef))
+       {
+         /* Do not read the rest of the line.  */
+         return nowtok;
+       }
       else if (nowtok == tok_else)
        {
          lr_error (ldfile, _("%s: more then one 'else'"), "LC_COLLATE");
@@ -2709,43 +2712,38 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
   /* The rest of the line containing `LC_COLLATE' must be free.  */
   lr_ignore_rest (ldfile, 1);
 
-  do
-    {
-      now = lr_token (ldfile, charmap, result, NULL, verbose);
-      nowtok = now->tok;
-    }
-  while (nowtok == tok_eol);
-
-  while (nowtok == tok_define)
+  while (1)
     {
-      if (ignore_content)
+      do
        {
-         lr_ignore_rest (ldfile, 0);
-         continue;
+         now = lr_token (ldfile, charmap, result, NULL, verbose);
+         nowtok = now->tok;
        }
+      while (nowtok == tok_eol);
 
-      arg = lr_token (ldfile, charmap, result, NULL, verbose);
-      if (arg->tok != tok_ident)
-       SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE");
+      if (nowtok != tok_define)
+       break;
+
+      if (ignore_content)
+       lr_ignore_rest (ldfile, 0);
       else
        {
-         /* Simply add the new symbol.  */
-         struct name_list *newsym = xmalloc (sizeof (*newsym)
-                                         + arg->val.str.lenmb + 1);
-         memcpy (newsym->str, arg->val.str.startmb, arg->val.str.lenmb);
-         newsym->str[arg->val.str.lenmb] = '\0';
-         newsym->next = defined;
-         defined = newsym;
-
-         lr_ignore_rest (ldfile, 1);
-       }
+         arg = lr_token (ldfile, charmap, result, NULL, verbose);
+         if (arg->tok != tok_ident)
+           SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE");
+         else
+           {
+             /* Simply add the new symbol.  */
+             struct name_list *newsym = xmalloc (sizeof (*newsym)
+                                                 + arg->val.str.lenmb + 1);
+             memcpy (newsym->str, arg->val.str.startmb, arg->val.str.lenmb);
+             newsym->str[arg->val.str.lenmb] = '\0';
+             newsym->next = defined;
+             defined = newsym;
 
-      do
-       {
-         now = lr_token (ldfile, charmap, result, NULL, verbose);
-         nowtok = now->tok;
+             lr_ignore_rest (ldfile, 1);
+           }
        }
-      while (nowtok == tok_eol);
     }
 
   if (nowtok == tok_copy)
index cc83374..366580e 100644 (file)
@@ -113,8 +113,7 @@ repertoire_read (const char *filename)
                      filename);
              repfile = lr_open (buf, repertoiremap_hash);
 
-             if (repfile == NULL)
-               free (buf);
+             free (buf);
            }
        }
 
index a9709f9..eb97ac1 100644 (file)
@@ -31,7 +31,7 @@ headers       := sys/uio.h bits/uio.h sys/ioctl.h bits/ioctls.h bits/ioctl-types.h \
           sys/select.h ustat.h sys/ustat.h bits/ustat.h sys/sysinfo.h \
           regexp.h bits/select.h bits/mman.h sys/xattr.h \
           syslog.h sys/syslog.h \
-          bits/syslog.h bits/syslog-ldbl.h bits/syslog-path.h
+          bits/syslog.h bits/syslog-ldbl.h bits/syslog-path.h bits/error.h
 
 routines := brk sbrk sstk ioctl \
            readv writev \
index 5df32dc..56f9637 100644 (file)
@@ -168,8 +168,8 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
       /* 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;
     }
index fc036f2..afb4d20 100644 (file)
@@ -190,26 +190,37 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
       /* Read the length information, group name, and password.  */
       if (gr_name == NULL)
        {
-         /* Allocate array to store lengths.  */
-         if (lensize == 0)
+         /* Handle a simple, usual case: no group members.  */
+         if (__builtin_expect (gr_resp.gr_mem_cnt == 0, 1))
            {
-             lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t);
-             len = (uint32_t *) alloca (lensize);
+             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 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,17 +262,22 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
        }
 
       retval = 0;
+
+      /* If there are no group members TOTAL_LEN is zero.  */
       if (gr_name == NULL)
        {
-         size_t n = __readall (sock, resultbuf->gr_mem[0], total_len);
-         if (__builtin_expect (n != total_len, 0))
+         if (total_len > 0)
            {
-             /* The `errno' to some value != ERANGE.  */
-             __set_errno (ENOENT);
-             retval = ENOENT;
+             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
        {
@@ -272,9 +288,9 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
          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; }))
+                   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;
@@ -286,8 +302,8 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
     }
   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;
     }
index 03b73a4..a211404 100644 (file)
@@ -379,8 +379,8 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
       /* 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;
     }
index b84baa1..21f792b 100644 (file)
@@ -211,8 +211,8 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
     }
   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;
     }
index a725b1d..3cd5a24 100644 (file)
@@ -301,8 +301,8 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
     }
   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;
     }
index 6718d92..8665352 100644 (file)
 #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 @@ __readall (int fd, void *buf, size_t len)
   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 @@ __readvall (int fd, const struct iovec *iov, int iovcnt)
 {
   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 @@ __readvall (int fd, const struct iovec *iov, int iovcnt)
            }
          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 @@ __nscd_unmap (struct mapped_database *mapped)
 }
 
 
-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 @@ get_mapping (request_type type, const char *key,
 
   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 @@ __nscd_open_socket (const char *key, size_t keylen, request_type type,
   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));
index 2bdd837..67c0ee4 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2003,2004,2005,
-   2007 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1993,1996-2001,2003-2005,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
@@ -418,15 +418,20 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends)
                            /* We found a table entry.  Now see whether the
                               character we are currently at has the same
                               equivalance class value.  */
-                           int len = weights[idx];
+                           int len = weights[idx & 0xffffff];
                            int32_t idx2;
                            const UCHAR *np = (const UCHAR *) n;
 
                            idx2 = findidx (&np);
-                           if (idx2 != 0 && len == weights[idx2])
+                           if (idx2 != 0
+                               && (idx >> 24) == (idx2 >> 24)
+                               && len == weights[idx2 & 0xffffff])
                              {
                                int cnt = 0;
 
+                               idx &= 0xffffff;
+                               idx2 &= 0xffffff;
+
                                while (cnt < len
                                       && (weights[idx + 1 + cnt]
                                           == weights[idx2 + 1 + cnt]))
index 129546c..4cf1688 100644 (file)
@@ -3378,7 +3378,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
 
       /* Build single byte matcing table for this equivalence class.  */
       char_buf[1] = (unsigned char) '\0';
-      len = weights[idx1];
+      len = weights[idx1 & 0xffffff];
       for (ch = 0; ch < SBC_MAX; ++ch)
        {
          char_buf[0] = ch;
@@ -3390,11 +3390,15 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
          if (idx2 == 0)
            /* This isn't a valid character.  */
            continue;
-         if (len == weights[idx2])
+         /* Compare only if the length matches and the collation rule
+            index is the same.  */
+         if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24))
            {
              int cnt = 0;
+
              while (cnt <= len &&
-                    weights[idx1 + 1 + cnt] == weights[idx2 + 1 + cnt])
+                    weights[(idx1 & 0xffffff) + 1 + cnt]
+                    == weights[(idx2 & 0xffffff) + 1 + cnt])
                ++cnt;
 
              if (cnt > len)
index bdfa355..135efe7 100644 (file)
@@ -1,5 +1,5 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
 
@@ -3825,7 +3825,6 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
          const int32_t *table, *indirect;
          const unsigned char *weights, *extra;
          const char *collseqwc;
-         int32_t idx;
          /* This #include defines a local function!  */
 #  include <locale/weight.h>
 
@@ -3883,15 +3882,20 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
                _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
              indirect = (const int32_t *)
                _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
-             idx = findidx (&cp);
+             int32_t idx = findidx (&cp);
              if (idx > 0)
                for (i = 0; i < cset->nequiv_classes; ++i)
                  {
                    int32_t equiv_class_idx = cset->equiv_classes[i];
-                   size_t weight_len = weights[idx];
-                   if (weight_len == weights[equiv_class_idx])
+                   size_t weight_len = weights[idx & 0xffffff];
+                   if (weight_len == weights[equiv_class_idx & 0xffffff]
+                       && (idx >> 24) == (equiv_class_idx >> 24))
                      {
                        int cnt = 0;
+
+                       idx &= 0xffffff;
+                       equiv_class_idx &= 0xffffff;
+
                        while (cnt <= weight_len
                               && (weights[equiv_class_idx + 1 + cnt]
                                   == weights[idx + 1 + cnt]))
index 221b41d..8f37ec5 100644 (file)
@@ -1002,6 +1002,7 @@ struct sort_result
 {
   struct addrinfo *dest_addr;
   struct sockaddr_storage source_addr;
+  size_t service_order;
   uint8_t source_addr_len;
   bool got_source_addr;
   uint8_t source_addr_flags;
@@ -1403,8 +1404,11 @@ rfc3484_sort (const void *p1, const void *p2)
     }
 
 
-  /* Rule 10: Otherwise, leave the order unchanged.  */
-  return 0;
+  /* Rule 10: Otherwise, leave the order unchanged.  To ensure this
+     compare with the value indicating the order in which the entries
+     have been received from the services.  NB: no two entries can have
+     the same order so the test will never return zero.  */
+  return a1->service_order < a2->service_order ? -1 : 1;
 }
 
 
@@ -1951,6 +1955,7 @@ getaddrinfo (const char *name, const char *service,
        {
          results[i].dest_addr = q;
          results[i].got_source_addr = false;
+         results[i].service_order = i;
 
          /* If we just looked up the address for a different
             protocol, reuse the result.  */
index 0d48c8c..44d6614 100644 (file)
@@ -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 @@ struct leap
     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;
@@ -63,6 +62,7 @@ static long int rule_stdoff;
 static long int rule_dstoff;
 static size_t num_leaps;
 static struct leap *leaps;
+static char *tzspec;
 
 #include <endian.h>
 #include <byteswap.h>
@@ -114,6 +114,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
   size_t leaps_idx;
   int was_using_tzfile = __use_tzfile;
   int trans_width = 4;
+  size_t tzspec_len;
 
   if (sizeof (time_t) != 4 && sizeof (time_t) != 8)
     abort ();
@@ -242,10 +243,18 @@ __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
+               ? st.st_size - (ftello (f)
+                               + num_transitions * (8 + 1)
+                               + num_types * 6
+                               + chars
+                               + num_leaps * 8
+                               + num_isstd
+                               + num_isgmt) - 1 : 0);
 
   /* Allocate enough memory including the extra block requested by the
      caller.  */
-  transitions = (time_t *) malloc (total_size + extra);
+  transitions = (time_t *) malloc (total_size + tzspec_len + extra);
   if (transitions == NULL)
     goto lose;
 
@@ -254,6 +263,10 @@ __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);
+  else
+    tzspec = NULL;
   if (extra > 0)
     *extrap = (char *) &leaps[num_leaps];
 
@@ -357,11 +370,16 @@ __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.  */
+  /* Read the POSIX TZ-style information if possible.  */
+  if (tzspec != NULL)
+    {
+      /* Skip over the newline first.  */
+      if (getc_unlocked (f) != '\n'
+         || fread_unlocked (tzspec, 1, tzspec_len - 1, f) != tzspec_len - 1)
+       tzspec = NULL;
+      else
+       tzspec[tzspec_len - 1] = '\0';
+    }
 
   fclose (f);
 
@@ -531,111 +549,151 @@ __tzfile_default (const char *std, const char *dst,
   compute_tzname_max (stdlen + dstlen);
 }
 \f
-static struct ttinfo *
-internal_function
-find_transition (time_t timer)
+void
+__tzfile_compute (time_t timer, int use_localtime,
+                 long int *leap_correct, int *leap_hit,
+                 struct tm *tp)
 {
-  size_t i;
+  register size_t i;
 
-  if (num_transitions == 0 || timer < transitions[0])
-    {
-      /* TIMER is before any transition (or there are no transitions).
-        Choose the first non-DST type
-        (or the first if they're all DST types).  */
-      i = 0;
-      while (i < num_types && types[i].isdst)
-       ++i;
-      if (i == num_types)
-       i = 0;
-    }
-  else if (timer >= transitions[num_transitions - 1])
-    i = type_idxs[num_transitions - 1];
-  else
+  if (use_localtime)
     {
-      /* Find the first transition after TIMER, and
-        then pick the type of the transition before it.  */
-      size_t lo = 0;
-      size_t hi = num_transitions - 1;
-      /* Assume that DST is changing twice a year and guess initial
-        search spot from it.
-        Half of a gregorian year has on average 365.2425 * 86400 / 2
-        = 15778476 seconds.  */
-      i = (transitions[num_transitions - 1] - timer) / 15778476;
-      if (i < num_transitions)
+      __tzname[0] = NULL;
+      __tzname[1] = NULL;
+
+      if (num_transitions == 0 || timer < transitions[0])
        {
-         i = num_transitions - 1 - i;
-         if (timer < transitions[i])
+         /* TIMER is before any transition (or there are no transitions).
+            Choose the first non-DST type
+            (or the first if they're all DST types).  */
+         i = 0;
+         while (i < num_types && types[i].isdst)
            {
-             if (i < 10 || timer >= transitions[i - 10])
-               {
-                 /* Linear search.  */
-                 while (timer < transitions[i - 1])
-                   --i;
-                 goto found;
-               }
-             hi = i - 10;
+             if (__tzname[1] == NULL)
+               __tzname[1] = __tzstring (&zone_names[types[i].idx]);
+
+             ++i;
            }
-         else
+
+         if (i == num_types)
+           i = 0;
+         __tzname[0] = __tzstring (&zone_names[types[i].idx]);
+         if (__tzname[1] == NULL)
            {
-             if (i + 10 >= num_transitions || timer < transitions[i + 10])
-               {
-                 /* Linear search.  */
-                 while (timer >= transitions[i])
-                   ++i;
-                 goto found;
-               }
-             lo = i + 10;
+             size_t j = i;
+             while (j < num_types)
+               if (types[j].isdst)
+                 {
+                   __tzname[1] = __tzstring (&zone_names[types[j].idx]);
+                   break;
+                 }
+               else
+                 ++j;
            }
        }
-
-      /* Binary search.  */
-      /* assert (timer >= transitions[lo] && timer < transitions[hi]); */
-      while (lo + 1 < hi)
+      else if (timer >= transitions[num_transitions - 1])
        {
-         i = (lo + hi) / 2;
-         if (timer < transitions[i])
-           hi = i;
-         else
-           lo = i;
-       }
-      i = hi;
+         if (tzspec == NULL)
+           {
+           use_last:
+             i = num_transitions - 1;
+             goto found;
+           }
 
-    found:
-      /* assert (timer >= transitions[i - 1] && timer < transitions[i]); */
-      i = type_idxs[i - 1];
-    }
+         /* Parse the POSIX TZ-style string.  */
+         __tzset_parse_tz (tzspec);
 
-  return &types[i];
-}
-\f
-void
-__tzfile_compute (time_t timer, int use_localtime,
-                 long int *leap_correct, int *leap_hit,
-                 struct tm *tp)
-{
-  register size_t i;
+         /* Convert to broken down structure.  If this fails do not
+            use the string.  */
+         if (! __offtime (&timer, 0, tp))
+           goto use_last;
 
-  if (use_localtime)
-    {
-      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; )
+         /* Use the rules from the TZ string to compute the change.  */
+         __tz_compute (timer, tp, 1);
+
+         *leap_correct = 0L;
+         *leap_hit = 0;
+         return;
+       }
+      else
        {
-         int type = type_idxs[--i];
-         int dst = types[type].isdst;
-         int idx = types[type].idx;
+         /* Find the first transition after TIMER, and
+            then pick the type of the transition before it.  */
+         size_t lo = 0;
+         size_t hi = num_transitions - 1;
+         /* Assume that DST is changing twice a year and guess initial
+            search spot from it.
+            Half of a gregorian year has on average 365.2425 * 86400 / 2
+            = 15778476 seconds.  */
+         i = (transitions[num_transitions - 1] - timer) / 15778476;
+         if (i < num_transitions)
+           {
+             i = num_transitions - 1 - i;
+             if (timer < transitions[i])
+               {
+                 if (i < 10 || timer >= transitions[i - 10])
+                   {
+                     /* Linear search.  */
+                     while (timer < transitions[i - 1])
+                       --i;
+                     goto found;
+                   }
+                 hi = i - 10;
+               }
+             else
+               {
+                 if (i + 10 >= num_transitions || timer < transitions[i + 10])
+                   {
+                     /* Linear search.  */
+                     while (timer >= transitions[i])
+                       ++i;
+                     goto found;
+                   }
+                 lo = i + 10;
+               }
+           }
 
-         if (__tzname[dst] == NULL)
+         /* Binary search.  */
+         /* assert (timer >= transitions[lo] && timer < transitions[hi]); */
+         while (lo + 1 < hi)
+           {
+             i = (lo + hi) / 2;
+             if (timer < transitions[i])
+               hi = i;
+             else
+               lo = i;
+           }
+         i = hi;
+
+       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)
            {
-             __tzname[dst] = __tzstring (&zone_names[idx]);
+             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;
+               }
 
-             if (__tzname[1 - dst] != NULL)
-               break;
+             ++j;
            }
+
+         i = type_idxs[i - 1];
        }
+
+      struct ttinfo *info = &types[i];
+      __daylight = rule_stdoff != rule_dstoff;
+      __timezone = -rule_stdoff;
+
       if (__tzname[0] == NULL)
        {
          /* This should only happen if there are no transition rules.
@@ -647,7 +705,8 @@ __tzfile_compute (time_t timer, int use_localtime,
        /* 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;
     }
 
index 0479abb..27efef0 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2002,2003,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2002,2003,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
@@ -70,7 +70,6 @@ static tz_rule tz_rules[2];
 
 
 static void compute_change (tz_rule *rule, int year) __THROW internal_function;
-static void tz_compute (const struct tm *tm) __THROW internal_function;
 static void tzset_internal (int always, int explicit)
      __THROW internal_function;
 \f
@@ -92,7 +91,7 @@ __tzstring (const char *s)
 {
   char *p;
   struct tzstring_l *t, *u, *new;
-  size_t len = strlen(s);
+  size_t len = strlen (s);
 
   /* Walk the list and look for a match.  If this string is the same
      as the end of an already-allocated string, it can share space. */
@@ -140,80 +139,34 @@ __tzname_max ()
 \f
 static char *old_tz;
 
-/* Interpret the TZ envariable.  */
 static void
 internal_function
-tzset_internal (always, explicit)
-     int always;
-     int explicit;
+update_vars (void)
+{
+  __daylight = tz_rules[0].offset != tz_rules[1].offset;
+  __timezone = -tz_rules[0].offset;
+  __tzname[0] = (char *) tz_rules[0].name;
+  __tzname[1] = (char *) tz_rules[1].name;
+
+  /* Keep __tzname_cur_max up to date.  */
+  size_t len0 = strlen (__tzname[0]);
+  size_t len1 = strlen (__tzname[1]);
+  if (len0 > __tzname_cur_max)
+    __tzname_cur_max = len0;
+  if (len1 > __tzname_cur_max)
+    __tzname_cur_max = len1;
+}
+
+/* Parse the POSIX TZ-style string.  */
+void
+__tzset_parse_tz (tz)
+     const char *tz;
 {
-  static int is_initialized;
-  register const char *tz;
   register size_t l;
   char *tzbuf;
   unsigned short int hh, mm, ss;
   unsigned short int whichrule;
 
-  if (is_initialized && !always)
-    return;
-  is_initialized = 1;
-
-  /* Examine the TZ environment variable.  */
-  tz = getenv ("TZ");
-  if (tz == NULL && !explicit)
-    /* Use the site-wide default.  This is a file name which means we
-       would not see changes to the file if we compare only the file
-       name for change.  We want to notice file changes if tzset() has
-       been called explicitly.  Leave TZ as NULL in this case.  */
-    tz = TZDEFAULT;
-  if (tz && *tz == '\0')
-    /* User specified the empty string; use UTC explicitly.  */
-    tz = "Universal";
-
-  /* A leading colon means "implementation defined syntax".
-     We ignore the colon and always use the same algorithm:
-     try a data file, and if none exists parse the 1003.1 syntax.  */
-  if (tz && *tz == ':')
-    ++tz;
-
-  /* Check whether the value changes since the last run.  */
-  if (old_tz != NULL && tz != NULL && strcmp (tz, old_tz) == 0)
-    /* No change, simply return.  */
-    return;
-
-  if (tz == NULL)
-    /* No user specification; use the site-wide default.  */
-    tz = TZDEFAULT;
-
-  tz_rules[0].name = NULL;
-  tz_rules[1].name = NULL;
-
-  /* Save the value of `tz'.  */
-  if (old_tz != NULL)
-    free (old_tz);
-  old_tz = tz ? __strdup (tz) : NULL;
-
-  /* Try to read a data file.  */
-  __tzfile_read (tz, 0, NULL);
-  if (__use_tzfile)
-    return;
-
-  /* No data file found.  Default to UTC if nothing specified.  */
-
-  if (tz == NULL || *tz == '\0'
-      || (TZDEFAULT != NULL && strcmp (tz, TZDEFAULT) == 0))
-    {
-      tz_rules[0].name = tz_rules[1].name = "UTC";
-      tz_rules[0].type = tz_rules[1].type = J0;
-      tz_rules[0].m = tz_rules[0].n = tz_rules[0].d = 0;
-      tz_rules[1].m = tz_rules[1].n = tz_rules[1].d = 0;
-      tz_rules[0].secs = tz_rules[1].secs = 0;
-      tz_rules[0].offset = tz_rules[1].offset = 0L;
-      tz_rules[0].change = tz_rules[1].change = (time_t) -1;
-      tz_rules[0].computed_for = tz_rules[1].computed_for = 0;
-      goto out;
-    }
-
   /* Clear out old state and reset to unnamed UTC.  */
   memset (tz_rules, 0, sizeof tz_rules);
   tz_rules[0].name = tz_rules[1].name = "";
@@ -413,20 +366,81 @@ tzset_internal (always, explicit)
     }
 
  out:
-  __daylight = tz_rules[0].offset != tz_rules[1].offset;
-  __timezone = -tz_rules[0].offset;
-  __tzname[0] = (char *) tz_rules[0].name;
-  __tzname[1] = (char *) tz_rules[1].name;
+  update_vars ();
+}
 
-  {
-    /* Keep __tzname_cur_max up to date.  */
-    size_t len0 = strlen (__tzname[0]);
-    size_t len1 = strlen (__tzname[1]);
-    if (len0 > __tzname_cur_max)
-      __tzname_cur_max = len0;
-    if (len1 > __tzname_cur_max)
-      __tzname_cur_max = len1;
-  }
+/* Interpret the TZ envariable.  */
+static void
+internal_function
+tzset_internal (always, explicit)
+     int always;
+     int explicit;
+{
+  static int is_initialized;
+  register const char *tz;
+
+  if (is_initialized && !always)
+    return;
+  is_initialized = 1;
+
+  /* Examine the TZ environment variable.  */
+  tz = getenv ("TZ");
+  if (tz == NULL && !explicit)
+    /* Use the site-wide default.  This is a file name which means we
+       would not see changes to the file if we compare only the file
+       name for change.  We want to notice file changes if tzset() has
+       been called explicitly.  Leave TZ as NULL in this case.  */
+    tz = TZDEFAULT;
+  if (tz && *tz == '\0')
+    /* User specified the empty string; use UTC explicitly.  */
+    tz = "Universal";
+
+  /* A leading colon means "implementation defined syntax".
+     We ignore the colon and always use the same algorithm:
+     try a data file, and if none exists parse the 1003.1 syntax.  */
+  if (tz && *tz == ':')
+    ++tz;
+
+  /* Check whether the value changes since the last run.  */
+  if (old_tz != NULL && tz != NULL && strcmp (tz, old_tz) == 0)
+    /* No change, simply return.  */
+    return;
+
+  if (tz == NULL)
+    /* No user specification; use the site-wide default.  */
+    tz = TZDEFAULT;
+
+  tz_rules[0].name = NULL;
+  tz_rules[1].name = NULL;
+
+  /* Save the value of `tz'.  */
+  if (old_tz != NULL)
+    free (old_tz);
+  old_tz = tz ? __strdup (tz) : NULL;
+
+  /* Try to read a data file.  */
+  __tzfile_read (tz, 0, NULL);
+  if (__use_tzfile)
+    return;
+
+  /* No data file found.  Default to UTC if nothing specified.  */
+
+  if (tz == NULL || *tz == '\0'
+      || (TZDEFAULT != NULL && strcmp (tz, TZDEFAULT) == 0))
+    {
+      tz_rules[0].name = tz_rules[1].name = "UTC";
+      tz_rules[0].type = tz_rules[1].type = J0;
+      tz_rules[0].m = tz_rules[0].n = tz_rules[0].d = 0;
+      tz_rules[1].m = tz_rules[1].n = tz_rules[1].d = 0;
+      tz_rules[0].secs = tz_rules[1].secs = 0;
+      tz_rules[0].offset = tz_rules[1].offset = 0L;
+      tz_rules[0].change = tz_rules[1].change = (time_t) -1;
+      tz_rules[0].computed_for = tz_rules[1].computed_for = 0;
+      update_vars ();
+      return;
+    }
+
+  __tzset_parse_tz (tz);
 }
 \f
 /* Figure out the exact time (as a time_t) in YEAR
@@ -523,13 +537,34 @@ compute_change (rule, year)
 
 /* Figure out the correct timezone for TM and set `__tzname',
    `__timezone', and `__daylight' accordingly.  */
-static void
+void
 internal_function
-tz_compute (tm)
-     const struct tm *tm;
+__tz_compute (timer, tm, use_localtime)
+     time_t timer;
+     struct tm *tm;
+     int use_localtime;
 {
   compute_change (&tz_rules[0], 1900 + tm->tm_year);
   compute_change (&tz_rules[1], 1900 + tm->tm_year);
+
+  if (use_localtime)
+    {
+      int isdst;
+
+      /* We have to distinguish between northern and southern
+        hemisphere.  For the latter the daylight saving time
+        ends in the next year.  */
+      if (__builtin_expect (tz_rules[0].change
+                           > tz_rules[1].change, 0))
+       isdst = (timer < tz_rules[1].change
+                || timer >= tz_rules[0].change);
+      else
+       isdst = (timer >= tz_rules[0].change
+                && timer < tz_rules[1].change);
+      tm->tm_isdst = isdst;
+      tm->tm_zone = __tzname[isdst];
+      tm->tm_gmtoff = tz_rules[isdst].offset;
+    }
 }
 \f
 /* Reinterpret the TZ environment variable and set `tzname'.  */
@@ -583,35 +618,14 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
       if (! __offtime (timer, 0, tp))
        tp = NULL;
       else
-       tz_compute (tp);
+       __tz_compute (*timer, tp, use_localtime);
       leap_correction = 0L;
       leap_extra_secs = 0;
     }
 
   if (tp)
     {
-      if (use_localtime)
-       {
-         if (!__use_tzfile)
-           {
-             int isdst;
-
-             /* We have to distinguish between northern and southern
-                hemisphere.  For the latter the daylight saving time
-                ends in the next year.  */
-             if (__builtin_expect (tz_rules[0].change
-                                   > tz_rules[1].change, 0))
-               isdst = (*timer < tz_rules[1].change
-                        || *timer >= tz_rules[0].change);
-             else
-               isdst = (*timer >= tz_rules[0].change
-                        && *timer < tz_rules[1].change);
-             tp->tm_isdst = isdst;
-             tp->tm_zone = __tzname[isdst];
-             tp->tm_gmtoff = tz_rules[isdst].offset;
-           }
-       }
-      else
+      if (! use_localtime)
        {
          tp->tm_isdst = 0;
          tp->tm_zone = "GMT";
index 4c87916..00f899b 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2000, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2000, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 1998.
 
@@ -44,7 +44,6 @@ static const struct test_times tests[] =
   { "America/Chicago", 1, 21600, {"CST", "CDT" }},
   { "America/Indiana/Indianapolis", 1, 18000, {"EST", "EDT" }},
   { "America/Los_Angeles", 1, 28800, {"PST", "PDT" }},
-  { "Asia/Tokyo", 1, -32400, {"JST", "JDT" }},
   { "Pacific/Auckland", 1, -43200, { "NZST", "NZDT" }},
   { NULL, 0, 0 }
 };