about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog48
-rw-r--r--elf/dl-addr.c74
-rw-r--r--elf/dl-open.c4
-rw-r--r--elf/tst-auditmod1.c26
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in11
-rwxr-xr-xiconvdata/run-iconv-test.sh28
-rw-r--r--localedata/ChangeLog5
-rw-r--r--localedata/locales/es_NI5
-rw-r--r--localedata/locales/es_PE5
-rw-r--r--nis/nss_compat/compat-grp.c29
-rw-r--r--nis/nss_compat/compat-pwd.c69
-rw-r--r--nis/nss_compat/compat-spwd.c59
-rw-r--r--nptl/ChangeLog13
-rw-r--r--nptl/Makefile2
-rw-r--r--nptl/allocatestack.c11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/smp.h56
-rw-r--r--nptl/sysdeps/unix/sysv/linux/smp.h30
-rw-r--r--nptl/tst-getpid3.c114
-rw-r--r--nscd/initgrcache.c5
-rw-r--r--posix/Makefile2
-rw-r--r--stdlib/test-canon.c8
-rw-r--r--sysdeps/unix/sysv/linux/dl-osinfo.h1
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list3
24 files changed, 434 insertions, 178 deletions
diff --git a/ChangeLog b/ChangeLog
index 7d172adb0f..6d8eea5ae4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+2006-06-23  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #2980]
+	* posix/Makefile (CFLAGS-waitid.c): Add
+	-fasynchronous-unwind-tables.
+
+2006-08-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf/dl-addr.c (_dl_addr): If GNU-style hash tables are present,
+	walk them instead of the symbol table.
+
+2006-08-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* nscd/initgrcache.c (addinitgroupsX): Judge successful lookups by
+	status of NSS calls, not the number of returned entries.
+
+	* sysdeps/unix/sysv/linux/syscalls.list: Remove add_key,
+	request_key, keyctl.
+
+2006-07-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/dl-osinfo.h: Remove unnecessary include.
+
+2006-07-16  Jeff Bailey  <jbailey@ubuntu.com>
+
+	* elf/tst-auditmod1.c: Fix typo in #error.
+
+2006-07-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf/tst-auditmod1.c: Remove code for unsupported architectures.
+
+	* iconvdata/run-iconv-test.sh: Run cmp in C locale.
+
+2006-07-20  Adam Nemet  <anemet@caviumnetworks.com>
+
+	* stdlib/test-canon.c (do_test): Close fd before unlinking file so
+	that the directory is empty even on non-POSIX filesystems.
+
+2006-07-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf/dl-open.c (dl_open_worker): Add branch prediction.
+
+	* nis/nss_compat/compat-grp.c: Avoid unnecessary setgrent calls into
+	the backend NSS module.  If backend setgrent call failed, don't have
+	internal_setgrent fail.  Just remember this until it is needed.
+	* nis/nss_compat/compat-pwd.c: Likewise.
+	* nis/nss_compat/compat-spwd.c: Likewise.
+
 2006-07-30  Roland McGrath  <roland@redhat.com>
 
 	* sysdeps/unix/sysv/linux/ia64/sigsuspend.c: File removed.
diff --git a/elf/dl-addr.c b/elf/dl-addr.c
index ced8978eb3..535977ca5e 100644
--- a/elf/dl-addr.c
+++ b/elf/dl-addr.c
@@ -74,28 +74,62 @@ _dl_addr (const void *address, Dl_info *info,
 
       ElfW(Word) strtabsize = match->l_info[DT_STRSZ]->d_un.d_val;
 
-      const ElfW(Sym) *symtabend;
-      if (match->l_info[DT_HASH] != NULL)
-	symtabend = (symtab
-		     + ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]);
+      const ElfW(Sym) *matchsym = NULL;
+      if (match->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+			+ DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] != NULL)
+	{
+	  /* We look at all symbol table entries referenced by the
+	     hash table.  */
+	  for (Elf_Symndx bucket = 0; bucket < match->l_nbuckets; ++bucket)
+	    {
+	      Elf32_Word symndx = match->l_gnu_buckets[bucket];
+	      if (bucket != 0)
+		{
+		  const Elf32_Word *hasharr = &match->l_gnu_chain_zero[symndx];
+
+		  do
+		    {
+		      /* The hash table never references local symbols
+			 so we can omit that test here.  */
+		      if (symtab[symndx].st_shndx != SHN_UNDEF
+#ifdef USE_TLS
+			  && ELFW(ST_TYPE) (symtab[symndx].st_info) != STT_TLS
+#endif
+			  && DL_ADDR_SYM_MATCH (match, &symtab[symndx],
+						matchsym, addr)
+			  && symtab[symndx].st_name < strtabsize)
+			matchsym = (ElfW(Sym) *) &symtab[symndx];
+
+		      ++symndx;
+		    }
+		  while ((*hasharr++ & 1u) == 0);
+		}
+	    }
+	}
       else
-	/* There is no direct way to determine the number of symbols in the
-	   dynamic symbol table and no hash table is present.  The ELF
-	   binary is ill-formed but what shall we do?  Use the beginning of
-	   the string table which generally follows the symbol table.  */
-	symtabend = (const ElfW(Sym) *) strtab;
-
-      const ElfW(Sym) *matchsym;
-      for (matchsym = NULL; (void *) symtab < (void *) symtabend; ++symtab)
-	if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
-	     || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
-#if defined USE_TLS
-	    && ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
+	{
+	  const ElfW(Sym) *symtabend;
+	  if (match->l_info[DT_HASH] != NULL)
+	    symtabend = (symtab
+			 + ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]);
+	  else
+	    /* There is no direct way to determine the number of symbols in the
+	       dynamic symbol table and no hash table is present.  The ELF
+	       binary is ill-formed but what shall we do?  Use the beginning of
+	       the string table which generally follows the symbol table.  */
+	    symtabend = (const ElfW(Sym) *) strtab;
+
+	  for (; (void *) symtab < (void *) symtabend; ++symtab)
+	    if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
+		 || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
+#ifdef USE_TLS
+		&& ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
 #endif
-	    && symtab->st_shndx != SHN_UNDEF
-	    && DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
-	    && symtab->st_name < strtabsize)
-	  matchsym = (ElfW(Sym) *) symtab;
+		&& symtab->st_shndx != SHN_UNDEF
+		&& DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
+		&& symtab->st_name < strtabsize)
+	      matchsym = (ElfW(Sym) *) symtab;
+	}
 
       if (mapp)
 	*mapp = match;
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 930400c420..cdbb6601d2 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -1,5 +1,5 @@
 /* Load a shared object at runtime, relocate it, and run its initializer.
-   Copyright (C) 1996-2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1996-2004, 2005, 2006 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
@@ -341,7 +341,7 @@ dl_open_worker (void *a)
       if (! l->l_real->l_relocated)
 	{
 #ifdef SHARED
-	  if (GLRO(dl_profile) != NULL)
+	  if (__builtin_expect (GLRO(dl_profile) != NULL, 0))
 	    {
 	      /* If this here is the shared object which we want to profile
 		 make sure the profile is started.  We can find out whether
diff --git a/elf/tst-auditmod1.c b/elf/tst-auditmod1.c
index e9f6fe9c4d..2d39df21e8 100644
--- a/elf/tst-auditmod1.c
+++ b/elf/tst-auditmod1.c
@@ -132,12 +132,6 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
 # define La_regs La_sh_regs
 # define La_retval La_sh_retval
 # define int_retval lrv_r0
-#elif defined __mc68000__
-# define pltenter la_m68k_gnu_pltenter
-# define pltexit la_m68k_gnu_pltexit
-# define La_regs La_m68k_regs
-# define La_retval La_m68k_retval
-# define int_retval lrv_d0
 #elif defined __alpha__
 # define pltenter la_alpha_gnu_pltenter
 # define pltexit la_alpha_gnu_pltexit
@@ -162,24 +156,6 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
 # define La_regs La_ia64_regs
 # define La_retval La_ia64_retval
 # define int_retval lrv_r8
-#elif defined __mips__ && _MIPS_SIM == _ABIO32
-# define pltenter la_mips_o32_gnu_pltenter
-# define pltexit la_mips_o32_gnu_pltexit
-# define La_regs La_mips_32_regs
-# define La_retval La_mips_32_retval
-# define int_retval lrv_v0
-#elif defined __mips__ && _MIPS_SIM == _ABIN32
-# define pltenter la_mips_n32_gnu_pltenter
-# define pltexit la_mips_n32_gnu_pltexit
-# define La_regs La_mips_64_regs
-# define La_retval La_mips_64_retval
-# define int_retval lrv_v0
-#elif defined __mips__ && _MIPS_SIM == _ABI64
-# define pltenter la_mips_n64_gnu_pltenter
-# define pltexit la_mips_n64_gnu_pltexit
-# define La_regs La_mips_64_regs
-# define La_retval La_mips_64_retval
-# define int_retval lrv_v0
 #elif defined __sparc__ && __WORDSIZE == 32
 # define pltenter la_sparc32_gnu_pltenter
 # define pltexit la_sparc32_gnu_pltexit
@@ -197,7 +173,7 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
 #include <tst-audit.h>
 #if (!defined (pltenter) || !defined (pltexit) || !defined (La_regs) \
      || !defined (La_retval) || !defined (int_retval))
-# error "architecture specific code needed in sysdeps/CPU/tls-audit.h or here"
+# error "architecture specific code needed in sysdeps/CPU/tst-audit.h or here"
 #endif
 
 
diff --git a/fedora/branch.mk b/fedora/branch.mk
index 0e239ca15d..b472f8bbf7 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-fc4
-fedora-sync-date := 2006-07-31 07:06 UTC
-fedora-sync-tag := fedora-glibc-20060731T0706
+fedora-sync-date := 2006-08-02 16:50 UTC
+fedora-sync-tag := fedora-glibc-20060802T1650
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index 644cf00559..23b28861a0 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,4 +1,4 @@
-%define glibcrelease 15
+%define glibcrelease 16
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define xenarches i686 athlon
 %ifarch %{xenarches}
@@ -1433,8 +1433,17 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Wed Aug  2 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-16
+- fix dladdr on binaries/libraries with only DT_GNU_HASH and no
+  DT_HASH (#200635)
+- fix early timeout of initgroups data in nscd (#173019)
+- add am/pm display to es_PE and es_NI locales (#167101)
+- fix nss_compat failures when nis/nis+ unavailable (#192072)
+
 * Mon Jul 31 2006 Roland McGrath <roland@redhat.com> 2.4.90-15
 - fix missing destructor calls in dlclose (#197932)
+- enable transliteration support in all locales (#196713)
+- disallow RTLD_GLOBAL flag for dlmopen in secondary namespaces (#197462)
 - PI mutex support
 
 * Tue Jul 10 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-13
diff --git a/iconvdata/run-iconv-test.sh b/iconvdata/run-iconv-test.sh
index 91216447ba..5f6339d2c8 100755
--- a/iconvdata/run-iconv-test.sh
+++ b/iconvdata/run-iconv-test.sh
@@ -1,6 +1,6 @@
 #! /bin/sh -f
 # Run available iconv(1) tests.
-# Copyright (C) 1998-2002, 2005 Free Software Foundation, Inc.
+# Copyright (C) 1998-2002, 2005, 2006 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 #
@@ -66,7 +66,7 @@ while read from to subset targets; do
 	    echo "FAILED"; failed=1; continue; }
 	echo $ac_n "OK$ac_c"
 	if test -s testdata/$from..$t; then
-	  cmp $temp1 testdata/$from..$t > /dev/null 2>&1 ||
+	  LC_ALL=C cmp $temp1 testdata/$from..$t > /dev/null 2>&1 ||
 	    { echo "/FAILED"; failed=1; continue; }
 	  echo $ac_n "/OK$ac_c"
 	fi
@@ -75,7 +75,8 @@ while read from to subset targets; do
 	  { if test $? -gt 128; then exit 1; fi
 	    echo "FAILED"; failed=1; continue; }
 	echo $ac_n "OK$ac_c"
-	test -s $temp1 && cmp testdata/$from $temp2 > /dev/null 2>&1 ||
+	test -s $temp1 &&
+	LC_ALL=C cmp testdata/$from $temp2 > /dev/null 2>&1 ||
 	  { echo "/FAILED"; failed=1; continue; }
 	echo "/OK"
 	rm -f $temp1 $temp2
@@ -91,7 +92,7 @@ while read from to subset targets; do
 	  { if test $? -gt 128; then exit 1; fi
 	    echo "FAILED"; failed=1; continue; }
 	echo $ac_n "OK$ac_c"
-	cmp testdata/suntzus $temp1 ||
+	LC_ALL=C cmp testdata/suntzus $temp1 ||
 	  { echo "/FAILED"; failed=1; continue; }
 	echo "/OK"
       fi
@@ -110,7 +111,7 @@ while read from to subset targets; do
 	    echo "FAILED"; failed=1; continue; }
 	echo $ac_n "OK$ac_c"
 	if test -s testdata/$from..$t; then
-	  cmp $temp1 testdata/$from..$t > /dev/null 2>&1 ||
+	  LC_ALL=C cmp $temp1 testdata/$from..$t > /dev/null 2>&1 ||
 	    { echo "/FAILED"; failed=1; continue; }
 	  echo $ac_n "/OK$ac_c"
 	fi
@@ -120,7 +121,8 @@ while read from to subset targets; do
 	  { if test $? -gt 128; then exit 1; fi
 	    echo "FAILED"; failed=1; continue; }
 	echo $ac_n "OK$ac_c"
-	test -s $temp1 && cmp testdata/$from $temp2 > /dev/null 2>&1 ||
+	test -s $temp1 &&
+	LC_ALL=C cmp testdata/$from $temp2 > /dev/null 2>&1 ||
 	  { echo "/FAILED"; failed=1; continue; }
 	echo "/OK"
 	rm -f $temp1 $temp2
@@ -135,7 +137,7 @@ while read from to subset targets; do
       { if test $? -gt 128; then exit 1; fi
 	echo "FAILED"; failed=1; continue; }
     echo $ac_n "OK$ac_c"
-    cmp testdata/suntzus $temp1 ||
+    LC_ALL=C cmp testdata/suntzus $temp1 ||
       { echo "/FAILED"; failed=1; continue; }
     echo "/OK"
   fi
@@ -153,32 +155,32 @@ while read utf8 from filename; do
   # Test conversion to the endianness dependent encoding.
   echo $ac_n "test encoder: $utf8 -> $from $ac_c"
   $PROG -f $utf8 -t $from < testdata/${filename}..${utf8} > $temp1
-  cmp $temp1 testdata/${filename}..${from}.BE > /dev/null 2>&1 ||
-  cmp $temp1 testdata/${filename}..${from}.LE > /dev/null 2>&1 ||
+  LC_ALL=C cmp $temp1 testdata/${filename}..${from}.BE > /dev/null 2>&1 ||
+  LC_ALL=C cmp $temp1 testdata/${filename}..${from}.LE > /dev/null 2>&1 ||
     { echo "/FAILED"; failed=1; continue; }
   echo "OK"
 
   # Test conversion from the endianness dependent encoding.
   echo $ac_n "test decoder: $from -> $utf8 $ac_c"
   $PROG -f $from -t $utf8 < testdata/${filename}..${from}.BE > $temp1
-  cmp $temp1 testdata/${filename}..${utf8} > /dev/null 2>&1 ||
+  LC_ALL=C cmp $temp1 testdata/${filename}..${utf8} > /dev/null 2>&1 ||
     { echo "/FAILED"; failed=1; continue; }
   $PROG -f $from -t $utf8 < testdata/${filename}..${from}.LE > $temp1
-  cmp $temp1 testdata/${filename}..${utf8} > /dev/null 2>&1 ||
+  LC_ALL=C cmp $temp1 testdata/${filename}..${utf8} > /dev/null 2>&1 ||
     { echo "/FAILED"; failed=1; continue; }
   echo "OK"
 
   # Test byte swapping behaviour.
   echo $ac_n "test non-BOM: ${from}BE -> ${from}LE $ac_c"
   $PROG -f ${from}BE -t ${from}LE < testdata/${filename}..${from}.BE > $temp1
-  cmp $temp1 testdata/${filename}..${from}.LE > /dev/null 2>&1 ||
+  LC_ALL=C cmp $temp1 testdata/${filename}..${from}.LE > /dev/null 2>&1 ||
     { echo "/FAILED"; failed=1; continue; }
   echo "OK"
 
   # Test byte swapping behaviour.
   echo $ac_n "test non-BOM: ${from}LE -> ${from}BE $ac_c"
   $PROG -f ${from}LE -t ${from}BE < testdata/${filename}..${from}.LE > $temp1
-  cmp $temp1 testdata/${filename}..${from}.BE > /dev/null 2>&1 ||
+  LC_ALL=C cmp $temp1 testdata/${filename}..${from}.BE > /dev/null 2>&1 ||
     { echo "/FAILED"; failed=1; continue; }
   echo "OK"
 
diff --git a/localedata/ChangeLog b/localedata/ChangeLog
index 3e43cf73c6..b58c0c09f9 100644
--- a/localedata/ChangeLog
+++ b/localedata/ChangeLog
@@ -1,3 +1,8 @@
+2006-08-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* locales/es_NI: Define real t_fmt_ampm and am_pm.
+	* locales/es_PE: Likewise.
+
 2006-07-30  Ulrich Drepper  <drepper@redhat.com>
 
 	* locales/te_IN: Minor fixups.
diff --git a/localedata/locales/es_NI b/localedata/locales/es_NI
index fbae5c7644..d75c68b6c7 100644
--- a/localedata/locales/es_NI
+++ b/localedata/locales/es_NI
@@ -108,8 +108,9 @@ mon     "<U0065><U006E><U0065><U0072><U006F>";/
 d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
 d_fmt   "<U0025><U0064><U002F><U0025><U006D><U002F><U0025><U0079>"
 t_fmt   "<U0025><U0054>"
-am_pm   "";""
-t_fmt_ampm ""
+t_fmt_ampm "<U0025><U0049><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
+<U0025><U0070>"
+am_pm	"<U0041><U004D>";"<U0050><U004D>"
 date_fmt	"<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065>/
 <U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
 <U0025><U005A><U0020><U0025><U0059>"
diff --git a/localedata/locales/es_PE b/localedata/locales/es_PE
index 7fa54839c6..27390ab764 100644
--- a/localedata/locales/es_PE
+++ b/localedata/locales/es_PE
@@ -117,8 +117,9 @@ mon     "<U0065><U006E><U0065><U0072><U006F>";/
 d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
 d_fmt   "<U0025><U0064><U002F><U0025><U006D><U002F><U0025><U0079>"
 t_fmt   "<U0025><U0054>"
-am_pm   "";""
-t_fmt_ampm ""
+t_fmt_ampm "<U0025><U0049><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
+<U0025><U0070>"
+am_pm	"<U0041><U004D>";"<U0050><U004D>"
 date_fmt	"<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065>/
 <U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
 <U0025><U005A><U0020><U0025><U0059>"
diff --git a/nis/nss_compat/compat-grp.c b/nis/nss_compat/compat-grp.c
index 093876fd74..f2f7195be1 100644
--- a/nis/nss_compat/compat-grp.c
+++ b/nis/nss_compat/compat-grp.c
@@ -59,12 +59,13 @@ struct blacklist_t
 struct ent_t
 {
   bool_t files;
+  enum nss_status setent_status;
   FILE *stream;
   struct blacklist_t blacklist;
 };
 typedef struct ent_t ent_t;
 
-static ent_t ext_ent = {TRUE, NULL, {NULL, 0, 0}};
+static ent_t ext_ent = { TRUE, NSS_STATUS_SUCCESS, NULL, { NULL, 0, 0 }};
 
 /* Protect global state against multiple changers.  */
 __libc_lock_define_initialized (static, lock)
@@ -89,7 +90,7 @@ init_nss_interface (void)
 }
 
 static enum nss_status
-internal_setgrent (ent_t *ent, int stayopen)
+internal_setgrent (ent_t *ent, int stayopen, int needent)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
 
@@ -137,12 +138,8 @@ internal_setgrent (ent_t *ent, int stayopen)
   else
     rewind (ent->stream);
 
-  if (status == NSS_STATUS_SUCCESS && nss_setgrent)
-    {
-      status = nss_setgrent (stayopen);
-      if (status == NSS_STATUS_UNAVAIL)
-        status = NSS_STATUS_SUCCESS;
-    }
+  if (needent && status == NSS_STATUS_SUCCESS && nss_setgrent)
+    ent->setent_status = nss_setgrent (stayopen);
 
   return status;
 }
@@ -158,7 +155,7 @@ _nss_compat_setgrent (int stayopen)
   if (ni == NULL)
     init_nss_interface ();
 
-  result = internal_setgrent (&ext_ent, stayopen);
+  result = internal_setgrent (&ext_ent, stayopen, 1);
 
   __libc_lock_unlock (lock);
 
@@ -212,6 +209,10 @@ getgrent_next_nss (struct group *result, ent_t *ent, char *buffer,
   if (!nss_getgrent_r)
     return NSS_STATUS_UNAVAIL;
 
+  /* If the setgrent call failed, say so.  */
+  if (ent->setent_status != NSS_STATUS_SUCCESS)
+    return ent->setent_status;
+
   do
     {
       enum nss_status status;
@@ -363,7 +364,7 @@ _nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen,
     init_nss_interface ();
 
   if (ext_ent.stream == NULL)
-    result = internal_setgrent (&ext_ent, 1);
+    result = internal_setgrent (&ext_ent, 1, 1);
 
   if (result == NSS_STATUS_SUCCESS)
     {
@@ -485,7 +486,7 @@ enum nss_status
 _nss_compat_getgrnam_r (const char *name, struct group *grp,
 			char *buffer, size_t buflen, int *errnop)
 {
-  ent_t ent = {TRUE, NULL, {NULL, 0, 0}};
+  ent_t ent = { TRUE, NSS_STATUS_SUCCESS, NULL, { NULL, 0, 0 }};
   enum nss_status result;
 
   if (name[0] == '-' || name[0] == '+')
@@ -498,7 +499,7 @@ _nss_compat_getgrnam_r (const char *name, struct group *grp,
 
   __libc_lock_unlock (lock);
 
-  result = internal_setgrent (&ent, 0);
+  result = internal_setgrent (&ent, 0, 0);
 
   if (result == NSS_STATUS_SUCCESS)
     result = internal_getgrnam_r (name, grp, &ent, buffer, buflen, errnop);
@@ -613,7 +614,7 @@ enum nss_status
 _nss_compat_getgrgid_r (gid_t gid, struct group *grp,
 			char *buffer, size_t buflen, int *errnop)
 {
-  ent_t ent = {TRUE, NULL, {NULL, 0, 0}};
+  ent_t ent = { TRUE, NSS_STATUS_SUCCESS, NULL, { NULL, 0, 0 }};
   enum nss_status result;
 
   __libc_lock_lock (lock);
@@ -623,7 +624,7 @@ _nss_compat_getgrgid_r (gid_t gid, struct group *grp,
 
   __libc_lock_unlock (lock);
 
-  result = internal_setgrent (&ent, 0);
+  result = internal_setgrent (&ent, 0, 0);
 
   if (result == NSS_STATUS_SUCCESS)
     result = internal_getgrgid_r (gid, grp, &ent, buffer, buflen, errnop);
diff --git a/nis/nss_compat/compat-pwd.c b/nis/nss_compat/compat-pwd.c
index 1031714529..ac132046da 100644
--- a/nis/nss_compat/compat-pwd.c
+++ b/nis/nss_compat/compat-pwd.c
@@ -62,9 +62,10 @@ struct blacklist_t
 
 struct ent_t
 {
-  bool_t netgroup;
-  bool_t first;
-  bool_t files;
+  bool netgroup;
+  bool first;
+  bool files;
+  enum nss_status setent_status;
   FILE *stream;
   struct blacklist_t blacklist;
   struct passwd pwd;
@@ -72,8 +73,9 @@ struct ent_t
 };
 typedef struct ent_t ent_t;
 
-static ent_t ext_ent = {0, 0, TRUE, NULL, {NULL, 0, 0},
-                        {NULL, NULL, 0, 0, NULL, NULL, NULL}};
+static ent_t ext_ent = { false, false, true, NSS_STATUS_SUCCESS, NULL,
+			 { NULL, 0, 0 },
+			 { NULL, NULL, 0, 0, NULL, NULL, NULL }};
 
 /* Protect global state against multiple changers.  */
 __libc_lock_define_initialized (static, lock)
@@ -202,12 +204,13 @@ copy_pwd_changes (struct passwd *dest, struct passwd *src,
 }
 
 static enum nss_status
-internal_setpwent (ent_t *ent, int stayopen)
+internal_setpwent (ent_t *ent, int stayopen, int needent)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;
 
-  ent->first = ent->netgroup = FALSE;
-  ent->files = TRUE;
+  ent->first = ent->netgroup = false;
+  ent->files = true;
+  ent->setent_status = NSS_STATUS_SUCCESS;
 
   /* If something was left over free it.  */
   if (ent->netgroup)
@@ -257,12 +260,8 @@ internal_setpwent (ent_t *ent, int stayopen)
 
   give_pwd_free (&ent->pwd);
 
-  if (status == NSS_STATUS_SUCCESS && nss_setpwent)
-    {
-      status = nss_setpwent (stayopen);
-      if (status == NSS_STATUS_UNAVAIL)
-        status = NSS_STATUS_SUCCESS;
-    }
+  if (needent && status == NSS_STATUS_SUCCESS && nss_setpwent)
+    ent->setent_status = nss_setpwent (stayopen);
 
   return status;
 }
@@ -278,7 +277,7 @@ _nss_compat_setpwent (int stayopen)
   if (ni == NULL)
     init_nss_interface ();
 
-  result = internal_setpwent (&ext_ent, stayopen);
+  result = internal_setpwent (&ext_ent, stayopen, 1);
 
   __libc_lock_unlock (lock);
 
@@ -301,7 +300,7 @@ internal_endpwent (ent_t *ent)
   if (ent->netgroup)
     __internal_endnetgrent (&ent->netgrdata);
 
-  ent->first = ent->netgroup = FALSE;
+  ent->first = ent->netgroup = false;
 
   if (ent->blacklist.data != NULL)
     {
@@ -348,17 +347,17 @@ getpwent_next_nss_netgr (const char *name, struct passwd *result, ent_t *ent,
 
   if (yp_get_default_domain (&curdomain) != YPERR_SUCCESS)
     {
-      ent->netgroup = FALSE;
-      ent->first = FALSE;
+      ent->netgroup = false;
+      ent->first = false;
       give_pwd_free (&ent->pwd);
       return NSS_STATUS_UNAVAIL;
     }
 
-  if (ent->first == TRUE)
+  if (ent->first == true)
     {
       memset (&ent->netgrdata, 0, sizeof (struct __netgrent));
       __internal_setnetgrent (group, &ent->netgrdata);
-      ent->first = FALSE;
+      ent->first = false;
     }
 
   while (1)
@@ -427,6 +426,10 @@ getpwent_next_nss (struct passwd *result, ent_t *ent, char *buffer,
   if (!nss_getpwent_r)
     return NSS_STATUS_UNAVAIL;
 
+  /* If the setpwent call failed, say so.  */
+  if (ent->setent_status != NSS_STATUS_SUCCESS)
+    return ent->setent_status;
+
   p2len = pwd_need_buflen (&ent->pwd);
   if (p2len > buflen)
     {
@@ -437,7 +440,7 @@ getpwent_next_nss (struct passwd *result, ent_t *ent, char *buffer,
   buflen -= p2len;
 
   if (ent->first)
-    ent->first = FALSE;
+    ent->first = false;
 
   do
     {
@@ -570,8 +573,8 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
 	{
 	  enum nss_status status;
 
-	  ent->netgroup = TRUE;
-	  ent->first = TRUE;
+	  ent->netgroup = true;
+	  ent->first = true;
 	  copy_pwd_changes (&ent->pwd, result, NULL, 0);
 
 	  status = getpwent_next_nss_netgr (NULL, result, ent,
@@ -626,8 +629,8 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
       /* +:... */
       if (result->pw_name[0] == '+' && result->pw_name[1] == '\0')
 	{
-	  ent->files = FALSE;
-	  ent->first = TRUE;
+	  ent->files = false;
+	  ent->first = true;
 	  copy_pwd_changes (&ent->pwd, result, NULL, 0);
 
 	  return getpwent_next_nss (result, ent, buffer, buflen, errnop);
@@ -675,7 +678,7 @@ _nss_compat_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen,
     init_nss_interface ();
 
   if (ext_ent.stream == NULL)
-    result = internal_setpwent (&ext_ent, 1);
+    result = internal_setpwent (&ext_ent, 1, 1);
 
   if (result == NSS_STATUS_SUCCESS)
     result = internal_getpwent_r (pwd, &ext_ent, buffer, buflen, errnop);
@@ -827,8 +830,8 @@ _nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
 			char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status result;
-  ent_t ent = {0, 0, TRUE, NULL, {NULL, 0, 0},
-               {NULL, NULL, 0, 0, NULL, NULL, NULL}};
+  ent_t ent = { false, false, true, NSS_STATUS_SUCCESS, NULL, { NULL, 0, 0 },
+		{ NULL, NULL, 0, 0, NULL, NULL, NULL }};
 
   if (name[0] == '-' || name[0] == '+')
     return NSS_STATUS_NOTFOUND;
@@ -840,7 +843,7 @@ _nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
 
   __libc_lock_unlock (lock);
 
-  result = internal_setpwent (&ent, 0);
+  result = internal_setpwent (&ent, 0, 0);
 
   if (result == NSS_STATUS_SUCCESS)
     result = internal_getpwnam_r (name, pwd, &ent, buffer, buflen, errnop);
@@ -1069,8 +1072,8 @@ _nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd,
 			char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status result;
-  ent_t ent = {0, 0, TRUE, NULL, {NULL, 0, 0},
-               {NULL, NULL, 0, 0, NULL, NULL, NULL}};
+  ent_t ent = { false, false, true, NSS_STATUS_SUCCESS, NULL, { NULL, 0, 0 },
+		{ NULL, NULL, 0, 0, NULL, NULL, NULL }};
 
   __libc_lock_lock (lock);
 
@@ -1079,7 +1082,7 @@ _nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd,
 
   __libc_lock_unlock (lock);
 
-  result = internal_setpwent (&ent, 0);
+  result = internal_setpwent (&ent, 0, 0);
 
   if (result == NSS_STATUS_SUCCESS)
     result = internal_getpwuid_r (uid, pwd, &ent, buffer, buflen, errnop);
@@ -1136,7 +1139,7 @@ blacklist_store_name (const char *name, ent_t *ent)
   return;
 }
 
-/* returns TRUE if ent->blacklist contains name, else FALSE */
+/* Returns TRUE if ent->blacklist contains name, else FALSE.  */
 static bool_t
 in_blacklist (const char *name, int namelen, ent_t *ent)
 {
diff --git a/nis/nss_compat/compat-spwd.c b/nis/nss_compat/compat-spwd.c
index 5c820a5f65..d1de3f75b0 100644
--- a/nis/nss_compat/compat-spwd.c
+++ b/nis/nss_compat/compat-spwd.c
@@ -59,9 +59,10 @@ struct blacklist_t
 
 struct ent_t
 {
-  bool_t netgroup;
-  bool_t files;
-  bool_t first;
+  bool netgroup;
+  bool files;
+  bool first;
+  enum nss_status setent_status;
   FILE *stream;
   struct blacklist_t blacklist;
   struct spwd pwd;
@@ -69,8 +70,9 @@ struct ent_t
 };
 typedef struct ent_t ent_t;
 
-static ent_t ext_ent = {0, TRUE, 0, NULL, {NULL, 0, 0},
-			{NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
+static ent_t ext_ent = { false, true, false, NSS_STATUS_SUCCESS, NULL,
+			 { NULL, 0, 0},
+			 { NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
 
 /* Protect global state against multiple changers.  */
 __libc_lock_define_initialized (static, lock)
@@ -161,7 +163,7 @@ internal_setspent (ent_t *ent, int stayopen)
   enum nss_status status = NSS_STATUS_SUCCESS;
 
   ent->first = ent->netgroup = 0;
-  ent->files = TRUE;
+  ent->files = true;
 
   /* If something was left over free it.  */
   if (ent->netgroup)
@@ -212,11 +214,7 @@ internal_setspent (ent_t *ent, int stayopen)
   give_spwd_free (&ent->pwd);
 
   if (status == NSS_STATUS_SUCCESS && nss_setspent)
-    {
-      status = nss_setspent (stayopen);
-      if (status == NSS_STATUS_UNAVAIL)
-        status = NSS_STATUS_SUCCESS;
-    }
+    ent->setent_status = nss_setspent (stayopen);
 
   return status;
 }
@@ -255,8 +253,8 @@ internal_endspent (ent_t *ent)
   if (ent->netgroup)
     __internal_endnetgrent (&ent->netgrdata);
 
-  ent->first = ent->netgroup = FALSE;
-  ent->files = TRUE;
+  ent->first = ent->netgroup = false;
+  ent->files = true;
 
   if (ent->blacklist.data != NULL)
     {
@@ -298,19 +296,23 @@ getspent_next_nss_netgr (const char *name, struct spwd *result, ent_t *ent,
   if (!nss_getspnam_r)
     return NSS_STATUS_UNAVAIL;
 
+  /* If the setpwent call failed, say so.  */
+  if (ent->setent_status != NSS_STATUS_SUCCESS)
+    return ent->setent_status;
+
   if (yp_get_default_domain (&curdomain) != YPERR_SUCCESS)
     {
-      ent->netgroup = FALSE;
-      ent->first = FALSE;
+      ent->netgroup = false;
+      ent->first = false;
       give_spwd_free (&ent->pwd);
       return NSS_STATUS_UNAVAIL;
     }
 
-  if (ent->first == TRUE)
+  if (ent->first == true)
     {
       memset (&ent->netgrdata, 0, sizeof (struct __netgrent));
       __internal_setnetgrent (group, &ent->netgrdata);
-      ent->first = FALSE;
+      ent->first = false;
     }
 
   while (1)
@@ -325,7 +327,7 @@ getspent_next_nss_netgr (const char *name, struct spwd *result, ent_t *ent,
       if (status != 1)
 	{
 	  __internal_endnetgrent (&ent->netgrdata);
-	  ent->netgroup = FALSE;
+	  ent->netgroup = false;
 	  give_spwd_free (&ent->pwd);
 	  return NSS_STATUS_RETURN;
 	}
@@ -400,6 +402,7 @@ getspent_next_nss (struct spwd *result, ent_t *ent,
   return NSS_STATUS_SUCCESS;
 }
 
+
 /* This function handle the +user entrys in /etc/shadow */
 static enum nss_status
 getspnam_plususer (const char *name, struct spwd *result, ent_t *ent,
@@ -440,6 +443,7 @@ getspnam_plususer (const char *name, struct spwd *result, ent_t *ent,
   return NSS_STATUS_SUCCESS;
 }
 
+
 static enum nss_status
 getspent_next_file (struct spwd *result, ent_t *ent,
 		    char *buffer, size_t buflen, int *errnop)
@@ -520,8 +524,8 @@ getspent_next_file (struct spwd *result, ent_t *ent,
 	{
 	  int status;
 
-	  ent->netgroup = TRUE;
-	  ent->first = TRUE;
+	  ent->netgroup = true;
+	  ent->first = true;
 	  copy_spwd_changes (&ent->pwd, result, NULL, 0);
 
 	  status = getspent_next_nss_netgr (NULL, result, ent,
@@ -577,8 +581,8 @@ getspent_next_file (struct spwd *result, ent_t *ent,
       /* +:... */
       if (result->sp_namp[0] == '+' && result->sp_namp[1] == '\0')
 	{
-	  ent->files = FALSE;
-	  ent->first = TRUE;
+	  ent->files = false;
+	  ent->first = true;
 	  copy_spwd_changes (&ent->pwd, result, NULL, 0);
 
 	  return getspent_next_nss (result, ent, buffer, buflen, errnop);
@@ -613,6 +617,7 @@ internal_getspent_r (struct spwd *pw, ent_t *ent,
     return getspent_next_nss (pw, ent, buffer, buflen, errnop);
 }
 
+
 enum nss_status
 _nss_compat_getspent_r (struct spwd *pwd, char *buffer, size_t buflen,
 			int *errnop)
@@ -636,6 +641,7 @@ _nss_compat_getspent_r (struct spwd *pwd, char *buffer, size_t buflen,
   return result;
 }
 
+
 /* Searches in /etc/passwd and the NIS/NIS+ map for a special user */
 static enum nss_status
 internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
@@ -778,13 +784,14 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
   return NSS_STATUS_SUCCESS;
 }
 
+
 enum nss_status
 _nss_compat_getspnam_r (const char *name, struct spwd *pwd,
 			char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status result;
-  ent_t ent = {0, TRUE, 0, NULL, {NULL, 0, 0},
-	       {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
+  ent_t ent = { false, true, false, NSS_STATUS_SUCCESS, NULL, { NULL, 0, 0},
+		{ NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
 
   if (name[0] == '-' || name[0] == '+')
     return NSS_STATUS_NOTFOUND;
@@ -806,6 +813,7 @@ _nss_compat_getspnam_r (const char *name, struct spwd *pwd,
   return result;
 }
 
+
 /* Support routines for remembering -@netgroup and -user entries.
    The names are stored in a single string with `|' as separator. */
 static void
@@ -852,6 +860,7 @@ blacklist_store_name (const char *name, ent_t *ent)
   return;
 }
 
+
 /* Returns TRUE if ent->blacklist contains name, else FALSE.  */
 static bool_t
 in_blacklist (const char *name, int namelen, ent_t *ent)
@@ -860,7 +869,7 @@ in_blacklist (const char *name, int namelen, ent_t *ent)
   char *cp;
 
   if (ent->blacklist.data == NULL)
-    return FALSE;
+    return false;
 
   buf[0] = '|';
   cp = stpcpy (&buf[1], name);
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 9a95de8bd4..e9011be083 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,16 @@
+2006-08-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/smp.h: New file.  Old Linux-specific
+	file.  Don't use sysctl.
+	* sysdeps/unix/sysv/linux/smp.h: Always assume SMP.  Archs can
+	overwrite the file if this is likely not true.
+
+2006-07-31  Daniel Jacobowitz  <dan@codesourcery.com>
+
+	* allocatestack.c (__reclaim_stacks): Reset the PID on cached stacks.
+	* Makefile (tests): Add tst-getpid3.
+	* tst-getpid3.c: New file.
+
 2006-07-30  Roland McGrath  <roland@redhat.com>
 
 	* Makefile (libpthread-routines): Add ptw-sigsuspend.
diff --git a/nptl/Makefile b/nptl/Makefile
index 1a1c377f48..3a72d3707e 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -256,7 +256,7 @@ tests = tst-typesizes \
 	tst-backtrace1 \
 	tst-oddstacklimit \
 	tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
-	tst-getpid1 tst-getpid2 \
+	tst-getpid1 tst-getpid2 tst-getpid3 \
 	tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99)
 xtests = tst-setuid1 tst-setuid1-static
 
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index a3ed1a33d3..4a1cd18481 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -742,9 +742,7 @@ __reclaim_stacks (void)
   list_t *runp;
   list_for_each (runp, &stack_used)
     {
-      struct pthread *curp;
-
-      curp = list_entry (runp, struct pthread, list);
+      struct pthread *curp = list_entry (runp, struct pthread, list);
       if (curp != self)
 	{
 	  /* This marks the stack as free.  */
@@ -758,6 +756,13 @@ __reclaim_stacks (void)
 	}
     }
 
+  /* Reset the PIDs in any cached stacks.  */
+  list_for_each (runp, &stack_cache)
+    {
+      struct pthread *curp = list_entry (runp, struct pthread, list);
+      curp->pid = self->pid;
+    }
+
   /* Add the stack of all running threads to the cache.  */
   list_splice (&stack_used, &stack_cache);
 
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/smp.h b/nptl/sysdeps/unix/sysv/linux/i386/smp.h
new file mode 100644
index 0000000000..f68a0c0758
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/i386/smp.h
@@ -0,0 +1,56 @@
+/* Determine whether the host has multiple processors.  Linux version.
+   Copyright (C) 1996, 2002, 2004, 2006 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include <not-cancel.h>
+
+/* Test whether the machine has more than one processor.  This is not the
+   best test but good enough.  More complicated tests would require `malloc'
+   which is not available at that time.  */
+static inline int
+is_smp_system (void)
+{
+  union
+  {
+    struct utsname uts;
+    char buf[512];
+  } u;
+  char *cp;
+
+  /* Try reading the number using `sysctl' first.  */
+  if (uname (&u.uts) == 0)
+    cp = u.uts.version;
+  else
+    {
+      /* This was not successful.  Now try reading the /proc filesystem.  */
+      int fd = open_not_cancel_2 ("/proc/sys/kernel/version", O_RDONLY);
+      if (__builtin_expect (fd, 0) == -1
+	  || read_not_cancel (fd, u.buf, sizeof (u.buf)) <= 0)
+	/* This also didn't work.  We give up and say it's a UP machine.  */
+	u.buf[0] = '\0';
+
+      close_not_cancel_no_status (fd);
+      cp = u.buf;
+    }
+
+  return strstr (cp, "SMP") != NULL;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/smp.h b/nptl/sysdeps/unix/sysv/linux/smp.h
index 4f4d358d32..fcc34f7681 100644
--- a/nptl/sysdeps/unix/sysv/linux/smp.h
+++ b/nptl/sysdeps/unix/sysv/linux/smp.h
@@ -1,5 +1,5 @@
 /* Determine whether the host has multiple processors.  Linux version.
-   Copyright (C) 1996, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996, 2002, 2004, 2006 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
@@ -17,36 +17,12 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/sysctl.h>
-#include <not-cancel.h>
-
 /* Test whether the machine has more than one processor.  This is not the
    best test but good enough.  More complicated tests would require `malloc'
    which is not available at that time.  */
 static inline int
 is_smp_system (void)
 {
-  static const int sysctl_args[] = { CTL_KERN, KERN_VERSION };
-  char buf[512];
-  size_t reslen = sizeof (buf);
-
-  /* Try reading the number using `sysctl' first.  */
-  if (__sysctl ((int *) sysctl_args,
-		sizeof (sysctl_args) / sizeof (sysctl_args[0]),
-		buf, &reslen, NULL, 0) < 0)
-    {
-      /* This was not successful.  Now try reading the /proc filesystem.  */
-      int fd = open_not_cancel_2 ("/proc/sys/kernel/version", O_RDONLY);
-      if (__builtin_expect (fd, 0) == -1
-	  || (reslen = read_not_cancel (fd, buf, sizeof (buf))) <= 0)
-	/* This also didn't work.  We give up and say it's a UP machine.  */
-	buf[0] = '\0';
-
-      close_not_cancel_no_status (fd);
-    }
-
-  return strstr (buf, "SMP") != NULL;
+  /* Assume all machines are SMP and/or CMT and/or SMT.  */
+  return 1;
 }
diff --git a/nptl/tst-getpid3.c b/nptl/tst-getpid3.c
new file mode 100644
index 0000000000..f1e77f6b10
--- /dev/null
+++ b/nptl/tst-getpid3.c
@@ -0,0 +1,114 @@
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+
+static pid_t pid;
+
+static void *
+pid_thread (void *arg)
+{
+  if (pid != getpid ())
+    {
+      printf ("pid wrong in thread: should be %d, is %d\n",
+	      (int) pid, (int) getpid ());
+      return (void *) 1L;
+    }
+
+  return NULL;
+}
+
+static int
+do_test (void)
+{
+  pid = getpid ();
+
+  pthread_t thr;
+  int ret = pthread_create (&thr, NULL, pid_thread, NULL);
+  if (ret)
+    {
+      printf ("pthread_create failed: %d\n", ret);
+      return 1;
+    }
+
+  void *thr_ret;
+  ret = pthread_join (thr, &thr_ret);
+  if (ret)
+    {
+      printf ("pthread_create failed: %d\n", ret);
+      return 1;
+    }
+  else if (thr_ret)
+    {
+      printf ("thread getpid failed\n");
+      return 1;
+    }
+
+  pid_t child = fork ();
+  if (child == -1)
+    {
+      printf ("fork failed: %m\n");
+      return 1;
+    }
+  else if (child == 0)
+    {
+      if (pid == getpid ())
+	{
+	  puts ("pid did not change after fork");
+	  exit (1);
+	}
+
+      pid = getpid ();
+      ret = pthread_create (&thr, NULL, pid_thread, NULL);
+      if (ret)
+	{
+	  printf ("pthread_create failed: %d\n", ret);
+	  return 1;
+	}
+
+      ret = pthread_join (thr, &thr_ret);
+      if (ret)
+	{
+	  printf ("pthread_create failed: %d\n", ret);
+	  return 1;
+	}
+      else if (thr_ret)
+	{
+	  printf ("thread getpid failed\n");
+	  return 1;
+	}
+
+      return 0;
+    }
+
+  int status;
+  if (TEMP_FAILURE_RETRY (waitpid (child, &status, 0)) != child)
+    {
+      puts ("waitpid failed");
+      kill (child, SIGKILL);
+      return 1;
+    }
+
+  if (!WIFEXITED (status))
+    {
+      if (WIFSIGNALED (status))
+	printf ("died from signal %s\n", strsignal (WTERMSIG (status)));
+      else
+	puts ("did not terminate correctly");
+      return 1;
+    }
+  if (WEXITSTATUS (status) != 0)
+    {
+      printf ("exit code %d\n", WEXITSTATUS (status));
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index f2ff03a0b1..b4ae13903a 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -117,6 +117,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
     goto out;
 
   /* Nothing added yet.  */
+  bool any_success = false;
   while (! no_more)
     {
       long int prev_start = start;
@@ -158,6 +159,8 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
       if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
 	__libc_fatal ("illegal status in internal_getgrouplist");
 
+      any_success |= status == NSS_STATUS_SUCCESS;
+
       if (status != NSS_STATUS_SUCCESS
 	  && nss_next_action (nip, status) == NSS_ACTION_RETURN)
 	 break;
@@ -171,7 +174,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
   ssize_t total;
   ssize_t written;
  out:
-  if (start == 0)
+  if (!any_success)
     {
       /* Nothing found.  Create a negative result record.  */
       written = total = sizeof (notfound);
diff --git a/posix/Makefile b/posix/Makefile
index 4f76a267e9..605d02c896 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -142,7 +142,7 @@ CFLAGS-pwrite.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-pwrite64.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-sleep.c = -fexceptions
 CFLAGS-wait.c = -fexceptions -fasynchronous-unwind-tables
-CFLAGS-waitid.c = -fexceptions
+CFLAGS-waitid.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-waitpid.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-getopt.c = -fexceptions
 CFLAGS-wordexp.c = -fexceptions
diff --git a/stdlib/test-canon.c b/stdlib/test-canon.c
index 54267465b8..9261898795 100644
--- a/stdlib/test-canon.c
+++ b/stdlib/test-canon.c
@@ -1,5 +1,6 @@
 /* Test program for returning the canonical absolute name of a given file.
-   Copyright (C) 1996,1997,2000,2002,2004,2005 Free Software Foundation, Inc.
+   Copyright (C) 1996,1997,2000,2002,2004,2005,2006
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by David Mosberger <davidm@azstarnet.com>.
 
@@ -213,7 +214,10 @@ do_test (int argc, char ** argv)
     }
 
   if (fd >= 0)
-    unlink ("doesExist/someFile");
+    {
+      close (fd);
+      unlink ("doesExist/someFile");
+    }
 
   if (has_dir)
     rmdir ("doesExist");
diff --git a/sysdeps/unix/sysv/linux/dl-osinfo.h b/sysdeps/unix/sysv/linux/dl-osinfo.h
index 6cc0550f3f..3c93218dfc 100644
--- a/sysdeps/unix/sysv/linux/dl-osinfo.h
+++ b/sysdeps/unix/sysv/linux/dl-osinfo.h
@@ -20,7 +20,6 @@
 #include <string.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <sys/sysctl.h>
 #include <sys/utsname.h>
 #include <kernel-features.h>
 #include <dl-sysdep.h>
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index 969d054c62..afb6d80978 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -1,6 +1,5 @@
 # File name	Caller	Syscall name	Args	Strong name	Weak names
 
-add_key		EXTRA	add_key		i:pppii	add_key
 adjtimex	adjtime	adjtimex	i:p	__adjtimex	adjtimex ntp_adjtime __adjtimex_internal
 bdflush		EXTRA	bdflush		i:ii	bdflush
 capget		EXTRA	capget		i:pp	capget
@@ -30,7 +29,6 @@ inotify_init	EXTRA	inotify_init	i:	inotify_init
 inotify_rm_watch	EXTRA	inotify_rm_watch	i:ii	inotify_rm_watch
 ioperm		-	ioperm		i:iii	ioperm
 iopl		-	iopl		i:i	iopl
-keyctl		EXTRA	keyctl		i:iiiii	keyctl
 klogctl		EXTRA	syslog		i:isi	klogctl
 lchown		-	lchown		i:sii	__lchown	lchown
 posix_madvise	-	madvise		Vi:pii	posix_madvise
@@ -54,7 +52,6 @@ putpmsg		-	putpmsg		i:ippii	putpmsg
 query_module	EXTRA	query_module	i:sipip	query_module
 quotactl	EXTRA	quotactl	i:isip	quotactl
 remap_file_pages -	remap_file_pages i:piiii	__remap_file_pages remap_file_pages
-request_key	EXTRA	request_key	i:pppi	request_key
 sched_getp	-	sched_getparam	i:ip	__sched_getparam	sched_getparam
 sched_gets	-	sched_getscheduler	i:i	__sched_getscheduler	sched_getscheduler
 sched_primax	-	sched_get_priority_max	i:i	__sched_get_priority_max	sched_get_priority_max