Updated to fedora-glibc-20070202T0923 fedora-glibc-2_5_90-16
authorjakub <jakub>
Fri, 2 Feb 2007 09:48:22 +0000 (09:48 +0000)
committerjakub <jakub>
Fri, 2 Feb 2007 09:48:22 +0000 (09:48 +0000)
51 files changed:
ChangeLog
NEWS
elf/dl-minimal.c
fedora/branch.mk
fedora/glibc.spec.in
iconvdata/Makefile
iconvdata/TESTS
iconvdata/brf.c [new file with mode: 0644]
iconvdata/gconv-modules
iconvdata/testdata/BRF [new file with mode: 0644]
iconvdata/testdata/BRF..UTF8 [new file with mode: 0644]
iconvdata/tst-tables.sh
localedata/ChangeLog
localedata/charmaps/BRF [new file with mode: 0644]
misc/hsearch_r.c
nptl/ChangeLog
nptl/pthread_join.c
nptl/tst-initializers1.c
nscd/connections.c
nscd/nscd-client.h
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
nscd/nscd_initgroups.c
scripts/gen-as-const.awk
stdio-common/Makefile
stdio-common/_itoa.c
stdio-common/_itoa.h
stdio-common/_itowa.c
stdio-common/bug17.c [new file with mode: 0644]
string/Makefile
string/Versions
string/strerror_l.c [new file with mode: 0644]
string/string.h
sysdeps/i386/bits/byteswap.h
sysdeps/i386/dl-trampoline.S
sysdeps/ieee754/ldbl-128ibm/s_ceill.c
sysdeps/ieee754/ldbl-128ibm/s_copysignl.c
sysdeps/ieee754/ldbl-128ibm/s_fabsl.c
sysdeps/ieee754/ldbl-128ibm/s_floorl.c
sysdeps/ieee754/ldbl-128ibm/s_roundl.c
sysdeps/ieee754/ldbl-128ibm/s_truncl.c
sysdeps/unix/sysv/linux/getdents.c
sysdeps/unix/sysv/linux/i386/sysdep.h
sysdeps/unix/sysv/linux/sys/personality.h
sysdeps/unix/sysv/linux/x86_64/sysdep.h
sysdeps/x86_64/bits/byteswap.h
wcsmbs/wchar.h

index 1717226..55f92a0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,138 @@
+2007-02-01  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep.h (PTR_MANGLE): Roll value before
+       returning.
+       (PTR_DEMANGLE): Real definition now that it's not the same as
+       PRT_MANGLE anymore.
+       * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise.
+
+       * string/strerror_l.c: New file.
+       * string/Makefile (routines): Add strerror_l.
+       * string/string.h: Declare strerror_l.
+       * string/Versions: Export strerror_l for GLIBC_2.6.
+
+2007-01-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * nscd/nscd_helper.c (open_socket): Now takes request type and key
+       as parameter.  Construct request record.  Try sending request
+       before the first poll use, it usually succeeds.  Adjust all
+       callers.
+       * nscd/nscd-client.h: Define MAXKEYLEN.
+       * nscd/connections.c (nscd_run): Don't define MAXKEYLEN here.
+
+2007-01-31  Jakub Jelinek  <jakub@redhat.com>
+
+       * nscd/nscd-client.h (__nscd_cache_search): Remove const qualifier
+       from return value.
+       * nscd/nscd_helper.c: Include string.h.
+       (__nscd_cache_search): Remove const qualifier from return value.
+       On strict alignment architectures check hash entry and data head
+       alignment.
+       * nscd/nscd_getpw_r.c (nscd_getpw_r): Don't crash or fail because
+       mmapped data during GC cycle contains garbage.  If
+       __nscd_drop_map_ref fails, decrement mapped->counter when returning
+       error or if retrying with NO_MAPPING, only __nscd_unmap if counter
+       dropped to 0.
+       * nscd/nscd_getgr_r.c (nscd_getgr_r): Likewise.
+       * nscd/nscd_initgroups.c (__nscd_getgrouplist): Likewise.
+       * nscd/nscd_gethst_r.c (nscd_gethst_r): Likewise.
+       * nscd/nscd_getai.c (__nscd_getai): Likewise.
+       * nscd/nscd_getserv_r.c (nscd_getserv_r): Likewise.
+
+2007-01-30  Ulrich Drepper  <drepper@redhat.com>
+
+       * misc/hsearch_r.c (hdestroy_r): Remove unnecessary test.
+
+2007-01-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/i386/dl-trampoline.S (_dl_runtime_profile): Use register
+       names not numbers in cfi_*.
+
+2007-01-26  Andreas Jaeger  <aj@suse.de>
+
+       * sysdeps/unix/sysv/linux/sys/personality.h (ADDR_NO_RANDOMIZE,
+       ADDR_LIMIT_3GB, PER_LINUX_32BIT, PER_LINUX32_3GB): Add.
+       Correct values of PER_HPUX and PER_OSF4.
+
+2007-01-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/dl-minimal.c: Undefine _itoa first.
+       * stdio-common/_itoa.h: Define _itoa and _fitoa for 64-bit platforms.
+       * malloc/mtrace.c: Revert last change.
+       * posix/wordexp.c: Likewise.
+
+2007-01-24  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/i386/bits/byteswap.h (__bswap_32): Add __nocona__, __core2__
+       and __geode__ to the list of i486+ CPUs.
+       * sysdeps/x86_64/bits/byteswap.h (__bswap_32): Likewise.
+
+2007-01-23  Ulrich Drepper  <drepper@redhat.com>
+
+       * stdio-common/_itoa.c: Include <limits.h>.
+       * stdio-common/_itowa.c: Likewise.
+
+2007-01-22  Ulrich Drepper  <drepper@redhat.com>
+
+       * stdio-common/_itowa.c: Don't compile _itowa for 64-bit
+       platforms.
+       * stdio-common/_itoa.c: Don't compile in _itoa and _fitoa for
+       64-bit platforms.
+       * malloc/mtrace.c (tr_where): Use _fitoa_word instead of _fitoa if
+       possible.
+       * posix/wordexp.c (parse_arith): Use _itoa_word instead of _itoa
+       if possible.
+
+       [BZ #3902]
+       * stdio-common/_itoa.c (_itoa): Make sure at least a zero is emitted.
+       * stdio-common/Makefile (tests): Add bug17.
+       * stdio-common/bug17.c: New file.
+
+2007-01-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * iconvdata/brf.c: New file.
+       * iconvdata/testdata/BRF: New file.
+       * iconvdata/testdata/BRF..UTF8: New file.
+       Contributed by Samuel Thibault <samuel.thibault@ens-lyon.org>.
+       * iconvdata/Makefile: Add rules to build BRF.
+       * iconvdata/TESTS: Add BRF entry.
+       * iconvdata/gconv-modules: Likewise.
+       * iconvdata/tst-tables.sh: Likewise.
+
+2007-01-18  Anton Nikishaev  <anton.nik@gmail.com>
+
+       * wcsmbs/wchar.h (wcstoll): Fix comment, function returns value of
+       type `long long int', not `long int'.
+       (wcstoq): Likewise.
+
+2007-01-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * scripts/gen-as-const.awk: Add cast to long to avoid int promotion
+       of values on 64-bit platforms which are too large.
+
+2007-01-12  Steven Munroe  <sjmunroe@us.ibm.com>
+           Joe Kerian  <jkerian@us.us.ibm.com>
+
+       [BZ #2749]
+       * sysdeps/ieee754/ldbl-128ibm/s_copysignl.c: Include
+       <math_ldbl_opt.h>.  Remove weak_alias.  Use long_double_symbol macro.
+       (__copysignl): Use signbit() for comparison.
+       * sysdeps/ieee754/ldbl-128ibm/s_fabsl.c (__fabsl): Correct parms for
+       SET_LDOUBLE_WORDS64.
+
+       [BZ #2423, #2749]
+       * sysdeps/ieee754/ldbl-128ibm/s_ceill.c: Don't include <fenv_libc.h>.
+       (__ceill): Remove calls to fegetround(), fesetround().
+       * sysdeps/ieee754/ldbl-128ibm/s_floorl.c: Likewise.
+       * sysdeps/ieee754/ldbl-128ibm/s_roundl.c: Likewise.
+       * sysdeps/ieee754/ldbl-128ibm/s_truncl.c: Likewise.
+
+2007-01-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * nscd/nscd_getserv_r.c (nscd_getserv_r): Fix pastos.
+
+       * sysdeps/unix/sysv/linux/getdents.c (offsetof): Remove.
+
 2007-01-17  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/unix/sysv/linux/fatal-prepare.h: Use PTHFCT_CALL to
diff --git a/NEWS b/NEWS
index a32179f..69414e0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes.  2007-1-13
+GNU C Library NEWS -- history of user-visible changes.  2007-2-1
 Copyright (C) 1992-2006, 2007 Free Software Foundation, Inc.
 See the end for copying conditions.
 
@@ -9,6 +9,8 @@ Version 2.6
 
 * New Linux interfaces: epoll_pwait.
 
+* New generic interfaces: strerror_l.
+
 * nscd can now cache the services database.   Implemented by Ulrich Drepper.
 
 \f
index 8e78709..4552408 100644 (file)
@@ -1,5 +1,5 @@
 /* Minimal replacements for basic facilities used in the dynamic linker.
-   Copyright (C) 1995-1998,2000-2002,2004,2005,2006
+   Copyright (C) 1995-1998,2000-2002,2004-2006,2007
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -283,6 +283,7 @@ __strtoul_internal (const char *nptr, char **endptr, int base, int group)
 }
 
 
+#undef _itoa
 /* We always use _itoa instead of _itoa_word in ld.so since the former
    also has to be present and it is never about speed when these
    functions are used.  */
index e4217bc..37e8ff5 100644 (file)
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-fc7
-fedora-sync-date := 2007-01-17 10:43 UTC
-fedora-sync-tag := fedora-glibc-20070117T1043
+fedora-sync-date := 2007-02-02 09:23 UTC
+fedora-sync-tag := fedora-glibc-20070202T0923
index 8b20273..14015da 100644 (file)
@@ -1,4 +1,4 @@
-%define glibcrelease 15
+%define glibcrelease 16
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define xenarches i686 athlon
 %ifarch %{xenarches}
@@ -1393,7 +1393,7 @@ touch $RPM_BUILD_ROOT/%{_prefix}/lib/locale/locale-archive
 %triggerin common -p /usr/sbin/tzdata-update -- tzdata
 
 %post devel
-/sbin/install-info %{_infodir}/libc.info.gz %{_infodir}/dir
+/sbin/install-info %{_infodir}/libc.info.gz %{_infodir}/dir || :
 
 %pre headers
 # this used to be a link and it is causing nightmares now
@@ -1403,7 +1403,7 @@ fi
 
 %preun devel
 if [ "$1" = 0 ]; then
-    /sbin/install-info --delete %{_infodir}/libc.info.gz %{_infodir}/dir
+    /sbin/install-info --delete %{_infodir}/libc.info.gz %{_infodir}/dir || :
 fi
 
 %post utils -p /sbin/ldconfig
@@ -1546,6 +1546,15 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Fri Feb  2 2007 Jakub Jelinek <jakub@redhat.com> 2.5.90-16
+- add strerror_l
+- fix application crashes when doing NSS lookups through nscd
+  mmapped databases and nscd decides to start garbage collection
+  during the lookups (#219145, #225315)
+- fix %0lld printing of 0LL on 32-bit architectures (BZ#3902)
+- ignore errors from install-info in glibc-devel scriptlets
+  (#223691)
+
 * Wed Jan 17 2007 Jakub Jelinek <jakub@redhat.com> 2.5.90-15
 - fix NIS getservbyname when proto is NULL
 - fix nss_compat +group handling (#220658)
index c7d5801..8b49367 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1997-2004,2005,2006 Free Software Foundation, Inc.
+# Copyright (C) 1997-2004,2005,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
@@ -58,7 +58,7 @@ modules       := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5             \
           IBM1142 IBM1143 IBM1144 IBM1145 IBM1146 IBM1147 IBM1148       \
           IBM1149 IBM1166 IBM1167 IBM4517 IBM4899 IBM4909 IBM4971       \
           IBM5347 IBM9030 IBM9066 IBM9448 IBM12712 IBM16804             \
-          IBM1364 IBM1371 IBM1388 IBM1390 IBM1399 ISO_11548-1 MIK
+          IBM1364 IBM1371 IBM1388 IBM1390 IBM1399 ISO_11548-1 MIK BRF
 
 modules.so := $(addsuffix .so, $(modules))
 
@@ -196,7 +196,8 @@ distribute := gconv-modules extra-module.mk gap.awk gaptab.awk gconv.map    \
              ibm9030.c ibm9030.h ibm9066.c ibm9066.h ibm9448.c ibm9448.h   \
              ibm12712.c ibm12712.h ibm16804.c ibm16804.h                   \
              ibm1364.c ibm1364.h ibm1371.c ibm1371.h ibm1388.c ibm1388.h   \
-             ibm1390.c ibm1390.h ibm1399.c ibm1399.h iso_11548-1.c mik.c
+             ibm1390.c ibm1390.h ibm1399.c ibm1399.h iso_11548-1.c mik.c   \
+             brf.c
 
 # We build the transformation modules only when we build shared libs.
 ifeq (yes,$(build-shared))
@@ -237,7 +238,7 @@ gen-8bit-gap-modules := koi8-r latin-greek latin-greek-1 ibm256 ibm273         \
                        iso8859-13 iso8859-14 iso8859-15 mac-uk sami-ws2   \
                        iso-ir-197 tis-620 koi8-u ibm874 cp10007 koi8-t    \
                        georgian-ps georgian-academy iso-ir-209 mac-sami   \
-                       iso8859-11 ibm866nav pt154 rk1048 mik
+                       iso8859-11 ibm866nav pt154 rk1048 mik brf
 
 gen-special-modules := iso8859-7jp
 
index b70e505..2743cc1 100644 (file)
@@ -1,5 +1,5 @@
 # Available tests for iconv(1) (and therefore iconv(3)) in GNU libc.
-# Copyright (C) 1998-2002, 2005 Free Software Foundation, Inc.
+# Copyright (C) 1998-2002, 2005, 2007 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 #
@@ -166,3 +166,4 @@ IBM1390                     IBM1390                 N       UTF8
 IBM1399                        IBM1399                 N       UTF8
 ISO_11548-1            ISO_11548-1             -       UTF8
 MIK                    MIK                     Y       UTF8
+BRF                    BRF                     -       UTF8
diff --git a/iconvdata/brf.c b/iconvdata/brf.c
new file mode 100644 (file)
index 0000000..4e40e7b
--- /dev/null
@@ -0,0 +1,29 @@
+/* Conversion from and to BRF.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Samuel Thibault <samuel.thibault@ens-lyon.org>, 2006.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdint.h>
+
+/* Get the conversion table.  */
+#define TABLES <brf.h>
+
+#define CHARSET_NAME   "BRF//"
+#define HAS_HOLES      1       /* Not all 256 character are defined.  */
+
+#include <8bit-gap.c>
index 852c7b9..7f47dec 100644 (file)
@@ -1,5 +1,5 @@
 # GNU libc iconv configuration.
-# Copyright (C) 1997-2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 1997-2004, 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
@@ -1907,3 +1907,7 @@ module    INTERNAL                ISO_11548-1//           ISO_11548-1     1
 #      from                    to                      module          cost
 module MIK//                   INTERNAL                MIK             1
 module INTERNAL                MIK//                   MIK             1
+
+#      from                    to                      module          cost
+module BRF//                   INTERNAL                BRF             1
+module INTERNAL                BRF//                   BRF             1
diff --git a/iconvdata/testdata/BRF b/iconvdata/testdata/BRF
new file mode 100644 (file)
index 0000000..a69e107
--- /dev/null
@@ -0,0 +1,7 @@
+A B C D E F G H I J
+K L M N O P Q R S T
+U V X Y Z & = ( ! )
+* < % ? : $ ] \ [ W
+1 2 3 4 5 6 7 8 9 0
+/ + # > ' -
+@ ^ _ " . ; ,
diff --git a/iconvdata/testdata/BRF..UTF8 b/iconvdata/testdata/BRF..UTF8
new file mode 100644 (file)
index 0000000..08275e2
--- /dev/null
@@ -0,0 +1,7 @@
+⠁⠀⠃⠀⠉⠀⠙⠀⠑⠀⠋⠀⠛⠀⠓⠀⠊⠀⠚
+⠅⠀⠇⠀⠍⠀⠝⠀⠕⠀⠏⠀⠟⠀⠗⠀⠎⠀⠞
+⠥⠀⠧⠀⠭⠀⠽⠀⠵⠀⠯⠀⠿⠀⠷⠀⠮⠀⠾
+⠡⠀⠣⠀⠩⠀⠹⠀⠱⠀⠫⠀⠻⠀⠳⠀⠪⠀⠺
+⠂⠀⠆⠀⠒⠀⠲⠀⠢⠀⠖⠀⠶⠀⠦⠀⠔⠀⠴
+⠌⠀⠬⠀⠼⠀⠜⠀⠄⠀⠤
+⠈⠀⠘⠀⠸⠀⠐⠀⠨⠀⠰⠀⠠
index 506adbc..be1e883 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 2000,2001,2002,2003,2004,2007 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Bruno Haible <haible@clisp.cons.org>, 2000.
 #
@@ -208,6 +208,7 @@ cat <<EOF |
   PT154
   RK1048
   MIK
+  BRF
   #
   # Multibyte encodings come here
   #
index 85b2d79..39e87c2 100644 (file)
@@ -1,3 +1,8 @@
+2007-01-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * charmaps/BRF: New file.
+       Contributed by Samuel Thibault <samuel.thibault@ens-lyon.org>.
+
 2006-12-05  Jakub Jelinek  <jakub@redhat.com>
 
        * locales/cs_CZ (LC_TIME): Change d_fmt to %e.%m.%Y from %-d.%-m.%Y.
diff --git a/localedata/charmaps/BRF b/localedata/charmaps/BRF
new file mode 100644 (file)
index 0000000..6b06f71
--- /dev/null
@@ -0,0 +1,108 @@
+<code_set_name> BRF
+<comment_char> %
+<escape_char> /
+% version: 1.0
+%  source: Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+CHARMAP
+<U0000>     /x00         NULL (NUL)
+<U0001>     /x01         START OF HEADING (SOH)
+<U0002>     /x02         START OF TEXT (STX)
+<U0003>     /x03         END OF TEXT (ETX)
+<U0004>     /x04         END OF TRANSMISSION (EOT)
+<U0005>     /x05         ENQUIRY (ENQ)
+<U0006>     /x06         ACKNOWLEDGE (ACK)
+<U0007>     /x07         BELL (BEL)
+<U0008>     /x08         BACKSPACE (BS)
+<U0009>     /x09         CHARACTER TABULATION (HT)
+<U000A>     /x0a         LINE FEED (LF)
+<U000B>     /x0b         LINE TABULATION (VT)
+<U000C>     /x0c         FORM FEED (FF)
+<U000D>     /x0d         CARRIAGE RETURN (CR)
+<U000E>     /x0e         SHIFT OUT (SO)
+<U000F>     /x0f         SHIFT IN (SI)
+<U0010>     /x10         DATALINK ESCAPE (DLE)
+<U0011>     /x11         DEVICE CONTROL ONE (DC1)
+<U0012>     /x12         DEVICE CONTROL TWO (DC2)
+<U0013>     /x13         DEVICE CONTROL THREE (DC3)
+<U0014>     /x14         DEVICE CONTROL FOUR (DC4)
+<U0015>     /x15         NEGATIVE ACKNOWLEDGE (NAK)
+<U0016>     /x16         SYNCHRONOUS IDLE (SYN)
+<U0017>     /x17         END OF TRANSMISSION BLOCK (ETB)
+<U0018>     /x18         CANCEL (CAN)
+<U0019>     /x19         END OF MEDIUM (EM)
+<U001A>     /x1a         SUBSTITUTE (SUB)
+<U001B>     /x1b         ESCAPE (ESC)
+<U001C>     /x1c         FILE SEPARATOR (IS4)
+<U001D>     /x1d         GROUP SEPARATOR (IS3)
+<U001E>     /x1e         RECORD SEPARATOR (IS2)
+<U001F>     /x1f         UNIT SEPARATOR (IS1)
+<U2800>     /x20         BRAILLE PATTERN BLANK
+<U282E>     /x21         BRAILLE PATTERN DOTS-2346
+<U2810>     /x22         BRAILLE PATTERN DOTS-5
+<U283C>     /x23         BRAILLE PATTERN DOTS-3456
+<U282B>     /x24         BRAILLE PATTERN DOTS-1246
+<U2829>     /x25         BRAILLE PATTERN DOTS-146
+<U282F>     /x26         BRAILLE PATTERN DOTS-12346
+<U2804>     /x27         BRAILLE PATTERN DOTS-3
+<U2837>     /x28         BRAILLE PATTERN DOTS-12356
+<U283E>     /x29         BRAILLE PATTERN DOTS-23456
+<U2821>     /x2a         BRAILLE PATTERN DOTS-16
+<U282C>     /x2b         BRAILLE PATTERN DOTS-346
+<U2820>     /x2c         BRAILLE PATTERN DOTS-6
+<U2824>     /x2d         BRAILLE PATTERN DOTS-36
+<U2828>     /x2e         BRAILLE PATTERN DOTS-46
+<U280C>     /x2f         BRAILLE PATTERN DOTS-34
+<U2834>     /x30         BRAILLE PATTERN DOTS-356
+<U2802>     /x31         BRAILLE PATTERN DOTS-2
+<U2806>     /x32         BRAILLE PATTERN DOTS-23
+<U2812>     /x33         BRAILLE PATTERN DOTS-25
+<U2832>     /x34         BRAILLE PATTERN DOTS-256
+<U2822>     /x35         BRAILLE PATTERN DOTS-26
+<U2816>     /x36         BRAILLE PATTERN DOTS-235
+<U2836>     /x37         BRAILLE PATTERN DOTS-2356
+<U2826>     /x38         BRAILLE PATTERN DOTS-236
+<U2814>     /x39         BRAILLE PATTERN DOTS-35
+<U2831>     /x3a         BRAILLE PATTERN DOTS-156
+<U2830>     /x3b         BRAILLE PATTERN DOTS-56
+<U2823>     /x3c         BRAILLE PATTERN DOTS-126
+<U283F>     /x3d         BRAILLE PATTERN DOTS-123456
+<U281C>     /x3e         BRAILLE PATTERN DOTS-345
+<U2839>     /x3f         BRAILLE PATTERN DOTS-1456
+<U2808>     /x40         BRAILLE PATTERN DOTS-4
+<U2801>     /x41         BRAILLE PATTERN DOTS-1
+<U2803>     /x42         BRAILLE PATTERN DOTS-12
+<U2809>     /x43         BRAILLE PATTERN DOTS-14
+<U2819>     /x44         BRAILLE PATTERN DOTS-145
+<U2811>     /x45         BRAILLE PATTERN DOTS-15
+<U280B>     /x46         BRAILLE PATTERN DOTS-124
+<U281B>     /x47         BRAILLE PATTERN DOTS-1245
+<U2813>     /x48         BRAILLE PATTERN DOTS-125
+<U280A>     /x49         BRAILLE PATTERN DOTS-24
+<U281A>     /x4a         BRAILLE PATTERN DOTS-245
+<U2805>     /x4b         BRAILLE PATTERN DOTS-13
+<U2807>     /x4c         BRAILLE PATTERN DOTS-123
+<U280D>     /x4d         BRAILLE PATTERN DOTS-134
+<U281D>     /x4e         BRAILLE PATTERN DOTS-1345
+<U2815>     /x4f         BRAILLE PATTERN DOTS-135
+<U280F>     /x50         BRAILLE PATTERN DOTS-1234
+<U281F>     /x51         BRAILLE PATTERN DOTS-12345
+<U2817>     /x52         BRAILLE PATTERN DOTS-1235
+<U280E>     /x53         BRAILLE PATTERN DOTS-234
+<U281E>     /x54         BRAILLE PATTERN DOTS-2345
+<U2825>     /x55         BRAILLE PATTERN DOTS-136
+<U2827>     /x56         BRAILLE PATTERN DOTS-1236
+<U283A>     /x57         BRAILLE PATTERN DOTS-2456
+<U282D>     /x58         BRAILLE PATTERN DOTS-1346
+<U283D>     /x59         BRAILLE PATTERN DOTS-13456
+<U2835>     /x5a         BRAILLE PATTERN DOTS-1356
+<U282A>     /x5b         BRAILLE PATTERN DOTS-246
+<U2833>     /x5c         BRAILLE PATTERN DOTS-1256
+<U283B>     /x5d         BRAILLE PATTERN DOTS-12456
+<U2818>     /x5e         BRAILLE PATTERN DOTS-45
+<U2838>     /x5f         BRAILLE PATTERN DOTS-456
+END CHARMAP
+
+WIDTH
+<U2800>...<U283F>      1
+END WIDTH
index b03c12c..cb4d674 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1995,1996,1997,2002,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1995-1997,2002,2005,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1993.
 
@@ -110,9 +110,8 @@ hdestroy_r (htab)
       return;
     }
 
-  if (htab->table != NULL)
-    /* free used memory */
-    free (htab->table);
+  /* Free used memory.  */
+  free (htab->table);
 
   /* the sign for an existing table is an value != NULL in htable */
   htab->table = NULL;
index 842a04f..9ee7f8d 100644 (file)
@@ -1,3 +1,10 @@
+2007-01-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * tst-initializers1.c: We want to test the initializers as seen
+       outside of libc, so undefined _LIBC.
+
+       * pthread_join.c (cleanup): Avoid warning.
+
 2007-01-17  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
index c88d85b..6a87a8b 100644 (file)
@@ -30,8 +30,8 @@ cleanup (void *arg)
   /* If we already changed the waiter ID, reset it.  The call cannot
      fail for any reason but the thread not having done that yet so
      there is no reason for a loop.  */
-  atomic_compare_and_exchange_bool_acq ((struct pthread **) arg, NULL,
-                                       THREAD_SELF);
+  (void) atomic_compare_and_exchange_bool_acq ((struct pthread **) arg, NULL,
+                                              THREAD_SELF);
 }
 
 
index ccd2728..eacee35 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2005.
 
@@ -17,6 +17,9 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+/* We test the code undef conditions outside of glibc.  */
+#undef _LIBC
+
 #include <pthread.h>
 
 pthread_mutex_t mtx_normal = PTHREAD_MUTEX_INITIALIZER;
index 88b44c3..4e01b31 100644 (file)
@@ -1430,7 +1430,6 @@ nscd_run (void *p)
 
       /* It should not be possible to crash the nscd with a silly
         request (i.e., a terribly large key).  We limit the size to 1kb.  */
-#define MAXKEYLEN 1024
       if (__builtin_expect (req.key_len, 1) < 0
          || __builtin_expect (req.key_len, 1) > MAXKEYLEN)
        {
index 7702f59..3c9688f 100644 (file)
@@ -44,6 +44,9 @@
 /* Path for the configuration file.  */
 #define _PATH_NSCDCONF  "/etc/nscd.conf"
 
+/* Maximu allowed length for the key.  */
+#define MAXKEYLEN 1024
+
 
 /* Available services.  */
 typedef enum
@@ -323,10 +326,10 @@ static inline int __nscd_drop_map_ref (struct mapped_database *map,
 
 
 /* Search the mapped database.  */
-extern const struct datahead *__nscd_cache_search (request_type type,
-                                                  const char *key,
-                                                  size_t keylen,
-                                                  const struct mapped_database *mapped);
+extern struct datahead *__nscd_cache_search (request_type type,
+                                            const char *key,
+                                            size_t keylen,
+                                            const struct mapped_database *mapped);
 
 /* Wrappers around read, readv and write that only read/write less than LEN
    bytes on error or EOF.  */
index b59c31e..5df32dc 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -42,6 +42,7 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
 {
   size_t keylen = strlen (key) + 1;
   int gc_cycle;
+  int nretries = 0;
 
   /* If the mapping is available, try to search there instead of
      communicating with the nscd.  */
@@ -50,49 +51,53 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
                               &gc_cycle);
 
  retry:;
-  const ai_response_header *ai_resp = NULL;
   struct nscd_ai_result *resultbuf = NULL;
   const char *recend = (const char *) ~UINTMAX_C (0);
   char *respdata = NULL;
   int retval = -1;
   int sock = -1;
+  ai_response_header ai_resp;
 
   if (mapped != NO_MAPPING)
     {
-      const struct datahead *found = __nscd_cache_search (GETAI, key, keylen,
-                                                         mapped);
+      struct datahead *found = __nscd_cache_search (GETAI, key, keylen,
+                                                   mapped);
       if (found != NULL)
        {
-         ai_resp = &found->data[0].aidata;
-         respdata = (char *) (ai_resp + 1);
+         respdata = (char *) (&found->data[0].aidata + 1);
+         ai_resp = found->data[0].aidata;
          recend = (const char *) found->data + found->recsize;
+         /* Now check if we can trust ai_resp fields.  If GC is
+            in progress, it can contain anything.  */
+         if (mapped->head->gc_cycle != gc_cycle)
+           {
+             retval = -2;
+             goto out;
+           }
        }
     }
 
   /* If we do not have the cache mapped, try to get the data over the
      socket.  */
-  ai_response_header ai_resp_mem;
-  if (ai_resp == NULL)
+  if (respdata == NULL)
     {
-      sock = __nscd_open_socket (key, keylen, GETAI, &ai_resp_mem,
-                                sizeof (ai_resp_mem));
+      sock = __nscd_open_socket (key, keylen, GETAI, &ai_resp,
+                                sizeof (ai_resp));
       if (sock == -1)
        {
          /* nscd not running or wrong version.  */
          __nss_not_use_nscd_hosts = 1;
          goto out;
        }
-
-      ai_resp = &ai_resp_mem;
     }
 
-  if (ai_resp->found == 1)
+  if (ai_resp.found == 1)
     {
-      size_t datalen = ai_resp->naddrs + ai_resp->addrslen + ai_resp->canonlen;
+      size_t datalen = ai_resp.naddrs + ai_resp.addrslen + ai_resp.canonlen;
 
-      /* This check is really only affects the case where the data
+      /* This check really only affects the case where the data
         comes from the mapped cache.  */
-      if ((char *) (ai_resp + 1) + datalen > recend)
+      if (respdata + datalen > recend)
        {
          assert (sock == -1);
          goto out;
@@ -108,10 +113,10 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
        }
 
       /* Set up the data structure, including pointers.  */
-      resultbuf->naddrs = ai_resp->naddrs;
+      resultbuf->naddrs = ai_resp.naddrs;
       resultbuf->addrs = (char *) (resultbuf + 1);
-      resultbuf->family = (uint8_t *) (resultbuf->addrs + ai_resp->addrslen);
-      if (ai_resp->canonlen != 0)
+      resultbuf->family = (uint8_t *) (resultbuf->addrs + ai_resp.addrslen);
+      if (ai_resp.canonlen != 0)
        resultbuf->canon = (char *) (resultbuf->family + resultbuf->naddrs);
       else
        resultbuf->canon = NULL;
@@ -137,10 +142,13 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
 
          /* Try to detect corrupt databases.  */
          if (resultbuf->canon != NULL
-             && resultbuf->canon[ai_resp->canonlen - 1] != '\0')
+             && resultbuf->canon[ai_resp.canonlen - 1] != '\0')
            /* We cannot use the database.  */
            {
-             free (resultbuf);
+             if (mapped->head->gc_cycle != gc_cycle)
+               retval = -2;
+             else
+               free (resultbuf);
              goto out_close;
            }
 
@@ -150,7 +158,7 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
     }
   else
     {
-      if (__builtin_expect (ai_resp->found == -1, 0))
+      if (__builtin_expect (ai_resp.found == -1, 0))
        {
          /* The daemon does not cache this database.  */
          __nss_not_use_nscd_hosts = 1;
@@ -158,7 +166,7 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
        }
 
       /* Store the error number.  */
-      *h_errnop = ai_resp->error;
+      *h_errnop = ai_resp.error;
 
       /* The `errno' to some value != ERANGE.  */
       __set_errno (ENOENT);
@@ -170,22 +178,25 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
-  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
+  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
     {
       /* When we come here this means there has been a GC cycle while we
         were looking for the data.  This means the data might have been
         inconsistent.  Retry if possible.  */
-      if ((gc_cycle & 1) != 0)
+      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
        {
          /* nscd is just running gc now.  Disable using the mapping.  */
-         __nscd_unmap (mapped);
+         if (atomic_decrement_val (&mapped->counter) == 0)
+           __nscd_unmap (mapped);
          mapped = NO_MAPPING;
        }
 
-      *result = NULL;
-      free (resultbuf);
-
-      goto retry;
+      if (retval != -1)
+       {
+         *result = NULL;
+         free (resultbuf);
+         goto retry;
+       }
     }
 
   return retval;
index 922b906..fc036f2 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998-2000, 2002-2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2000, 2002-2005, 2006, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
 
@@ -88,6 +89,7 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
              struct group **result)
 {
   int gc_cycle;
+  int nretries = 0;
   const uint32_t *len = NULL;
   size_t lensize = 0;
 
@@ -97,55 +99,59 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
                                                       &__gr_map_handle,
                                                       &gc_cycle);
  retry:;
-  const gr_response_header *gr_resp = NULL;
   const char *gr_name = NULL;
   size_t gr_name_len = 0;
   int retval = -1;
   const char *recend = (const char *) ~UINTMAX_C (0);
+  gr_response_header gr_resp;
 
   if (mapped != NO_MAPPING)
     {
-      const struct datahead *found = __nscd_cache_search (type, key, keylen,
-                                                         mapped);
+      struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
       if (found != NULL)
        {
-         gr_resp = &found->data[0].grdata;
-         len = (const uint32_t *) (gr_resp + 1);
-         /* The alignment is always sufficient.  */
-         assert (((uintptr_t) len & (__alignof__ (*len) - 1)) == 0);
+         len = (const uint32_t *) (&found->data[0].grdata + 1);
+         gr_resp = found->data[0].grdata;
          gr_name = ((const char *) len
-                    + gr_resp->gr_mem_cnt * sizeof (uint32_t));
-         gr_name_len = gr_resp->gr_name_len + gr_resp->gr_passwd_len;
+                    + gr_resp.gr_mem_cnt * sizeof (uint32_t));
+         gr_name_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len;
          recend = (const char *) found->data + found->recsize;
+         /* Now check if we can trust gr_resp fields.  If GC is
+            in progress, it can contain anything.  */
+         if (mapped->head->gc_cycle != gc_cycle)
+           {
+             retval = -2;
+             goto out;
+           }
+
+         /* The alignment is always sufficient, unless GC is in progress.  */
+         assert (((uintptr_t) len & (__alignof__ (*len) - 1)) == 0);
        }
     }
 
-  gr_response_header gr_resp_mem;
   int sock = -1;
-  if (gr_resp == NULL)
+  if (gr_name == NULL)
     {
-      sock = __nscd_open_socket (key, keylen, type, &gr_resp_mem,
-                                sizeof (gr_resp_mem));
+      sock = __nscd_open_socket (key, keylen, type, &gr_resp,
+                                sizeof (gr_resp));
       if (sock == -1)
        {
          __nss_not_use_nscd_group = 1;
          goto out;
        }
-
-      gr_resp = &gr_resp_mem;
     }
 
   /* No value found so far.  */
   *result = NULL;
 
-  if (__builtin_expect (gr_resp->found == -1, 0))
+  if (__builtin_expect (gr_resp.found == -1, 0))
     {
       /* The daemon does not cache this database.  */
       __nss_not_use_nscd_group = 1;
       goto out_close;
     }
 
-  if (gr_resp->found == 1)
+  if (gr_resp.found == 1)
     {
       struct iovec vec[2];
       char *p = buffer;
@@ -157,8 +163,8 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
         align the pointer.  */
       align = ((__alignof__ (char *) - (p - ((char *) 0)))
               & (__alignof__ (char *) - 1));
-      total_len = (align + (1 + gr_resp->gr_mem_cnt) * sizeof (char *)
-                  + gr_resp->gr_name_len + gr_resp->gr_passwd_len);
+      total_len = (align + (1 + gr_resp.gr_mem_cnt) * sizeof (char *)
+                  + gr_resp.gr_name_len + gr_resp.gr_passwd_len);
       if (__builtin_expect (buflen < total_len, 0))
        {
        no_room:
@@ -170,16 +176,16 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 
       p += align;
       resultbuf->gr_mem = (char **) p;
-      p += (1 + gr_resp->gr_mem_cnt) * sizeof (char *);
+      p += (1 + gr_resp.gr_mem_cnt) * sizeof (char *);
 
       /* Set pointers for strings.  */
       resultbuf->gr_name = p;
-      p += gr_resp->gr_name_len;
+      p += gr_resp.gr_name_len;
       resultbuf->gr_passwd = p;
-      p += gr_resp->gr_passwd_len;
+      p += gr_resp.gr_passwd_len;
 
       /* Fill in what we know now.  */
-      resultbuf->gr_gid = gr_resp->gr_gid;
+      resultbuf->gr_gid = gr_resp.gr_gid;
 
       /* Read the length information, group name, and password.  */
       if (gr_name == NULL)
@@ -187,17 +193,17 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
          /* Allocate array to store lengths.  */
          if (lensize == 0)
            {
-             lensize = gr_resp->gr_mem_cnt * sizeof (uint32_t);
+             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)
+         else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize)
            len = extend_alloca (len, lensize,
-                                gr_resp->gr_mem_cnt * sizeof (uint32_t));
+                                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[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;
+         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.  */
@@ -209,14 +215,14 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
        /* We already have the data.  Just copy the group name and
           password.  */
        memcpy (resultbuf->gr_name, gr_name,
-               gr_resp->gr_name_len + gr_resp->gr_passwd_len);
+               gr_resp.gr_name_len + gr_resp.gr_passwd_len);
 
       /* Clear the terminating entry.  */
-      resultbuf->gr_mem[gr_resp->gr_mem_cnt] = NULL;
+      resultbuf->gr_mem[gr_resp.gr_mem_cnt] = NULL;
 
       /* Prepare reading the group members.  */
       total_len = 0;
-      for (cnt = 0; cnt < gr_resp->gr_mem_cnt; ++cnt)
+      for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt)
        {
          resultbuf->gr_mem[cnt] = p;
          total_len += len[cnt];
@@ -224,9 +230,25 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
        }
 
       if (__builtin_expect (gr_name + gr_name_len + total_len > recend, 0))
-       goto out_close;
+       {
+         /* len array might contain garbage during nscd GC cycle,
+            retry rather than fail in that case.  */
+         if (gr_name != NULL && mapped->head->gc_cycle != gc_cycle)
+           retval = -2;
+         goto out_close;
+       }
       if (__builtin_expect (total_len > buflen, 0))
-       goto no_room;
+       {
+         /* len array might contain garbage during nscd GC cycle,
+            retry rather than fail in that case.  */
+         if (gr_name != NULL && mapped->head->gc_cycle != gc_cycle)
+           {
+             retval = -2;
+             goto out_close;
+           }
+         else
+           goto no_room;
+       }
 
       retval = 0;
       if (gr_name == NULL)
@@ -248,14 +270,14 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 
          /* 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)
+             || 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; }))
+                  cnt < gr_resp.gr_mem_cnt; }))
            {
              /* We cannot use the database.  */
-             retval = -1;
+             retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
              goto out_close;
            }
 
@@ -274,19 +296,21 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
-  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
+  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
     {
       /* When we come here this means there has been a GC cycle while we
         were looking for the data.  This means the data might have been
         inconsistent.  Retry if possible.  */
-      if ((gc_cycle & 1) != 0)
+      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
        {
          /* nscd is just running gc now.  Disable using the mapping.  */
-         __nscd_unmap (mapped);
+         if (atomic_decrement_val (&mapped->counter) == 0)
+           __nscd_unmap (mapped);
          mapped = NO_MAPPING;
        }
 
-      goto retry;
+      if (retval != -1)
+       goto retry;
     }
 
   return retval;
index e83e482..03b73a4 100644 (file)
@@ -113,7 +113,6 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
                               &gc_cycle);
 
  retry:;
-  const hst_response_header *hst_resp = NULL;
   const char *h_name = NULL;
   const uint32_t *aliases_len = NULL;
   const char *addr_list = NULL;
@@ -121,18 +120,27 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
   int retval = -1;
   const char *recend = (const char *) ~UINTMAX_C (0);
   int sock = -1;
+  hst_response_header hst_resp;
   if (mapped != NO_MAPPING)
     {
-      const struct datahead *found = __nscd_cache_search (type, key, keylen,
-                                                         mapped);
+      /* No const qualifier, as it can change during garbage collection.  */
+      struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
       if (found != NULL)
        {
-         hst_resp = &found->data[0].hstdata;
-         h_name = (char *) (hst_resp + 1);
-         aliases_len = (uint32_t *) (h_name + hst_resp->h_name_len);
+         h_name = (char *) (&found->data[0].hstdata + 1);
+         hst_resp = found->data[0].hstdata;
+         aliases_len = (uint32_t *) (h_name + hst_resp.h_name_len);
          addr_list = ((char *) aliases_len
-                      + hst_resp->h_aliases_cnt * sizeof (uint32_t));
-         addr_list_len = hst_resp->h_addr_list_cnt * INADDRSZ;
+                      + hst_resp.h_aliases_cnt * sizeof (uint32_t));
+         addr_list_len = hst_resp.h_addr_list_cnt * INADDRSZ;
+         recend = (const char *) found->data + found->recsize;
+         /* Now check if we can trust hst_resp fields.  If GC is
+            in progress, it can contain anything.  */
+         if (mapped->head->gc_cycle != gc_cycle)
+           {
+             retval = -2;
+             goto out;
+           }
 
 #ifndef _STRING_ARCH_unaligned
          /* The aliases_len array in the mapped database might very
@@ -142,51 +150,47 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
          if (((uintptr_t) aliases_len & (__alignof__ (*aliases_len) - 1))
              != 0)
            {
-             uint32_t *tmp = alloca (hst_resp->h_aliases_cnt
+             uint32_t *tmp = alloca (hst_resp.h_aliases_cnt
                                      * sizeof (uint32_t));
              aliases_len = memcpy (tmp, aliases_len,
-                                   hst_resp->h_aliases_cnt
+                                   hst_resp.h_aliases_cnt
                                    * sizeof (uint32_t));
            }
 #endif
          if (type != GETHOSTBYADDR && type != GETHOSTBYNAME)
            {
-             if (hst_resp->h_length == INADDRSZ)
+             if (hst_resp.h_length == INADDRSZ)
                addr_list += addr_list_len;
-             addr_list_len = hst_resp->h_addr_list_cnt * IN6ADDRSZ;
+             addr_list_len = hst_resp.h_addr_list_cnt * IN6ADDRSZ;
            }
-         recend = (const char *) found->data + found->recsize;
          if (__builtin_expect ((const char *) addr_list + addr_list_len
                                > recend, 0))
-           goto out_close;
+           goto out;
        }
     }
 
-  hst_response_header hst_resp_mem;
-  if (hst_resp == NULL)
+  if (h_name == NULL)
     {
-      sock = __nscd_open_socket (key, keylen, type, &hst_resp_mem,
-                                sizeof (hst_resp_mem));
+      sock = __nscd_open_socket (key, keylen, type, &hst_resp,
+                                sizeof (hst_resp));
       if (sock == -1)
        {
          __nss_not_use_nscd_hosts = 1;
          goto out;
        }
-
-      hst_resp = &hst_resp_mem;
     }
 
   /* No value found so far.  */
   *result = NULL;
 
-  if (__builtin_expect (hst_resp->found == -1, 0))
+  if (__builtin_expect (hst_resp.found == -1, 0))
     {
       /* The daemon does not cache this database.  */
       __nss_not_use_nscd_hosts = 1;
       goto out_close;
     }
 
-  if (hst_resp->found == 1)
+  if (hst_resp.found == 1)
     {
       char *cp = buffer;
       uintptr_t align1;
@@ -201,15 +205,15 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
         align the pointer and the base of the h_addr_list pointers.  */
       align1 = ((__alignof__ (char *) - (cp - ((char *) 0)))
                & (__alignof__ (char *) - 1));
-      align2 = ((__alignof__ (char *) - ((cp + align1 + hst_resp->h_name_len)
+      align2 = ((__alignof__ (char *) - ((cp + align1 + hst_resp.h_name_len)
                                         - ((char *) 0)))
                & (__alignof__ (char *) - 1));
-      if (buflen < (align1 + hst_resp->h_name_len + align2
-                   + ((hst_resp->h_aliases_cnt + hst_resp->h_addr_list_cnt
+      if (buflen < (align1 + hst_resp.h_name_len + align2
+                   + ((hst_resp.h_aliases_cnt + hst_resp.h_addr_list_cnt
                        + 2)
                       * sizeof (char *))
-                   + hst_resp->h_addr_list_cnt * (type == AF_INET
-                                                  ? INADDRSZ : IN6ADDRSZ)))
+                   + hst_resp.h_addr_list_cnt * (type == AF_INET
+                                                 ? INADDRSZ : IN6ADDRSZ)))
        {
        no_room:
          *h_errnop = NETDB_INTERNAL;
@@ -221,12 +225,12 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 
       /* Prepare the result as far as we can.  */
       resultbuf->h_aliases = (char **) cp;
-      cp += (hst_resp->h_aliases_cnt + 1) * sizeof (char *);
+      cp += (hst_resp.h_aliases_cnt + 1) * sizeof (char *);
       resultbuf->h_addr_list = (char **) cp;
-      cp += (hst_resp->h_addr_list_cnt + 1) * sizeof (char *);
+      cp += (hst_resp.h_addr_list_cnt + 1) * sizeof (char *);
 
       resultbuf->h_name = cp;
-      cp += hst_resp->h_name_len + align2;
+      cp += hst_resp.h_name_len + align2;
 
       if (type == GETHOSTBYADDR || type == GETHOSTBYNAME)
        {
@@ -238,7 +242,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
          resultbuf->h_addrtype = AF_INET6;
          resultbuf->h_length = IN6ADDRSZ;
        }
-      for (cnt = 0; cnt < hst_resp->h_addr_list_cnt; ++cnt)
+      for (cnt = 0; cnt < hst_resp.h_addr_list_cnt; ++cnt)
        {
          resultbuf->h_addr_list[cnt] = cp;
          cp += resultbuf->h_length;
@@ -250,47 +254,47 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
          struct iovec vec[4];
 
          vec[0].iov_base = resultbuf->h_name;
-         vec[0].iov_len = hst_resp->h_name_len;
-         total_len = hst_resp->h_name_len;
+         vec[0].iov_len = hst_resp.h_name_len;
+         total_len = hst_resp.h_name_len;
          n = 1;
 
-         if (hst_resp->h_aliases_cnt > 0)
+         if (hst_resp.h_aliases_cnt > 0)
            {
-             aliases_len = alloca (hst_resp->h_aliases_cnt
+             aliases_len = alloca (hst_resp.h_aliases_cnt
                                    * sizeof (uint32_t));
              vec[n].iov_base = (void *) aliases_len;
-             vec[n].iov_len = hst_resp->h_aliases_cnt * sizeof (uint32_t);
+             vec[n].iov_len = hst_resp.h_aliases_cnt * sizeof (uint32_t);
 
-             total_len += hst_resp->h_aliases_cnt * sizeof (uint32_t);
+             total_len += hst_resp.h_aliases_cnt * sizeof (uint32_t);
              ++n;
            }
 
          if (type == GETHOSTBYADDR || type == GETHOSTBYNAME)
            {
              vec[n].iov_base = resultbuf->h_addr_list[0];
-             vec[n].iov_len = hst_resp->h_addr_list_cnt * INADDRSZ;
+             vec[n].iov_len = hst_resp.h_addr_list_cnt * INADDRSZ;
 
-             total_len += hst_resp->h_addr_list_cnt * INADDRSZ;
+             total_len += hst_resp.h_addr_list_cnt * INADDRSZ;
 
              ++n;
            }
          else
            {
-             if (hst_resp->h_length == INADDRSZ)
+             if (hst_resp.h_length == INADDRSZ)
                {
-                 ignore = alloca (hst_resp->h_addr_list_cnt * INADDRSZ);
+                 ignore = alloca (hst_resp.h_addr_list_cnt * INADDRSZ);
                  vec[n].iov_base = ignore;
-                 vec[n].iov_len = hst_resp->h_addr_list_cnt * INADDRSZ;
+                 vec[n].iov_len = hst_resp.h_addr_list_cnt * INADDRSZ;
 
-                 total_len += hst_resp->h_addr_list_cnt * INADDRSZ;
+                 total_len += hst_resp.h_addr_list_cnt * INADDRSZ;
 
                  ++n;
                }
 
              vec[n].iov_base = resultbuf->h_addr_list[0];
-             vec[n].iov_len = hst_resp->h_addr_list_cnt * IN6ADDRSZ;
+             vec[n].iov_len = hst_resp.h_addr_list_cnt * IN6ADDRSZ;
 
-             total_len += hst_resp->h_addr_list_cnt * IN6ADDRSZ;
+             total_len += hst_resp.h_addr_list_cnt * IN6ADDRSZ;
 
              ++n;
            }
@@ -300,13 +304,13 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
        }
       else
        {
-         memcpy (resultbuf->h_name, h_name, hst_resp->h_name_len);
+         memcpy (resultbuf->h_name, h_name, hst_resp.h_name_len);
          memcpy (resultbuf->h_addr_list[0], addr_list, addr_list_len);
        }
 
       /*  Now we also can read the aliases.  */
       total_len = 0;
-      for (cnt = 0; cnt < hst_resp->h_aliases_cnt; ++cnt)
+      for (cnt = 0; cnt < hst_resp.h_aliases_cnt; ++cnt)
        {
          resultbuf->h_aliases[cnt] = cp;
          cp += aliases_len[cnt];
@@ -316,10 +320,25 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 
       if (__builtin_expect ((const char *) addr_list + addr_list_len
                            + total_len > recend, 0))
-       goto out_close;
+       {
+         /* aliases_len array might contain garbage during nscd GC cycle,
+            retry rather than fail in that case.  */
+         if (addr_list != NULL && mapped->head->gc_cycle != gc_cycle)
+           retval = -2;
+         goto out_close;
+       }
       /* See whether this would exceed the buffer capacity.  */
       if (__builtin_expect (cp > buffer + buflen, 0))
-       goto no_room;
+       {
+         /* aliases_len array might contain garbage during nscd GC cycle,
+            retry rather than fail in that case.  */
+         if (addr_list != NULL && mapped->head->gc_cycle != gc_cycle)
+           {
+             retval = -2;
+             goto out_close;
+           }
+         goto no_room;
+       }
 
       /* And finally read the aliases.  */
       if (addr_list == NULL)
@@ -338,14 +357,18 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
                  (const char *) addr_list + addr_list_len, total_len);
 
          /* Try to detect corrupt databases.  */
-         if (resultbuf->h_name[hst_resp->h_name_len - 1] != '\0'
-             || ({for (cnt = 0; cnt < hst_resp->h_aliases_cnt; ++cnt)
+         if (resultbuf->h_name[hst_resp.h_name_len - 1] != '\0'
+             || ({for (cnt = 0; cnt < hst_resp.h_aliases_cnt; ++cnt)
                     if (resultbuf->h_aliases[cnt][aliases_len[cnt] - 1]
                         != '\0')
                       break;
-                  cnt < hst_resp->h_aliases_cnt; }))
-           /* We cannot use the database.  */
-           goto out_close;
+                  cnt < hst_resp.h_aliases_cnt; }))
+           {
+             /* We cannot use the database.  */
+             if (mapped->head->gc_cycle != gc_cycle)
+               retval = -2;
+             goto out_close;
+           }
 
          retval = 0;
          *result = resultbuf;
@@ -354,7 +377,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
   else
     {
       /* Store the error number.  */
-      *h_errnop = hst_resp->error;
+      *h_errnop = hst_resp.error;
 
       /* The `errno' to some value != ERANGE.  */
       __set_errno (ENOENT);
@@ -366,19 +389,21 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
-  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
+  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
     {
       /* When we come here this means there has been a GC cycle while we
         were looking for the data.  This means the data might have been
         inconsistent.  Retry if possible.  */
-      if ((gc_cycle & 1) != 0 || ++nretries == 5)
+      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
        {
          /* nscd is just running gc now.  Disable using the mapping.  */
-         __nscd_unmap (mapped);
+         if (atomic_decrement_val (&mapped->counter) == 0)
+           __nscd_unmap (mapped);
          mapped = NO_MAPPING;
        }
 
-      goto retry;
+      if (retval != -1)
+       goto retry;
     }
 
   return retval;
index e8e4d73..b84baa1 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998, 1999, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2003, 2004, 2005, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
 
@@ -88,76 +89,81 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
              struct passwd **result)
 {
   int gc_cycle;
+  int nretries = 0;
+
   /* If the mapping is available, try to search there instead of
      communicating with the nscd.  */
   struct mapped_database *mapped;
   mapped = __nscd_get_map_ref (GETFDPW, "passwd", &map_handle, &gc_cycle);
 
  retry:;
-  const pw_response_header *pw_resp = NULL;
   const char *pw_name = NULL;
   int retval = -1;
   const char *recend = (const char *) ~UINTMAX_C (0);
+  pw_response_header pw_resp;
 
   if (mapped != NO_MAPPING)
     {
-      const struct datahead *found = __nscd_cache_search (type, key, keylen,
-                                                         mapped);
+      struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
       if (found != NULL)
        {
-         pw_resp = &found->data[0].pwdata;
-         pw_name = (const char *) (pw_resp + 1);
+         pw_name = (const char *) (&found->data[0].pwdata + 1);
+         pw_resp = found->data[0].pwdata;
          recend = (const char *) found->data + found->recsize;
+         /* Now check if we can trust pw_resp fields.  If GC is
+            in progress, it can contain anything.  */
+         if (mapped->head->gc_cycle != gc_cycle)
+           {
+             retval = -2;
+             goto out;
+           }
        }
     }
 
-  pw_response_header pw_resp_mem;
   int sock = -1;
-  if (pw_resp == NULL)
+  if (pw_name == NULL)
     {
-      sock = __nscd_open_socket (key, keylen, type, &pw_resp_mem,
-                                sizeof (pw_resp_mem));
+      sock = __nscd_open_socket (key, keylen, type, &pw_resp,
+                                sizeof (pw_resp));
       if (sock == -1)
        {
          __nss_not_use_nscd_passwd = 1;
          goto out;
        }
-
-      pw_resp = &pw_resp_mem;
     }
 
   /* No value found so far.  */
   *result = NULL;
 
-  if (__builtin_expect (pw_resp->found == -1, 0))
+  if (__builtin_expect (pw_resp.found == -1, 0))
     {
       /* The daemon does not cache this database.  */
       __nss_not_use_nscd_passwd = 1;
       goto out_close;
     }
 
-  if (pw_resp->found == 1)
+  if (pw_resp.found == 1)
     {
       /* Set the information we already have.  */
-      resultbuf->pw_uid = pw_resp->pw_uid;
-      resultbuf->pw_gid = pw_resp->pw_gid;
+      resultbuf->pw_uid = pw_resp.pw_uid;
+      resultbuf->pw_gid = pw_resp.pw_gid;
 
       char *p = buffer;
       /* get pw_name */
       resultbuf->pw_name = p;
-      p += pw_resp->pw_name_len;
+      p += pw_resp.pw_name_len;
       /* get pw_passwd */
       resultbuf->pw_passwd = p;
-      p += pw_resp->pw_passwd_len;
+      p += pw_resp.pw_passwd_len;
       /* get pw_gecos */
       resultbuf->pw_gecos = p;
-      p += pw_resp->pw_gecos_len;
+      p += pw_resp.pw_gecos_len;
       /* get pw_dir */
       resultbuf->pw_dir = p;
-      p += pw_resp->pw_dir_len;
+      p += pw_resp.pw_dir_len;
       /* get pw_pshell */
       resultbuf->pw_shell = p;
-      p += pw_resp->pw_shell_len;
+      p += pw_resp.pw_shell_len;
 
       ssize_t total = p - buffer;
       if (__builtin_expect (pw_name + total > recend, 0))
@@ -189,14 +195,14 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
          memcpy (resultbuf->pw_name, pw_name, total);
 
          /* Try to detect corrupt databases.  */
-         if (resultbuf->pw_name[pw_resp->pw_name_len - 1] != '\0'
-             || resultbuf->pw_passwd[pw_resp->pw_passwd_len - 1] != '\0'
-             || resultbuf->pw_gecos[pw_resp->pw_gecos_len - 1] != '\0'
-             || resultbuf->pw_dir[pw_resp->pw_dir_len - 1] != '\0'
-             || resultbuf->pw_shell[pw_resp->pw_shell_len - 1] != '\0')
+         if (resultbuf->pw_name[pw_resp.pw_name_len - 1] != '\0'
+             || resultbuf->pw_passwd[pw_resp.pw_passwd_len - 1] != '\0'
+             || resultbuf->pw_gecos[pw_resp.pw_gecos_len - 1] != '\0'
+             || resultbuf->pw_dir[pw_resp.pw_dir_len - 1] != '\0'
+             || resultbuf->pw_shell[pw_resp.pw_shell_len - 1] != '\0')
            {
              /* We cannot use the database.  */
-             retval = -1;
+             retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
              goto out_close;
            }
 
@@ -215,19 +221,21 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
-  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
+  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
     {
       /* When we come here this means there has been a GC cycle while we
         were looking for the data.  This means the data might have been
         inconsistent.  Retry if possible.  */
-      if ((gc_cycle & 1) != 0)
+      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
        {
          /* nscd is just running gc now.  Disable using the mapping.  */
-         __nscd_unmap (mapped);
+         if (atomic_decrement_val (&mapped->counter) == 0)
+           __nscd_unmap (mapped);
          mapped = NO_MAPPING;
        }
 
-      goto retry;
+      if (retval != -1)
+       goto retry;
     }
 
   return retval;
index ea5dced..a725b1d 100644 (file)
@@ -93,7 +93,6 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
                     "/", 1), proto ?: "", protolen + 1);
 
  retry:;
-  const serv_response_header *serv_resp = NULL;
   const char *s_name = NULL;
   const char *s_proto = NULL;
   const uint32_t *aliases_len = NULL;
@@ -101,19 +100,32 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
   int retval = -1;
   const char *recend = (const char *) ~UINTMAX_C (0);
   int sock = -1;
+  serv_response_header serv_resp;
+
   if (mapped != NO_MAPPING)
     {
-      const struct datahead *found = __nscd_cache_search (type, key, keylen,
-                                                         mapped);
+      struct datahead *found = __nscd_cache_search (type, key, keylen, mapped);
 
       if (found != NULL)
        {
-         serv_resp = &found->data[0].servdata;
-         s_name = (char *) (serv_resp + 1);
-         s_proto = s_name + serv_resp->s_name_len;
-         aliases_len = (uint32_t *) (s_proto + serv_resp->s_proto_len);
+         s_name = (char *) (&found->data[0].servdata + 1);
+         serv_resp = found->data[0].servdata;
+         s_proto = s_name + serv_resp.s_name_len;
+         aliases_len = (uint32_t *) (s_proto + serv_resp.s_proto_len);
          aliases_list = ((char *) aliases_len
-                         + serv_resp->s_aliases_cnt * sizeof (uint32_t));
+                         + serv_resp.s_aliases_cnt * sizeof (uint32_t));
+         recend = (const char *) found->data + found->recsize;
+         /* Now check if we can trust serv_resp fields.  If GC is
+            in progress, it can contain anything.  */
+         if (mapped->head->gc_cycle != gc_cycle)
+           {
+             retval = -2;
+             goto out;
+           }
+         if (__builtin_expect ((const char *) aliases_len
+                               + serv_resp.s_aliases_cnt * sizeof (uint32_t)
+                               > recend, 0))
+           goto out;
 
 #ifndef _STRING_ARCH_unaligned
          /* The aliases_len array in the mapped database might very
@@ -123,46 +135,38 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
          if (((uintptr_t) aliases_len & (__alignof__ (*aliases_len) - 1))
              != 0)
            {
-             uint32_t *tmp = alloca (hst_resp->h_aliases_cnt
+             uint32_t *tmp = alloca (serv_resp.s_aliases_cnt
                                      * sizeof (uint32_t));
              aliases_len = memcpy (tmp, aliases_len,
-                                   hst_resp->h_aliases_cnt
+                                   serv_resp.s_aliases_cnt
                                    * sizeof (uint32_t));
            }
 #endif
-         recend = (const char *) found->data + found->recsize;
-         if (__builtin_expect ((const char *) aliases_len
-                               + serv_resp->s_aliases_cnt * sizeof (uint32_t)
-                               > recend, 0))
-           goto out_close;
        }
     }
 
-  serv_response_header serv_resp_mem;
-  if (serv_resp == NULL)
+  if (s_name == NULL)
     {
-      sock = __nscd_open_socket (key, keylen, type, &serv_resp_mem,
-                                sizeof (serv_resp_mem));
+      sock = __nscd_open_socket (key, keylen, type, &serv_resp,
+                                sizeof (serv_resp));
       if (sock == -1)
        {
          __nss_not_use_nscd_services = 1;
          goto out;
        }
-
-      serv_resp = &serv_resp_mem;
     }
 
   /* No value found so far.  */
   *result = NULL;
 
-  if (__builtin_expect (serv_resp->found == -1, 0))
+  if (__builtin_expect (serv_resp.found == -1, 0))
     {
       /* The daemon does not cache this database.  */
       __nss_not_use_nscd_services = 1;
       goto out_close;
     }
 
-  if (serv_resp->found == 1)
+  if (serv_resp.found == 1)
     {
       char *cp = buf;
       uintptr_t align1;
@@ -176,13 +180,13 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
         align the pointer and the base of the h_addr_list pointers.  */
       align1 = ((__alignof__ (char *) - (cp - ((char *) 0)))
                & (__alignof__ (char *) - 1));
-      align2 = ((__alignof__ (char *) - ((cp + align1 + serv_resp->s_name_len
-                                         + serv_resp->s_proto_len)
+      align2 = ((__alignof__ (char *) - ((cp + align1 + serv_resp.s_name_len
+                                         + serv_resp.s_proto_len)
                                         - ((char *) 0)))
                & (__alignof__ (char *) - 1));
-      if (buflen < (align1 + serv_resp->s_name_len + serv_resp->s_proto_len
+      if (buflen < (align1 + serv_resp.s_name_len + serv_resp.s_proto_len
                    + align2
-                   + (serv_resp->s_aliases_cnt + 1) * sizeof (char *)))
+                   + (serv_resp.s_aliases_cnt + 1) * sizeof (char *)))
        {
        no_room:
          __set_errno (ERANGE);
@@ -193,31 +197,31 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
 
       /* Prepare the result as far as we can.  */
       resultbuf->s_aliases = (char **) cp;
-      cp += (serv_resp->s_aliases_cnt + 1) * sizeof (char *);
+      cp += (serv_resp.s_aliases_cnt + 1) * sizeof (char *);
 
       resultbuf->s_name = cp;
-      cp += serv_resp->s_name_len;
+      cp += serv_resp.s_name_len;
       resultbuf->s_proto = cp;
-      cp += serv_resp->s_proto_len + align2;
-      resultbuf->s_port = serv_resp->s_port;
+      cp += serv_resp.s_proto_len + align2;
+      resultbuf->s_port = serv_resp.s_port;
 
       if (s_name == NULL)
        {
          struct iovec vec[2];
 
          vec[0].iov_base = resultbuf->s_name;
-         vec[0].iov_len = serv_resp->s_name_len + serv_resp->s_proto_len;
+         vec[0].iov_len = serv_resp.s_name_len + serv_resp.s_proto_len;
          total_len = vec[0].iov_len;
          n = 1;
 
-         if (serv_resp->s_aliases_cnt > 0)
+         if (serv_resp.s_aliases_cnt > 0)
            {
-             aliases_len = alloca (serv_resp->s_aliases_cnt
+             aliases_len = alloca (serv_resp.s_aliases_cnt
                                    * sizeof (uint32_t));
              vec[n].iov_base = (void *) aliases_len;
-             vec[n].iov_len = serv_resp->s_aliases_cnt * sizeof (uint32_t);
+             vec[n].iov_len = serv_resp.s_aliases_cnt * sizeof (uint32_t);
 
-             total_len += serv_resp->s_aliases_cnt * sizeof (uint32_t);
+             total_len += serv_resp.s_aliases_cnt * sizeof (uint32_t);
              ++n;
            }
 
@@ -226,11 +230,11 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
        }
       else
        memcpy (resultbuf->s_name, s_name,
-               serv_resp->s_name_len + serv_resp->s_proto_len);
+               serv_resp.s_name_len + serv_resp.s_proto_len);
 
       /*  Now we also can read the aliases.  */
       total_len = 0;
-      for (cnt = 0; cnt < serv_resp->s_aliases_cnt; ++cnt)
+      for (cnt = 0; cnt < serv_resp.s_aliases_cnt; ++cnt)
        {
          resultbuf->s_aliases[cnt] = cp;
          cp += aliases_len[cnt];
@@ -240,10 +244,26 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
 
       if (__builtin_expect ((const char *) aliases_list + total_len > recend,
                            0))
-       goto out_close;
+       {
+         /* aliases_len array might contain garbage during nscd GC cycle,
+            retry rather than fail in that case.  */
+         if (aliases_list != NULL && mapped->head->gc_cycle != gc_cycle)
+           retval = -2;
+         goto out_close;
+       }
+
       /* See whether this would exceed the buffer capacity.  */
       if (__builtin_expect (cp > buf + buflen, 0))
-       goto no_room;
+       {
+         /* aliases_len array might contain garbage during nscd GC cycle,
+            retry rather than fail in that case.  */
+         if (aliases_list != NULL && mapped->head->gc_cycle != gc_cycle)
+           {
+             retval = -2;
+             goto out_close;
+           }
+         goto no_room;
+       }
 
       /* And finally read the aliases.  */
       if (aliases_list == NULL)
@@ -261,15 +281,19 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
          memcpy (resultbuf->s_aliases[0], aliases_list, total_len);
 
          /* Try to detect corrupt databases.  */
-         if (resultbuf->s_name[serv_resp->s_name_len - 1] != '\0'
-             || resultbuf->s_proto[serv_resp->s_proto_len - 1] != '\0'
-             || ({for (cnt = 0; cnt < serv_resp->s_aliases_cnt; ++cnt)
+         if (resultbuf->s_name[serv_resp.s_name_len - 1] != '\0'
+             || resultbuf->s_proto[serv_resp.s_proto_len - 1] != '\0'
+             || ({for (cnt = 0; cnt < serv_resp.s_aliases_cnt; ++cnt)
                     if (resultbuf->s_aliases[cnt][aliases_len[cnt] - 1]
                         != '\0')
                       break;
-                  cnt < serv_resp->s_aliases_cnt; }))
-           /* We cannot use the database.  */
-           goto out_close;
+                  cnt < serv_resp.s_aliases_cnt; }))
+           {
+             /* We cannot use the database.  */
+             if (mapped->head->gc_cycle != gc_cycle)
+               retval = -2;
+             goto out_close;
+           }
 
          retval = 0;
          *result = resultbuf;
@@ -287,19 +311,21 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
-  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
+  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
     {
       /* When we come here this means there has been a GC cycle while we
         were looking for the data.  This means the data might have been
         inconsistent.  Retry if possible.  */
-      if ((gc_cycle & 1) != 0 || ++nretries == 5)
+      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
        {
          /* nscd is just running gc now.  Disable using the mapping.  */
-         __nscd_unmap (mapped);
+         if (atomic_decrement_val (&mapped->counter) == 0)
+           __nscd_unmap (mapped);
          mapped = NO_MAPPING;
        }
 
-      goto retry;
+      if (retval != -1)
+       goto retry;
     }
 
   return retval;
index 7c45981..394b2f8 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2002,2003,2004,2005,2006,2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -21,6 +22,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdbool.h>
+#include <string.h>
 #include <time.h>
 #include <unistd.h>
 #include <sys/mman.h>
@@ -95,16 +97,20 @@ __readvall (int fd, const struct iovec *iov, int iovcnt)
 
 
 static int
-open_socket (void)
+open_socket (request_type type, const char *key, size_t keylen)
 {
   int sock = __socket (PF_UNIX, SOCK_STREAM, 0);
   if (sock < 0)
     return -1;
 
+  struct
+  {
+    request_header req;
+    char key[keylen];
+  } reqdata;
+
   /* Make socket non-blocking.  */
-  int fl = __fcntl (sock, F_GETFL);
-  if (fl != -1)
-    __fcntl (sock, F_SETFL, fl | O_NONBLOCK);
+  __fcntl (sock, F_SETFL, O_RDWR | O_NONBLOCK);
 
   struct sockaddr_un sun;
   sun.sun_family = AF_UNIX;
@@ -113,13 +119,56 @@ open_socket (void)
       && errno != EINPROGRESS)
     goto out;
 
-  struct pollfd fds[1];
-  fds[0].fd = sock;
-  fds[0].events = POLLOUT | POLLERR | POLLHUP;
-  if (__poll (fds, 1, 5 * 1000) > 0)
-    /* Success.  We do not check for success of the connect call here.
-       If it failed, the following operations will fail.  */
-    return sock;
+  reqdata.req.version = NSCD_VERSION;
+  reqdata.req.type = type;
+  reqdata.req.key_len = keylen;
+
+  memcpy (reqdata.key, key, keylen);
+
+  bool first_try = true;
+  struct timeval tvend;
+  while (1)
+    {
+#ifndef MSG_NOSIGNAL
+# define MSG_NOSIGNAL 0
+#endif
+      ssize_t wres = TEMP_FAILURE_RETRY (__send (sock, &reqdata,
+                                                sizeof (reqdata),
+                                                MSG_NOSIGNAL));
+      if (__builtin_expect (wres == (ssize_t) sizeof (reqdata), 1))
+       /* We managed to send the request.  */
+       return sock;
+
+      if (wres != -1 || errno != EAGAIN)
+       /* Something is really wrong, no chance to continue.  */
+       break;
+
+      /* The daemon is busy wait for it.  */
+      int to;
+      if (first_try)
+       {
+         gettimeofday (&tvend, NULL);
+         tvend.tv_sec += 5;
+         to = 5 * 1000;
+         first_try = false;
+       }
+      else
+       {
+         struct timeval now;
+         gettimeofday (&now, NULL);
+         to = ((tvend.tv_sec - now.tv_sec) * 1000
+               + (tvend.tv_usec - now.tv_usec) / 1000);
+       }
+
+      struct pollfd fds[1];
+      fds[0].fd = sock;
+      fds[0].events = POLLOUT | POLLERR | POLLHUP;
+      if (__poll (fds, 1, to) <= 0)
+       /* The connection timed out or broke down.  */
+       break;
+
+      /* We try to write again.  */
+    }
 
  out:
   close_not_cancel_no_status (sock);
@@ -179,36 +228,15 @@ get_mapping (request_type type, const char *key,
   int saved_errno = errno;
 
   int mapfd = -1;
+  char resdata[keylen];
 
-  /* Send the request.  */
-  struct
-  {
-    request_header req;
-    char key[keylen];
-  } reqdata;
-
-  int sock = open_socket ();
+  /* Open a socket and send the request.  */
+  int sock = open_socket (type, key, keylen);
   if (sock < 0)
     goto out;
 
-  reqdata.req.version = NSCD_VERSION;
-  reqdata.req.type = type;
-  reqdata.req.key_len = keylen;
-  memcpy (reqdata.key, key, keylen);
-
-# ifndef MSG_NOSIGNAL
-#  define MSG_NOSIGNAL 0
-# endif
-  if (__builtin_expect (TEMP_FAILURE_RETRY (__send (sock, &reqdata,
-                                                   sizeof (reqdata),
-                                                   MSG_NOSIGNAL))
-                       != sizeof (reqdata), 0))
-    /* We cannot even write the request.  */
-    goto out_close2;
-
   /* Room for the data sent along with the file descriptor.  We expect
      the key name back.  */
-# define resdata reqdata.key
   struct iovec iov[1];
   iov[0].iov_base = resdata;
   iov[0].iov_len = keylen;
@@ -362,7 +390,10 @@ __nscd_get_map_ref (request_type type, const char *name,
 }
 
 
-const struct datahead *
+/* Don't return const struct datahead *, as eventhough the record
+   is normally constant, it can change arbitrarily during nscd
+   garbage collection.  */
+struct datahead *
 __nscd_cache_search (request_type type, const char *key, size_t keylen,
                     const struct mapped_database *mapped)
 {
@@ -374,16 +405,32 @@ __nscd_cache_search (request_type type, const char *key, size_t keylen,
     {
       struct hashentry *here = (struct hashentry *) (mapped->data + work);
 
+#ifndef _STRING_ARCH_unaligned
+      /* Although during garbage collection when moving struct hashentry
+        records around we first copy from old to new location and then
+        adjust pointer from previous hashentry to it, there is no barrier
+        between those memory writes.  It is very unlikely to hit it,
+        so check alignment only if a misaligned load can crash the
+        application.  */
+      if ((uintptr_t) here & (__alignof__ (*here) - 1))
+       return NULL;
+#endif
+
       if (type == here->type
          && keylen == here->len
-         && here->key + here->len <= datasize
+         && here->key + keylen <= datasize
          && memcmp (key, mapped->data + here->key, keylen) == 0
          && here->packet + sizeof (struct datahead) <= datasize)
        {
          /* We found the entry.  Increment the appropriate counter.  */
-         const struct datahead *dh
+         struct datahead *dh
            = (struct datahead *) (mapped->data + here->packet);
 
+#ifndef _STRING_ARCH_unaligned
+         if ((uintptr_t) dh & (__alignof__ (*dh) - 1))
+           return NULL;
+#endif
+
          /* See whether we must ignore the entry or whether something
             is wrong because garbage collection is in progress.  */
          if (dh->usable && here->packet + dh->allocsize <= datasize)
@@ -402,28 +449,22 @@ int
 __nscd_open_socket (const char *key, size_t keylen, request_type type,
                    void *response, size_t responselen)
 {
+  /* This should never happen and it is something the nscd daemon
+     enforces, too.  He it helps to limit the amount of stack
+     used.  */
+  if (keylen > MAXKEYLEN)
+    return -1;
+
   int saved_errno = errno;
 
-  int sock = open_socket ();
+  int sock = open_socket (type, key, keylen);
   if (sock >= 0)
     {
-      request_header req;
-      req.version = NSCD_VERSION;
-      req.type = type;
-      req.key_len = keylen;
-
-      struct iovec vec[2];
-      vec[0].iov_base = &req;
-      vec[0].iov_len = sizeof (request_header);
-      vec[1].iov_base = (void *) key;
-      vec[1].iov_len = keylen;
-
-      ssize_t nbytes = TEMP_FAILURE_RETRY (__writev (sock, vec, 2));
-      if (nbytes == (ssize_t) (sizeof (request_header) + keylen)
-         /* Wait for data.  */
-         && wait_on_socket (sock) > 0)
+      /* Wait for data.  */
+      if (wait_on_socket (sock) > 0)
        {
-         nbytes = TEMP_FAILURE_RETRY (__read (sock, response, responselen));
+         ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, response,
+                                                      responselen));
          if (nbytes == (ssize_t) responselen)
            return sock;
        }
index 97a037d..866455a 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -39,6 +39,7 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
 {
   size_t userlen = strlen (user) + 1;
   int gc_cycle;
+  int nretries = 0;
 
   /* If the mapping is available, try to search there instead of
      communicating with the nscd.  */
@@ -46,44 +47,49 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
   mapped = __nscd_get_map_ref (GETFDGR, "group", &__gr_map_handle, &gc_cycle);
 
  retry:;
-  const initgr_response_header *initgr_resp = NULL;
   char *respdata = NULL;
   int retval = -1;
   int sock = -1;
+  initgr_response_header initgr_resp;
 
   if (mapped != NO_MAPPING)
     {
-      const struct datahead *found = __nscd_cache_search (INITGROUPS, user,
-                                                         userlen, mapped);
+      struct datahead *found = __nscd_cache_search (INITGROUPS, user,
+                                                   userlen, mapped);
       if (found != NULL)
        {
-         initgr_resp = &found->data[0].initgrdata;
-         respdata = (char *) (initgr_resp + 1);
+         respdata = (char *) (&found->data[0].initgrdata + 1);
+         initgr_resp = found->data[0].initgrdata;
          char *recend = (char *) found->data + found->recsize;
 
-         if (respdata + initgr_resp->ngrps * sizeof (int32_t) > recend)
+         /* Now check if we can trust initgr_resp fields.  If GC is
+            in progress, it can contain anything.  */
+         if (mapped->head->gc_cycle != gc_cycle)
+           {
+             retval = -2;
+             goto out;
+           }
+
+         if (respdata + initgr_resp.ngrps * sizeof (int32_t) > recend)
            goto out;
        }
     }
 
   /* If we do not have the cache mapped, try to get the data over the
      socket.  */
-  initgr_response_header initgr_resp_mem;
-  if (initgr_resp == NULL)
+  if (respdata == NULL)
     {
-      sock = __nscd_open_socket (user, userlen, INITGROUPS, &initgr_resp_mem,
-                                sizeof (initgr_resp_mem));
+      sock = __nscd_open_socket (user, userlen, INITGROUPS, &initgr_resp,
+                                sizeof (initgr_resp));
       if (sock == -1)
        {
          /* nscd not running or wrong version.  */
          __nss_not_use_nscd_group = 1;
          goto out;
        }
-
-      initgr_resp = &initgr_resp_mem;
     }
 
-  if (initgr_resp->found == 1)
+  if (initgr_resp.found == 1)
     {
       /* The following code assumes that gid_t and int32_t are the
         same size.  This is the case for al existing implementation.
@@ -91,40 +97,40 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
         doesn't use memcpy but instead copies each array element one
         by one.  */
       assert (sizeof (int32_t) == sizeof (gid_t));
-      assert (initgr_resp->ngrps >= 0);
+      assert (initgr_resp.ngrps >= 0);
 
       /* Make sure we have enough room.  We always count GROUP in even
         though we might not end up adding it.  */
-      if (*size < initgr_resp->ngrps + 1)
+      if (*size < initgr_resp.ngrps + 1)
        {
          gid_t *newp = realloc (*groupsp,
-                                (initgr_resp->ngrps + 1) * sizeof (gid_t));
+                                (initgr_resp.ngrps + 1) * sizeof (gid_t));
          if (newp == NULL)
            /* We cannot increase the buffer size.  */
            goto out_close;
 
          *groupsp = newp;
-         *size = initgr_resp->ngrps + 1;
+         *size = initgr_resp.ngrps + 1;
        }
 
       if (respdata == NULL)
        {
          /* Read the data from the socket.  */
-         if ((size_t) __readall (sock, *groupsp, initgr_resp->ngrps
+         if ((size_t) __readall (sock, *groupsp, initgr_resp.ngrps
                                                  * sizeof (gid_t))
-             == initgr_resp->ngrps * sizeof (gid_t))
-           retval = initgr_resp->ngrps;
+             == initgr_resp.ngrps * sizeof (gid_t))
+           retval = initgr_resp.ngrps;
        }
       else
        {
          /* Just copy the data.  */
-         retval = initgr_resp->ngrps;
+         retval = initgr_resp.ngrps;
          memcpy (*groupsp, respdata, retval * sizeof (gid_t));
        }
     }
   else
     {
-      if (__builtin_expect (initgr_resp->found == -1, 0))
+      if (__builtin_expect (initgr_resp.found == -1, 0))
        {
          /* The daemon does not cache this database.  */
          __nss_not_use_nscd_group = 1;
@@ -153,19 +159,21 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out:
-  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1)
+  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
     {
       /* When we come here this means there has been a GC cycle while we
         were looking for the data.  This means the data might have been
         inconsistent.  Retry if possible.  */
-      if ((gc_cycle & 1) != 0)
+      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
        {
          /* nscd is just running gc now.  Disable using the mapping.  */
-         __nscd_unmap (mapped);
+         if (atomic_decrement_val (&mapped->counter) == 0)
+           __nscd_unmap (mapped);
          mapped = NO_MAPPING;
        }
 
-      goto retry;
+      if (retval != -1)
+       goto retry;
     }
 
   return retval;
index c529fa4..bc3c47f 100644 (file)
@@ -38,7 +38,7 @@ NF > 1 {
   if (test)
     print "  TEST (" name ", \"" FILENAME ":" FNR "\", " $0 ")";
   else
-    printf "asm (\"@@@name@@@%s@@@value@@@%%0@@@end@@@\" : : \"i\" (%s));\n",
+    printf "asm (\"@@@name@@@%s@@@value@@@%%0@@@end@@@\" : : \"i\" ((long) %s));\n",
       name, $0;
 }
 
index 37bcdb3..9822055 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+# Copyright (C) 1991-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
@@ -54,7 +54,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
         tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \
         tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 bug15 \
         tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
-        tst-fwrite bug16
+        tst-fwrite bug16 bug17
 
 test-srcs = tst-unbputc tst-printf
 
index f61b23f..373843f 100644 (file)
@@ -1,5 +1,5 @@
 /* Internal function for converting integers to ASCII.
-   Copyright (C) 1994, 1995, 1996, 1999, 2000, 2002, 2003, 2004
+   Copyright (C) 1994, 1995, 1996, 1999, 2000, 2002, 2003, 2004, 2007
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Torbjorn Granlund <tege@matematik.su.se>
@@ -22,6 +22,7 @@
 
 #include <gmp-mparam.h>
 #include <gmp.h>
+#include <limits.h>
 #include <stdlib/gmp-impl.h>
 #include <stdlib/longlong.h>
 
@@ -78,10 +79,12 @@ struct base_table_t
 #endif
 
 
+/* We do not compile _itoa if we always can use _itoa_word.  */
+#if LLONG_MAX != LONG_MAX
 /* Local variables.  */
 const struct base_table_t _itoa_base_table[] attribute_hidden =
 {
-#if BITS_PER_MP_LIMB == 64
+# if BITS_PER_MP_LIMB == 64
   /*  2 */ {SEL1(0ull) 1, 1},
   /*  3 */ {SEL1(0xaaaaaaaaaaaaaaabull) 0, 1},
   /*  4 */ {SEL1(0ull) 1, 2},
@@ -117,8 +120,8 @@ const struct base_table_t _itoa_base_table[] attribute_hidden =
   /* 34 */ {SEL1(0xf0f0f0f0f0f0f0f1ull) 0, 5},
   /* 35 */ {SEL1(0xea0ea0ea0ea0ea0full) 0, 5},
   /* 36 */ {SEL1(0xe38e38e38e38e38full) 0, 5}
-#endif
-#if BITS_PER_MP_LIMB == 32
+# endif
+# if BITS_PER_MP_LIMB == 32
   /*  2 */ {SEL1(0ul) 1, 1, {0, 31, 0x80000000ul SEL2(0xfffffffful)}},
   /*  3 */ {SEL1(0xaaaaaaabul) 0, 1, {0, 20, 0xcfd41b91ul SEL2(0x3b563c24ul)}},
   /*  4 */ {SEL1(0ul) 1, 2, {1, 15, 0x40000000ul SEL2(0xfffffffful)}},
@@ -154,8 +157,9 @@ const struct base_table_t _itoa_base_table[] attribute_hidden =
   /* 34 */ {SEL1(0xf0f0f0f1ul) 0, 5, {1, 6, 0x5c13d840ul SEL2(0x63dfc229ul)}},
   /* 35 */ {SEL1(0xd41d41d5ul) 1, 6, {1, 6, 0x6d91b519ul SEL2(0x2b0fee30ul)}},
   /* 36 */ {SEL1(0x38e38e39ul) 0, 3, {0, 6, 0x81bf1000ul SEL2(0xf91bd1b6ul)}}
-#endif
+# endif
 };
+#endif
 
 /* Lower-case digits.  */
 extern const char _itoa_lower_digits[];
@@ -201,6 +205,7 @@ _itoa_word (unsigned long value, char *buflim,
 #undef SPECIAL
 
 
+#if LLONG_MAX != LONG_MAX
 char *
 _itoa (value, buflim, base, upper_case)
      unsigned long long int value;
@@ -215,7 +220,7 @@ _itoa (value, buflim, base, upper_case)
 
   switch (base)
     {
-#define RUN_2N(BITS) \
+# define RUN_2N(BITS) \
       do                                                                     \
         {                                                                    \
          /* `unsigned long long int' always has 64 bits.  */                 \
@@ -269,7 +274,8 @@ _itoa (value, buflim, base, upper_case)
 
     default:
       {
-#if BITS_PER_MP_LIMB == 64
+       char *bufend = buflim;
+# if BITS_PER_MP_LIMB == 64
        mp_limb_t base_multiplier = brec->base_multiplier;
        if (brec->flag)
          while (value != 0)
@@ -293,8 +299,8 @@ _itoa (value, buflim, base, upper_case)
              *--buflim = digits[rem];
              value = quo;
            }
-#endif
-#if BITS_PER_MP_LIMB == 32
+# endif
+# if BITS_PER_MP_LIMB == 32
        mp_limb_t t[3];
        int n;
 
@@ -302,11 +308,11 @@ _itoa (value, buflim, base, upper_case)
           Optimize for frequent cases of 32 bit numbers.  */
        if ((mp_limb_t) (value >> 32) >= 1)
          {
-#if UDIV_TIME > 2 * UMUL_TIME || UDIV_NEEDS_NORMALIZATION
+#  if UDIV_TIME > 2 * UMUL_TIME || UDIV_NEEDS_NORMALIZATION
            int big_normalization_steps = brec->big.normalization_steps;
            mp_limb_t big_base_norm
              = brec->big.base << big_normalization_steps;
-#endif
+#  endif
            if ((mp_limb_t) (value >> 32) >= brec->big.base)
              {
                mp_limb_t x1hi, x1lo, r;
@@ -315,7 +321,7 @@ _itoa (value, buflim, base, upper_case)
                   always be very small.  It might be faster just to
                   subtract in a tight loop.  */
 
-#if UDIV_TIME > 2 * UMUL_TIME
+#  if UDIV_TIME > 2 * UMUL_TIME
                mp_limb_t x, xh, xl;
 
                if (big_normalization_steps == 0)
@@ -340,7 +346,7 @@ _itoa (value, buflim, base, upper_case)
                udiv_qrnnd_preinv (t[0], x, xh, xl, big_base_norm,
                                   brec->big.base_ninv);
                t[1] = x >> big_normalization_steps;
-#elif UDIV_NEEDS_NORMALIZATION
+#  elif UDIV_NEEDS_NORMALIZATION
                mp_limb_t x, xh, xl;
 
                if (big_normalization_steps == 0)
@@ -362,17 +368,17 @@ _itoa (value, buflim, base, upper_case)
                xl = x1lo << big_normalization_steps;
                udiv_qrnnd (t[0], x, xh, xl, big_base_norm);
                t[1] = x >> big_normalization_steps;
-#else
+#  else
                udiv_qrnnd (x1hi, r, 0, (mp_limb_t) (value >> 32),
                            brec->big.base);
                udiv_qrnnd (x1lo, t[2], r, (mp_limb_t) value, brec->big.base);
                udiv_qrnnd (t[0], t[1], x1hi, x1lo, brec->big.base);
-#endif
+#  endif
                n = 3;
              }
            else
              {
-#if (UDIV_TIME > 2 * UMUL_TIME)
+#  if UDIV_TIME > 2 * UMUL_TIME
                mp_limb_t x;
 
                value <<= brec->big.normalization_steps;
@@ -380,17 +386,17 @@ _itoa (value, buflim, base, upper_case)
                                   (mp_limb_t) value, big_base_norm,
                                   brec->big.base_ninv);
                t[1] = x >> brec->big.normalization_steps;
-#elif UDIV_NEEDS_NORMALIZATION
+#  elif UDIV_NEEDS_NORMALIZATION
                mp_limb_t x;
 
                value <<= big_normalization_steps;
                udiv_qrnnd (t[0], x, (mp_limb_t) (value >> 32),
                            (mp_limb_t) value, big_base_norm);
                t[1] = x >> big_normalization_steps;
-#else
+#  else
                udiv_qrnnd (t[0], t[1], (mp_limb_t) (value >> 32),
                            (mp_limb_t) value, brec->big.base);
-#endif
+#  endif
                n = 2;
              }
          }
@@ -406,7 +412,7 @@ _itoa (value, buflim, base, upper_case)
            mp_limb_t ti = t[--n];
            int ndig_for_this_limb = 0;
 
-#if UDIV_TIME > 2 * UMUL_TIME
+#  if UDIV_TIME > 2 * UMUL_TIME
            mp_limb_t base_multiplier = brec->base_multiplier;
            if (brec->flag)
              while (ti != 0)
@@ -432,7 +438,7 @@ _itoa (value, buflim, base, upper_case)
                  ti = quo;
                  ++ndig_for_this_limb;
                }
-#else
+#  else
            while (ti != 0)
              {
                mp_limb_t quo, rem;
@@ -443,7 +449,7 @@ _itoa (value, buflim, base, upper_case)
                ti = quo;
                ++ndig_for_this_limb;
              }
-#endif
+#  endif
            /* If this wasn't the most significant word, pad with zeros.  */
            if (n != 0)
              while (ndig_for_this_limb < brec->big.ndigits)
@@ -453,13 +459,16 @@ _itoa (value, buflim, base, upper_case)
                }
          }
        while (n != 0);
-#endif
+# endif
+       if (buflim == bufend)
+         *--buflim = '0';
       }
       break;
     }
 
   return buflim;
 }
+#endif
 
 char *
 _fitoa_word (unsigned long value, char *buf, unsigned int base, int upper_case)
@@ -471,6 +480,7 @@ _fitoa_word (unsigned long value, char *buf, unsigned int base, int upper_case)
   return buf;
 }
 
+#if LLONG_MAX != LONG_MAX
 char *
 _fitoa (unsigned long long value, char *buf, unsigned int base, int upper_case)
 {
@@ -480,3 +490,4 @@ _fitoa (unsigned long long value, char *buf, unsigned int base, int upper_case)
     *buf++ = *cp++;
   return buf;
 }
+#endif
index 21a9c39..6d9812f 100644 (file)
@@ -1,5 +1,5 @@
 /* Internal function for converting integers to ASCII.
-   Copyright (C) 1994,95,96,97,98,99,2002,2003 Free Software Foundation, Inc.
+   Copyright (C) 1994-1999,2002,2003,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
@@ -19,7 +19,8 @@
 
 #ifndef _ITOA_H
 #define _ITOA_H
-#include <sys/cdefs.h>
+
+#include <limits.h>
 
 /* Convert VALUE into ASCII in base BASE (2..36).
    Write backwards starting the character just before BUFLIM.
@@ -81,4 +82,12 @@ extern char *_fitoa_word (unsigned long value, char *buf, unsigned int base,
 extern char *_fitoa (unsigned long long value, char *buf, unsigned int base,
                     int upper_case) attribute_hidden;
 
+#if LONG_MAX == LLONG_MAX
+/* No need for special long long versions.  */
+# define _itoa(value, buf, base, upper_case) \
+  _itoa_word (value, buf, base, upper_case)
+# define _fitoa(value, buf, base, upper_case) \
+  _fitoa_word (value, buf, base, upper_case)
+#endif
+
 #endif /* itoa.h */
index b9cc341..09a961d 100644 (file)
@@ -1,5 +1,5 @@
 /* Internal function for converting integers to ASCII.
-   Copyright (C) 1994,1995,1996,1999,2000,2002 Free Software Foundation, Inc.
+   Copyright (C) 1994-1996,1999,2000,2002,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Torbjorn Granlund <tege@matematik.su.se>
    and Ulrich Drepper <drepper@gnu.org>.
@@ -21,6 +21,7 @@
 
 #include <gmp-mparam.h>
 #include <gmp.h>
+#include <limits.h>
 #include <stdlib/gmp-impl.h>
 #include <stdlib/longlong.h>
 
@@ -85,6 +86,7 @@ extern const wchar_t _itowa_lower_digits[] attribute_hidden;
 extern const wchar_t _itowa_upper_digits[] attribute_hidden;
 
 
+#if LLONG_MAX != LONG_MAX
 wchar_t *
 _itowa (value, buflim, base, upper_case)
      unsigned long long int value;
@@ -99,7 +101,7 @@ _itowa (value, buflim, base, upper_case)
 
   switch (base)
     {
-#define RUN_2N(BITS) \
+# define RUN_2N(BITS) \
       do                                                                     \
         {                                                                    \
          /* `unsigned long long int' always has 64 bits.  */                 \
@@ -153,7 +155,7 @@ _itowa (value, buflim, base, upper_case)
 
     default:
       {
-#if BITS_PER_MP_LIMB == 64
+# if BITS_PER_MP_LIMB == 64
        mp_limb_t base_multiplier = brec->base_multiplier;
        if (brec->flag)
          while (value != 0)
@@ -177,8 +179,8 @@ _itowa (value, buflim, base, upper_case)
              *--bp = digits[rem];
              value = quo;
            }
-#endif
-#if BITS_PER_MP_LIMB == 32
+# endif
+# if BITS_PER_MP_LIMB == 32
        mp_limb_t t[3];
        int n;
 
@@ -186,11 +188,11 @@ _itowa (value, buflim, base, upper_case)
           Optimize for frequent cases of 32 bit numbers.  */
        if ((mp_limb_t) (value >> 32) >= 1)
          {
-#if UDIV_TIME > 2 * UMUL_TIME || UDIV_NEEDS_NORMALIZATION
+# if UDIV_TIME > 2 * UMUL_TIME || UDIV_NEEDS_NORMALIZATION
            int big_normalization_steps = brec->big.normalization_steps;
            mp_limb_t big_base_norm
              = brec->big.base << big_normalization_steps;
-#endif
+# endif
            if ((mp_limb_t) (value >> 32) >= brec->big.base)
              {
                mp_limb_t x1hi, x1lo, r;
@@ -199,7 +201,7 @@ _itowa (value, buflim, base, upper_case)
                   always be very small.  It might be faster just to
                   subtract in a tight loop.  */
 
-#if UDIV_TIME > 2 * UMUL_TIME
+# if UDIV_TIME > 2 * UMUL_TIME
                mp_limb_t x, xh, xl;
 
                if (big_normalization_steps == 0)
@@ -224,7 +226,7 @@ _itowa (value, buflim, base, upper_case)
                udiv_qrnnd_preinv (t[0], x, xh, xl, big_base_norm,
                                   brec->big.base_ninv);
                t[1] = x >> big_normalization_steps;
-#elif UDIV_NEEDS_NORMALIZATION
+# elif UDIV_NEEDS_NORMALIZATION
                mp_limb_t x, xh, xl;
 
                if (big_normalization_steps == 0)
@@ -246,17 +248,17 @@ _itowa (value, buflim, base, upper_case)
                xl = x1lo << big_normalization_steps;
                udiv_qrnnd (t[0], x, xh, xl, big_base_norm);
                t[1] = x >> big_normalization_steps;
-#else
+# else
                udiv_qrnnd (x1hi, r, 0, (mp_limb_t) (value >> 32),
                            brec->big.base);
                udiv_qrnnd (x1lo, t[2], r, (mp_limb_t) value, brec->big.base);
                udiv_qrnnd (t[0], t[1], x1hi, x1lo, brec->big.base);
-#endif
+# endif
                n = 3;
              }
            else
              {
-#if (UDIV_TIME > 2 * UMUL_TIME)
+# if UDIV_TIME > 2 * UMUL_TIME
                mp_limb_t x;
 
                value <<= brec->big.normalization_steps;
@@ -264,17 +266,17 @@ _itowa (value, buflim, base, upper_case)
                                   (mp_limb_t) value, big_base_norm,
                                   brec->big.base_ninv);
                t[1] = x >> brec->big.normalization_steps;
-#elif UDIV_NEEDS_NORMALIZATION
+# elif UDIV_NEEDS_NORMALIZATION
                mp_limb_t x;
 
                value <<= big_normalization_steps;
                udiv_qrnnd (t[0], x, (mp_limb_t) (value >> 32),
                            (mp_limb_t) value, big_base_norm);
                t[1] = x >> big_normalization_steps;
-#else
+# else
                udiv_qrnnd (t[0], t[1], (mp_limb_t) (value >> 32),
                            (mp_limb_t) value, brec->big.base);
-#endif
+# endif
                n = 2;
              }
          }
@@ -290,7 +292,7 @@ _itowa (value, buflim, base, upper_case)
            mp_limb_t ti = t[--n];
            int ndig_for_this_limb = 0;
 
-#if UDIV_TIME > 2 * UMUL_TIME
+# if UDIV_TIME > 2 * UMUL_TIME
            mp_limb_t base_multiplier = brec->base_multiplier;
            if (brec->flag)
              while (ti != 0)
@@ -316,7 +318,7 @@ _itowa (value, buflim, base, upper_case)
                  ti = quo;
                  ++ndig_for_this_limb;
                }
-#else
+# else
            while (ti != 0)
              {
                mp_limb_t quo, rem;
@@ -327,7 +329,7 @@ _itowa (value, buflim, base, upper_case)
                ti = quo;
                ++ndig_for_this_limb;
              }
-#endif
+# endif
            /* If this wasn't the most significant word, pad with zeros.  */
            if (n != 0)
              while (ndig_for_this_limb < brec->big.ndigits)
@@ -337,10 +339,11 @@ _itowa (value, buflim, base, upper_case)
                }
          }
        while (n != 0);
-#endif
+# endif
       }
       break;
     }
 
   return bp;
 }
+#endif
diff --git a/stdio-common/bug17.c b/stdio-common/bug17.c
new file mode 100644 (file)
index 0000000..2ef3986
--- /dev/null
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <string.h>
+
+static int
+do_test (void)
+{
+  static const char expect[] = "0, 0, 0";
+  char buf[100];
+  int status = 0;
+
+  static const char fmt1[] = "%0d, %0ld, %0lld";
+  snprintf (buf, sizeof (buf), fmt1, 0, 0L, 0LL);
+  if (strcmp (buf, expect) != 0)
+    {
+      printf ("\"%s\": got \"%s\", expected \"%s\"\n", fmt1, buf, expect);
+      status = 1;
+    }
+
+  static const char fmt2[] = "%0u, %0lu, %0llu";
+  snprintf (buf, sizeof (buf), fmt2, 0u, 0uL, 0uLL);
+  if (strcmp (buf, expect) != 0)
+    {
+      printf ("\"%s\": got \"%s\", expected \"%s\"\n", fmt2, buf, expect);
+      status = 1;
+    }
+
+  return status;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
index f087022..d4ec224 100644 (file)
@@ -40,7 +40,7 @@ routines      := strcat strchr strcmp strcoll strcpy strcspn          \
                                     addsep replace)                    \
                   envz basename                                        \
                   strcoll_l strxfrm_l string-inlines memrchr           \
-                  xpg-strerror
+                  xpg-strerror strerror_l
 
 # Gcc internally generates calls to unbounded memcpy and memset
 # for -fbounded-pointer compiles.  Glibc uses memchr for explicit checks.
index ee5dee9..f145fd3 100644 (file)
@@ -77,4 +77,7 @@ libc {
     # x*
     __xpg_strerror_r;
   }
+  GLIBC_2.6 {
+    strerror_l;
+  }
 }
diff --git a/string/strerror_l.c b/string/strerror_l.c
new file mode 100644 (file)
index 0000000..348a3c5
--- /dev/null
@@ -0,0 +1,71 @@
+/* Copyright (C) 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <libintl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+
+
+static __thread char *last_value;
+
+
+static const char *
+translate (const char *str, locale_t loc)
+{
+  locale_t oldloc = __uselocale (loc);
+  const char *res = _(str);
+  __uselocale (oldloc);
+  return res;
+}
+
+
+/* Return a string describing the errno code in ERRNUM.  */
+char *
+strerror_l (int errnum, locale_t loc)
+{
+
+
+  if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal
+                       || _sys_errlist_internal[errnum] == NULL, 0))
+    {
+      free (last_value);
+      if (__asprintf (&last_value, "%s%d",
+                     translate ("Unknown error ", loc), errnum) == -1)
+       last_value = NULL;
+
+      return last_value;
+    }
+
+  return (char *) translate (_sys_errlist_internal[errnum], loc);
+}
+
+
+#ifdef _LIBC
+# ifdef _LIBC_REENTRANT
+/* This is called when a thread is exiting to free the last_value string.  */
+static void __attribute__ ((section ("__libc_thread_freeres_fn")))
+strerror_thread_freeres (void)
+{
+  free (last_value);
+}
+text_set_element (__libc_thread_subfreeres, strerror_thread_freeres);
+text_set_element (__libc_subfreeres, strerror_thread_freeres);
+# endif
+#endif
index 1adf925..5e1a96f 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1993, 1995-2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1993, 1995-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
@@ -283,6 +283,12 @@ extern char *strerror_r (int __errnum, char *__buf, size_t __buflen)
 # endif
 #endif
 
+#ifdef __USE_GNU
+/* Translate error number to string according to the locale L.  */
+extern char *strerror_l (int __errnum, __locale_t __l) __THROW;
+#endif
+
+
 /* We define this function always since `bzero' is sometimes needed when
    the namespace rules does not allow this.  */
 extern void __bzero (void *__s, size_t __n) __THROW __nonnull ((1));
index bed2755..3baad85 100644 (file)
@@ -1,5 +1,6 @@
 /* Macros to swap the order of bytes in integer values.
-   Copyright (C) 1997,1998,2000,2002,2003,2006 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 2000, 2002, 2003, 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
@@ -66,7 +67,8 @@ __bswap_16 (unsigned short int __bsx)
    `bswap' opcode.  On i386 we have to use three instructions.  */
 #  if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \
       && !defined __pentium4__ && !defined __k8__ && !defined __athlon__ \
-      && !defined __k6__
+      && !defined __k6__ && !defined __nocona__ && !defined __core2__ \
+      && !defined __geode__
 #   define __bswap_32(x)                                                     \
      (__extension__                                                          \
       ({ register unsigned int __v, __x = (x);                               \
index fd87eb7..f991797 100644 (file)
@@ -1,5 +1,5 @@
 /* PLT trampolines.  i386 version.
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2004, 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
@@ -101,29 +101,29 @@ _dl_runtime_profile:
        */
        cfi_adjust_cfa_offset (12)
 1:     movl %ebx, (%esp)
-       cfi_rel_offset (3, 0)
+       cfi_rel_offset (ebx, 0)
        movl %edx, %ebx         # This is the frame buffer size
        pushl %edi
        cfi_adjust_cfa_offset (4)
-       cfi_rel_offset (7, 0)
+       cfi_rel_offset (edi, 0)
        pushl %esi
        cfi_adjust_cfa_offset (4)
-       cfi_rel_offset (6, 0)
+       cfi_rel_offset (esi, 0)
        leal 44(%esp), %esi
        movl %ebx, %ecx
        movl %esp, %edi
        subl %ebx, %edi
        andl $0xfffffff0, %edi  # Align stack
        movl %esp, %ebx
-       cfi_def_cfa_register (3)
+       cfi_def_cfa_register (ebx)
        movl %edi, %esp
        shrl $2, %ecx
        rep
        movsl
        movl (%edi), %esi
-       cfi_restore (6)
+       cfi_restore (esi)
        movl 4(%edi), %edi
-       cfi_restore (7)
+       cfi_restore (edi)
        /*
           %ebx+40  return address
           %ebx+36  PLT1
@@ -144,9 +144,9 @@ _dl_runtime_profile:
        movl 20(%ebx), %eax
        call *(%ebx)
        movl %ebx, %esp
-       cfi_def_cfa_register (4)
+       cfi_def_cfa_register (esp)
        movl 8(%esp), %ebx
-       cfi_restore (3)
+       cfi_restore (ebx)
        /*
            +40     return address
            +36     PLT1
index 035e4f5..6252e91 100644 (file)
@@ -1,6 +1,6 @@
 /* Ceil (round to +inf) long double floating-point values.
    IBM extended format long double version.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 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
@@ -19,7 +19,6 @@
    02111-1307 USA.  */
 
 #include <math.h>
-#include <fenv_libc.h>
 #include <math_ldbl_opt.h>
 #include <float.h>
 #include <ieee754.h>
@@ -44,11 +43,9 @@ __ceill (x)
                                             __builtin_inf ()), 1))
     {
       double orig_xh;
-      int save_round = fegetround ();
 
       /* Long double arithmetic, including the canonicalisation below,
         only works in round-to-nearest mode.  */
-      fesetround (FE_TONEAREST);
 
       /* Convert the high double to integer.  */
       orig_xh = xh;
@@ -81,8 +78,6 @@ __ceill (x)
       /* Ensure we return -0 rather than +0 when appropriate.  */
       if (orig_xh < 0.0)
        xh = -__builtin_fabs (xh);
-
-      fesetround (save_round);
     }
 
   return ldbl_pack (xh, xl);
index 7e7b441..1a198c1 100644 (file)
@@ -25,6 +25,7 @@ static char rcsid[] = "$NetBSD: $";
 
 #include "math.h"
 #include "math_private.h"
+#include <math_ldbl_opt.h>
 
 #ifdef __STDC__
        long double __copysignl(long double x, long double y)
@@ -33,13 +34,13 @@ static char rcsid[] = "$NetBSD: $";
        long double x,y;
 #endif
 {
-  if (y < 0.0)
-    {
-      if (x >= 0.0)
-       x = -x;
-    }
-  else if (x < 0.0)
+  if (signbit (x) != signbit (y))
     x = -x;
   return x;
 }
-weak_alias (__copysignl, copysignl)
+
+#ifdef IS_IN_libm
+long_double_symbol (libm, __copysignl, copysignl);
+#else
+long_double_symbol (libc, __copysignl, copysignl);
+#endif
index 6266312..89eb205 100644 (file)
@@ -37,7 +37,7 @@ static char rcsid[] = "$NetBSD: $";
        GET_LDOUBLE_WORDS64(hx,lx,x);
        lx = lx ^ ( hx & 0x8000000000000000LL );
        hx = hx & 0x7fffffffffffffffLL;
-       SET_LDOUBLE_WORDS64(hx,lx,x);
-        return x;
+       SET_LDOUBLE_WORDS64(x,hx,lx);
+       return x;
 }
 long_double_symbol (libm, __fabsl, fabsl);
index 4c4ae9b..eff7572 100644 (file)
@@ -1,6 +1,6 @@
 /* Round to int long double floating-point values.
    IBM extended format long double version.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 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
@@ -19,7 +19,6 @@
    02111-1307 USA.  */
 
 #include <math.h>
-#include <fenv_libc.h>
 #include <math_ldbl_opt.h>
 #include <float.h>
 #include <ieee754.h>
@@ -43,11 +42,8 @@ __floorl (x)
                        && __builtin_isless (__builtin_fabs (xh),
                                             __builtin_inf ()), 1))
     {
-      int save_round = fegetround ();
-
       /* Long double arithmetic, including the canonicalisation below,
         only works in round-to-nearest mode.  */
-      fesetround (FE_TONEAREST);
 
       /* Convert the high double to integer.  */
       hi = ldbl_nearbyint (xh);
@@ -75,8 +71,6 @@ __floorl (x)
       xh = hi;
       xl = lo;
       ldbl_canonicalize (&xh, &xl);
-
-      fesetround (save_round);
     }
 
   return ldbl_pack (xh, xl);
index 0880e6e..d633bfa 100644 (file)
@@ -1,6 +1,6 @@
 /* Round to int long double floating-point values.
    IBM extended format long double version.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 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
@@ -22,7 +22,6 @@
    when it's coded in C.  */
 
 #include <math.h>
-#include <fenv_libc.h>
 #include <math_ldbl_opt.h>
 #include <float.h>
 #include <ieee754.h>
@@ -47,11 +46,9 @@ __roundl (x)
                                             __builtin_inf ()), 1))
     {
       double orig_xh;
-      int save_round = fegetround ();
 
       /* Long double arithmetic, including the canonicalisation below,
         only works in round-to-nearest mode.  */
-      fesetround (FE_TONEAREST);
 
       /* Convert the high double to integer.  */
       orig_xh = xh;
@@ -88,8 +85,6 @@ __roundl (x)
       xh = hi;
       xl = lo;
       ldbl_canonicalize (&xh, &xl);
-
-      fesetround (save_round);
     }
 
   return ldbl_pack (xh, xl);
index d7bc47e..ceace0d 100644 (file)
@@ -1,6 +1,6 @@
 /* Truncate (toward zero) long double floating-point values.
    IBM extended format long double version.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 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
@@ -22,7 +22,6 @@
    when it's coded in C.  */
 
 #include <math.h>
-#include <fenv_libc.h>
 #include <math_ldbl_opt.h>
 #include <float.h>
 #include <ieee754.h>
@@ -47,11 +46,9 @@ __truncl (x)
                                             __builtin_inf ()), 1))
     {
       double orig_xh;
-      int save_round = fegetround ();
 
       /* Long double arithmetic, including the canonicalisation below,
         only works in round-to-nearest mode.  */
-      fesetround (FE_TONEAREST);
 
       /* Convert the high double to integer.  */
       orig_xh = xh;
@@ -92,8 +89,6 @@ __truncl (x)
       /* Ensure we return -0 rather than +0 when appropriate.  */
       if (orig_xh < 0.0)
        xh = -__builtin_fabs (xh);
-
-      fesetround (save_round);
     }
 
   return ldbl_pack (xh, xl);
index 836cbf3..b33d178 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1995-2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995-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
@@ -50,8 +51,6 @@ extern int __have_no_getdents64 attribute_hidden;
 # define __have_no_getdents64 0
 #endif
 
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-
 /* For Linux we need a special version of this file since the
    definition of `struct dirent' is not the same for the kernel and
    the libc.  There is one additional field which might be introduced
index 5286676..89d5b12 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992,1993,1995-2000,2002-2005,2006
+/* Copyright (C) 1992,1993,1995-2000,2002-2006,2007
        Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
@@ -566,15 +566,23 @@ asm (".L__X'%ebx = 1\n\t"
    is too complicated here since we have no PC-relative addressing mode.  */
 #else
 # ifdef __ASSEMBLER__
-#  define PTR_MANGLE(reg)      xorl %gs:POINTER_GUARD, reg
-#  define PTR_DEMANGLE(reg)    PTR_MANGLE (reg)
+#  define PTR_MANGLE(reg)      xorl %gs:POINTER_GUARD, reg;                  \
+                               roll $9, reg
+#  define PTR_DEMANGLE(reg)    rorl $9, reg;                                 \
+                               xorl %gs:POINTER_GUARD, reg
 # else
-#  define PTR_MANGLE(var)      asm ("xorl %%gs:%c2, %0"                      \
+#  define PTR_MANGLE(var)      asm ("xorl %%gs:%c2, %0\n"                    \
+                                    "roll $9, %0"                            \
+                                    : "=r" (var)                             \
+                                    : "0" (var),                             \
+                                      "i" (offsetof (tcbhead_t,              \
+                                                     pointer_guard)))
+#  define PTR_DEMANGLE(var)    asm ("rorl $9, %0\n"                          \
+                                    "xorl %%gs:%c2, %0"                      \
                                     : "=r" (var)                             \
                                     : "0" (var),                             \
                                       "i" (offsetof (tcbhead_t,              \
                                                      pointer_guard)))
-#  define PTR_DEMANGLE(var)    PTR_MANGLE (var)
 # endif
 #endif
 
index 5d14a9b..ff7c61a 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 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
@@ -16,7 +16,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* Taken verbatim from Linux 2.4 (include/linux/personality.h).  */
+/* Taken verbatim from Linux 2.6 (include/linux/personality.h).  */
 
 #ifndef _SYS_PERSONALITY_H
 #define _SYS_PERSONALITY_H 1
    These occupy the top three bytes.  */
 enum
   {
+    ADDR_NO_RANDOMIZE = 0x0040000,
     MMAP_PAGE_ZERO = 0x0100000,
     ADDR_LIMIT_32BIT = 0x0800000,
     SHORT_INODE = 0x1000000,
     WHOLE_SECONDS = 0x2000000,
     STICKY_TIMEOUTS = 0x4000000,
+    ADDR_LIMIT_3GB =   0x8000000
   };
 
 /* Personality types.
@@ -52,14 +54,15 @@ enum
     PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
     PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
     PER_LINUX32 = 0x0008,
+    PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB,
     PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,     /* IRIX5 32-bit */
     PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,    /* IRIX6 new 32-bit */
     PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,     /* IRIX6 64-bit */
     PER_RISCOS = 0x000c,
     PER_SOLARIS = 0x000d | STICKY_TIMEOUTS,
     PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
-    PER_HPUX = 0x000f,
-    PER_OSF4 = 0x0010,
+    PER_OSF4 = 0x000f,
+    PER_HPUX = 0x0010,
     PER_MASK = 0x00ff,
   };
 
index 5dfffca..3a0a632 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2001-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
 /* We cannot use the thread descriptor because in ld.so we use setjmp
    earlier than the descriptor is initialized.  */
 # ifdef __ASSEMBLER__
-#  define PTR_MANGLE(reg)      xorq __pointer_chk_guard_local(%rip), reg
-#  define PTR_DEMANGLE(reg)    PTR_MANGLE (reg)
+#  define PTR_MANGLE(reg)      xorq __pointer_chk_guard_local(%rip), reg;    \
+                               rolq $17, reg
+#  define PTR_DEMANGLE(reg)    rorq $17, reg;                                \
+                               xorq __pointer_chk_guard_local(%rip), reg
 # else
-#  define PTR_MANGLE(reg)      asm ("xorq __pointer_chk_guard_local(%%rip), %0"\
+#  define PTR_MANGLE(reg)      asm ("xorq __pointer_chk_guard_local(%%rip), %0\n" \
+                                    "rolq $17, %0"                           \
+                                    : "=r" (reg) : "0" (reg))
+#  define PTR_DEMANGLE(reg)    asm ("rorq $17, %0\n"                         \
+                                    "xorq __pointer_chk_guard_local(%%rip), %0" \
                                     : "=r" (reg) : "0" (reg))
-#  define PTR_DEMANGLE(reg)    PTR_MANGLE (reg)
 # endif
 #else
 # ifdef __ASSEMBLER__
-#  define PTR_MANGLE(reg)      xorq %fs:POINTER_GUARD, reg
-#  define PTR_DEMANGLE(reg)    PTR_MANGLE (reg)
+#  define PTR_MANGLE(reg)      xorq %fs:POINTER_GUARD, reg;                  \
+                               rolq $17, reg
+#  define PTR_DEMANGLE(reg)    rorq $17, reg;                                \
+                               xorq %fs:POINTER_GUARD, reg
 # else
-#  define PTR_MANGLE(var)      asm ("xorq %%fs:%c2, %0"                      \
+#  define PTR_MANGLE(var)      asm ("xorq %%fs:%c2, %0\n"                    \
+                                    "rolq $17, %0"                           \
+                                    : "=r" (var)                             \
+                                    : "0" (var),                             \
+                                      "i" (offsetof (tcbhead_t,              \
+                                                     pointer_guard)))
+#  define PTR_DEMANGLE(var)    asm ("rorq $17, %0\n"                         \
+                                    "xorq %%fs:%c2, %0"                      \
                                     : "=r" (var)                             \
                                     : "0" (var),                             \
                                       "i" (offsetof (tcbhead_t,              \
                                                      pointer_guard)))
-#  define PTR_DEMANGLE(var)    PTR_MANGLE (var)
 # endif
 #endif
 
index e1c861c..7514a9f 100644 (file)
@@ -1,5 +1,6 @@
 /* Macros to swap the order of bytes in integer values.
-   Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 2000, 2002, 2003, 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
@@ -59,7 +60,8 @@
 # if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__            \
                          || defined __pentiumpro__ || defined __pentium4__   \
                          || defined __k8__ || defined __athlon__             \
-                         || defined __k6__)
+                         || defined __k6__ || defined __nocona__             \
+                         || defined __core2__ || defined __geode__)
 /* To swap the bytes in a word the i486 processors and up provide the
    `bswap' opcode.  On i386 we have to use three instructions.  */
 #  define __bswap_32(x) \
index f54abfa..3c5a8cb 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-2004,2005,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2004,2005,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
@@ -414,7 +414,7 @@ extern unsigned long int wcstoul (__const wchar_t *__restrict __nptr,
      __THROW;
 
 #if defined __USE_ISOC99 || (defined __GNUC__ && defined __USE_GNU)
-/* Convert initial portion of wide string NPTR to `long int'
+/* Convert initial portion of wide string NPTR to `long long int'
    representation.  */
 __extension__
 extern long long int wcstoll (__const wchar_t *__restrict __nptr,
@@ -431,7 +431,7 @@ extern unsigned long long int wcstoull (__const wchar_t *__restrict __nptr,
 __END_NAMESPACE_C99
 
 #if defined __GNUC__ && defined __USE_GNU
-/* Convert initial portion of wide string NPTR to `long int'
+/* Convert initial portion of wide string NPTR to `long long int'
    representation.  */
 __extension__
 extern long long int wcstoq (__const wchar_t *__restrict __nptr,