summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libc/ChangeLog256
-rw-r--r--libc/Makeconfig1
-rw-r--r--libc/Makefile11
-rw-r--r--libc/bits/termios.h4
-rw-r--r--libc/elf/Makefile12
-rw-r--r--libc/elf/soinit.c4
-rw-r--r--libc/iconvdata/Depend1
-rw-r--r--libc/include/inline-hashtab.h5
-rw-r--r--libc/libio/freopen.c5
-rw-r--r--libc/libio/freopen64.c5
-rw-r--r--libc/libio/stdio.h2
-rw-r--r--libc/locale/programs/ld-collate.c12
-rw-r--r--libc/localedata/ChangeLog5
-rw-r--r--libc/localedata/locales/iso14651_t1_common3
-rw-r--r--libc/math/libm-test.inc4
-rw-r--r--libc/misc/fstab.c6
-rw-r--r--libc/misc/regexp.h16
-rw-r--r--libc/nptl/ChangeLog45
-rw-r--r--libc/nptl/Makefile6
-rw-r--r--libc/nptl/sysdeps/pthread/createthread.c4
-rw-r--r--libc/nptl/sysdeps/pthread/pthread.h6
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S19
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S37
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S23
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S13
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S25
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S25
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S14
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S13
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S16
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile4
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S21
-rw-r--r--libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S21
-rw-r--r--libc/nptl/tst-rwlock2.c28
-rw-r--r--libc/nptl/tst-rwlock2a.c2
-rw-r--r--libc/nptl/tst-typesizes.c29
-rw-r--r--libc/nscd/aicache.c39
-rw-r--r--libc/nscd/cache.c41
-rw-r--r--libc/nscd/connections.c221
-rw-r--r--libc/nscd/grpcache.c16
-rw-r--r--libc/nscd/hstcache.c46
-rw-r--r--libc/nscd/initgrcache.c10
-rw-r--r--libc/nscd/mem.c54
-rw-r--r--libc/nscd/nscd.h7
-rw-r--r--libc/nscd/nscd_getserv_r.c2
-rw-r--r--libc/nscd/pwdcache.c31
-rw-r--r--libc/nscd/servicescache.c6
-rw-r--r--libc/posix/glob.c5
-rw-r--r--libc/resolv/arpa/nameser_compat.h5
-rw-r--r--libc/resolv/nss_dns/dns-host.c39
-rw-r--r--libc/resolv/res_query.c15
-rw-r--r--libc/resolv/res_send.c29
-rw-r--r--libc/scripts/data/localplt-sparc-linux-gnu.data18
-rw-r--r--libc/scripts/data/localplt-sparc64-linux-gnu.data20
-rw-r--r--libc/scripts/soversions.awk13
-rw-r--r--libc/shlib-versions5
-rw-r--r--libc/stdio-common/Makefile6
-rw-r--r--libc/stdio-common/scanf14.c53
-rw-r--r--libc/stdio-common/scanf15.c43
-rw-r--r--libc/stdio-common/scanf16.c147
-rw-r--r--libc/stdio-common/scanf17.c128
-rw-r--r--libc/string/Makefile2
-rw-r--r--libc/string/endian.h66
-rw-r--r--libc/string/test-memmem.c185
-rw-r--r--libc/string/test-string.h12
-rw-r--r--libc/sysdeps/posix/getaddrinfo.c35
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_lround.S6
-rw-r--r--libc/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S10
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_llround.S10
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S10
-rw-r--r--libc/sysdeps/sparc/Makefile4
-rw-r--r--libc/sysdeps/sparc/machine-gmon.h33
-rw-r--r--libc/sysdeps/sparc/sparc-mcount.S29
-rw-r--r--libc/sysdeps/sparc/sparc64/backtrace.c58
-rw-r--r--libc/sysdeps/unix/sysv/linux/Makefile2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h3
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h16
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S6
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h15
-rw-r--r--libc/time/strftime_l.c43
-rw-r--r--ports/ChangeLog.arm20
-rw-r--r--ports/ChangeLog.hppa15
-rw-r--r--ports/ChangeLog.mips5
-rw-r--r--ports/sysdeps/arm/nptl/pthread_spin_lock.c4
-rw-r--r--ports/sysdeps/arm/nptl/pthread_spin_trylock.c4
-rw-r--r--ports/sysdeps/unix/sysv/linux/arm/eabi/configure2
-rw-r--r--ports/sysdeps/unix/sysv/linux/arm/eabi/configure.in2
-rw-r--r--ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h41
-rw-r--r--ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h12
-rw-r--r--ports/sysdeps/unix/sysv/linux/mips/bits/socket.h72
91 files changed, 2088 insertions, 338 deletions
diff --git a/libc/ChangeLog b/libc/ChangeLog
index 110f60889..c0dcf2de3 100644
--- a/libc/ChangeLog
+++ b/libc/ChangeLog
@@ -1,3 +1,257 @@
+2008-06-18 Ulrich Drepper <drepper@redhat.com>
+
+ * nscd/connections.c (main_loop_poll): Fix test for read error.
+ (main_loop_epoll): Likewise.
+
+2008-06-13 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/posix/getaddrinfo.c: Move _res_hconf_init call to a
+ better place so it is not called when nscd is used.
+
+ * nscd/connections.c: Also recognize and handle changes to the
+ resolver configuration file.
+
+2008-06-12 Ulrich Drepper <drepper@redhat.com>
+
+ * time/strftime.c: Pass reference to tzset_called around to handle
+ recursive calls.
+
+ [BZ #6612]
+ * time/strftime.c (__strftime_internal): Call tzset() only
+ when printing timezone-dependent values.
+ Based on a patch by Petr Baudis <pasky@suse.cz>.
+
+ * resolv/nss_dns/dns-host.c (gaih_getanswer): Don't
+ unconditionally use second gaih_getanswer_slice result.
+
+ * sysdeps/posix/getaddrinfo.c (gai_inet): Remove unnecessary test.
+ (getaddrinfo): RES must always be non-NULL.
+
+2008-06-12 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/powerpc/powerpc64/fpu/s_llround.S (__llround): Avoid using
+ cr[34] registers.
+ * sysdeps/powerpc/powerpc64/fpu/s_llroundf.S (__llroundf): Likewise.
+ * sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S (__llround):
+ Likewise.
+ * sysdeps/powerpc/powerpc32/fpu/s_lround.S (__lround): Avoid using cr3
+ register.
+
+2008-06-12 Ulrich Drepper <drepper@redhat.com>
+
+ * nscd/nscd.h (struct database_dyn): Add inotify_descr and clear_cache
+ fields.
+ * nscd/connections.c (inotify_fd): New variable.
+ (nscd_init): Try to open an inotify descriptor.
+ If successful, watch files for databases using inotify instead of
+ having prune threads stat the files.
+ (nscd_run_prune): Recognize clear_cache flag being set and call
+ prune_cache appropriately.
+ (main_loop_poll): Add inotify descriptor to wait set and handle the
+ reported changes.
+ (main_loop_epoll): Likewise.
+ * nscd/cache.c (prune_cache): Don't stat files for databases if
+ inotify is used.
+ * sysdeps/unix/sysv/linux/Makefile [subdir=nscd]
+ (CFLAGS-connections.c): Add -DHAVE_INOTIFY.
+
+ * nscd/grpcache.c (cache_addgr): Correctly compute size of
+ fixed-size portion of the record.
+ * nscd/servicescache.c (cache_addserv): Likewise.
+ * nscd/pwdcache.c (cache_addpw): Likewise.
+ * nscd/initgrcache.c (addinitgroupsX): Likewise.
+
+2008-06-11 Ulrich Drepper <drepper@redhat.com>
+
+ * nscd/mem.c (gc): Initialize obstack earlier so that if we jump
+ out we don't use uninitialized memory.
+
+ * nscd/hstcache.c (cache_addhst): Send correct number of bytes to
+ the client.
+
+2008-06-10 Ulrich Drepper <drepper@redhat.com>
+
+ * resolv/nss_dns/dns-host.c (gaih_getanswer_slice): Also log and
+ ignore T_DNAME messages.
+ * resolv/arpa/nameser_compat.h (T_DNAME): Define.
+
+2008-06-05 Jakub Jelinek <jakub@redhat.com>
+
+ * misc/regexp.h (compile): Use __REPB_PREFIX macro.
+ Avoid segfault if first GETC returns eof/'\0'/'\n'.
+
+2008-06-03 Jakub Jelinek <jakub@redhat.com>
+
+ * nscd/nscd_getserv_r.c (__nscd_getservbyport_r): Pass cp
+ instead of portstr to nscd_getserv_r. Patch by
+ Roman Kagan <rkagan@mail.ru>.
+
+2008-05-26 Jim Meyering <meyering@redhat.com>
+
+ Remove more useless "if" tests before "free".
+ * include/inline-hashtab.h (htab_delete): Likewise.
+ * libio/freopen.c (freopen): Likewise.
+ * libio/freopen64.c (freopen64): Likewise.
+ * locale/programs/ld-collate.c (collate_read): Likewise.
+ * misc/fstab.c (libc_freeres_fn): Likewise.
+ * posix/glob.c (globfree): Likewise.
+
+2008-05-24 Ulrich Drepper <drepper@redhat.com>
+
+ * string/Makefile (strop-tests): Add memmem.
+ * string/test-memmem.c: New file.
+ * string/test-string.h (BUF1PAGES): Define to 1 if undefined.
+ (test_init): Size buf1 according to BUF1PAGES.
+
+2008-05-24 Jakub Jelinek <jakub@redhat.com>
+
+ * libio/stdio.h (vscanf): Fix -std=c99 redirect.
+ * stdio-common/Makefile (tests): Add scanf16 and scanf17.
+ (CFLAGS-scanf17.c): New.
+ * stdio-common/scanf14.c (main): Add fscanf and scanf tests.
+ * stdio-common/scanf15.c (main): Likewise.
+ * stdio-common/scanf16.c: New file.
+ * stdio-common/scanf17.c: New file.
+
+2008-05-24 Ulrich Drepper <drepper@redhat.com>
+
+ * resolv/res_send.c (send_dg): If we already have one of two
+ answers and the server reports SERVFAIL, NOTIMP, or REFUSED, then
+ use the one answer insted of failing.
+
+2008-02-20 Ryan S. Arnold <rsa@us.ibm.com>
+
+ * math/libm-test.inc (exp_test): Exclude expl(1000.0L) from
+ being executed on PowerPC as the expected result exceeds IBM
+ long double 128 __LDBL_MAX__.
+
+2008-05-21 Roland McGrath <roland@redhat.com>
+
+ * shlib-versions (sparc.*-.*-.*, sparc64.*-.*-.*): Add ABI lines.
+
+ * Makefile (check-data): Use $(abi-name) before other guesses.
+ Look in $(add-ons) dirs before scripts/data/.
+ * elf/Makefile (check-data): Likewise.
+
+ * scripts/soversions.awk: Grok ABI line.
+ * Makeconfig ($(common-objpfx)soversions.mk): Likewise.
+ Emit definition for abi-name variable.
+
+2008-05-21 Ulrich Drepper <drepper@redhat.com>
+
+ * string/endian.h: Define new fixed-size hto* and *toh macros only
+ if [__USE_BSD].
+
+ * iconvdata/Depend: Add localedata.
+
+2008-05-21 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * bits/termios.h (ONLCR): Define under [__USE_XOPEN] too.
+
+2008-05-08 David S. Miller <davem@davemloft.net>
+
+ * sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S: Use
+ HIDDEN_JUMPTARGET.
+ * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
+ (__SYSCALL_CLOBBERS): Remove %g* registers.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
+ (__SYSCALL_CLOBBERS): Likewise.
+ * scripts/data/localplt-sparc-linux-gnu.data: New file.
+ * scripts/data/localplt-sparc64-linux-gnu.data: New file.
+
+2008-05-21 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
+ (CALL_ERRNO_LOCATION): Define.
+ (__SYSCALL_STRING, __CLONE_SYSCALL_STRING): Use it.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
+ (CALL_ERRNO_LOCATION): Define.
+ (__SYSCALL_STRING, __CLONE_SYSCALL_STRING): Use it.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/brk.S (__brk): Use
+ HIDDEN_JUMPTARGET for __errno_location call in libc.so.
+
+2008-05-20 Ulrich Drepper <drepper@redhat.com>
+
+ * include/inline-hashtab.h (higher_prime_number): Fix type of mid
+ variable.
+
+2008-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
+ (FIRST_FRAME_POINTER): Define.
+
+2008-05-09 David S. Miller <davem@davemloft.net>
+
+ * sysdeps/sparc/sparc64/backtrace.c: New file.
+
+2008-05-14 David S. Miller <davem@davemloft.net>
+
+ * sysdeps/sparc/machine-gmon.h: New file.
+ * sysdeps/sparc/sparc-mcount.S: Likewise.
+ * sysdeps/sparc/Makefile: Add sparc-mcount target to
+ sysdep_routines in gmon directory.
+
+2008-05-19 Jakub Jelinek <jakub@redhat.com>
+
+ * elf/soinit.c (__EH_FRAME_BEGIN__): Remove.
+
+2008-05-19 Ulrich Drepper <drepper@redhat.com>
+
+ * resolv/res_query.c (__libc_res_nquery): In case one of two
+ answer was too short don't try to read that answer's header.
+
+ * resolv/res_send.c (send_dg): In case of timeout and there are
+ two queries and one has been answered, return value indicating
+ success.
+
+2008-05-18 Ulrich Drepper <drepper@redhat.com>
+
+ * nscd/cache.c (cache_add): Take additional parameter specifying
+ whether this is in response of a cache refill. Check alignment
+ of package data. Revamp waking of pruning thread.
+ (prune_cache): Small optimization.
+ * nscd/nscd.h: Adjust cache_add prototypes.
+ * nscd/aicache.c: Adjust cache_add calls.
+ * nscd/grpcache.c: Likewise.
+ * nscd/hstcache.c: Likewise.
+ * nscd/initgrcache.c: Likewise.
+ * nscd/pwdcache.c: Likewise.
+ * nscd/servicescache.c: Likewise.
+ * nscd/connections.c (restart): Really disable cache use before
+ exec attempt. If it fails, reenable cache.
+ (nscd_run_prune): Initialize wakeup_time. After wakeup, set wakeup
+ time to max to be able to notice concurrent cache additions. Unlock
+ prune_lock while performing gc. Afterwards compute wakeup time with
+ current wakeup_time value in mind.
+
+2008-05-17 Ulrich Drepper <drepper@redhat.com>
+
+ * nscd/mem.c (gc): Avoid stack overflow when allocating move list.
+
+ * nscd/mem.c (gc): Correctly determine highest used array element
+ in mark.
+
+ * nscd/mem.c (markrange): Add assert to check entries are all
+ aligned. Small cleanup in bitmap use.
+
+ * nscd/nscd.h (mem_in_flight): Replace blockaddr field with
+ blockoff of type nscd_ssize_t.
+ * nscd/mem.c (gc): Simplify markrange call for on-flight blocks.
+ (mempoll_alloc): Record block offset and not address.
+
+ * nscd/mem.c (gc): Fix test for stack overuse.
+
+ * nscd/aicache.c (addhstaiX): Fix a few small problems, cleanups,
+ more asserts.
+
+ * sysdeps/posix/getaddrinfo.c (gaih_inet): If nscd reports no
+ entry is available, believe it.
+
+ * resolv/nss_dns/dns-host.c (gaih_getanswer_slice): If there are
+ no answers return NSS_STATUS_NOTFOUND.
+ (gaih_getanswer): Don't call gaih_getanswer_slice if the answer
+ buffer does not have any content.
+
2008-05-16 Ulrich Drepper <drepper@redhat.com>
* string/strcasestr.c (CMP_FUNC): Use __strncasecmp, not strncasecmp.
@@ -174,7 +428,7 @@
* nscd/hstcache.c: Likewise.
* nscd/initgrcache.c: Likewise.
* nscd/pwdcache.c: Likewise.
- * nscd/servicecache.c: Likewise.
+ * nscd/servicescache.c: Likewise.
2008-05-10 Roland McGrath <roland@redhat.com>
diff --git a/libc/Makeconfig b/libc/Makeconfig
index df7516047..913601f02 100644
--- a/libc/Makeconfig
+++ b/libc/Makeconfig
@@ -834,6 +834,7 @@ $(common-objpfx)soversions.mk: $(common-objpfx)soversions.i $(..)Makeconfig
(seen_DEFAULT=0; seen_WORDSIZE32=0; seen_WORDSIZE64=0; \
while read which lib number setname; do \
eval seen_$$which=1; \
+ test x"$$which" != xABI || echo abi-name = "$$lib"; \
test x"$$which" = xDEFAULT || continue; \
case $$number in \
[0-9]*) echo "$$lib.so-version=.$$number"; \
diff --git a/libc/Makefile b/libc/Makefile
index f721ca833..c2498a13b 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -1,4 +1,5 @@
-# Copyright (C) 1991-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+# Copyright (C) 1991-2002,2003,2004,2005,2006,2008
+# 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
@@ -266,8 +267,12 @@ tests-clean:
tests: $(objpfx)c++-types-check.out $(objpfx)check-local-headers.out
ifneq ($(CXX),no)
check-data := $(firstword $(wildcard \
- $(foreach M,$(config-machine) $(base-machine),\
- scripts/data/c++-types-$M-$(config-os).data)))
+ $(foreach D,$(add-ons) scripts/data,\
+ $(patsubst %,$D/c++-types-%.data,\
+ $(abi-name) \
+ $(addsuffix -$(config-os),\
+ $(config-machine) \
+ $(base-machine))))))
ifneq (,$(check-data))
$(objpfx)c++-types-check.out: $(check-data) scripts/check-c++-types.sh
scripts/check-c++-types.sh $< $(CXX) $(filter-out -std=gnu99 -Wstrict-prototypes,$(CFLAGS)) $(CPPFLAGS) > $@
diff --git a/libc/bits/termios.h b/libc/bits/termios.h
index 4dc0fab91..293d0a606 100644
--- a/libc/bits/termios.h
+++ b/libc/bits/termios.h
@@ -135,8 +135,10 @@ struct termios
/* Output modes. */
tcflag_t c_oflag;
#define OPOST (1 << 0) /* Perform output processing. */
-#ifdef __USE_BSD
+#if defined __USE_BSD || defined __USE_XOPEN
# define ONLCR (1 << 1) /* Map NL to CR-NL on output. */
+#endif
+#ifdef __USE_BSD
# define OXTABS TAB3 /* Expand tabs to spaces. */
# define ONOEOT (1 << 3) /* Discard EOT (^D) on output. */
#endif
diff --git a/libc/elf/Makefile b/libc/elf/Makefile
index efe8942e6..e4f693f0e 100644
--- a/libc/elf/Makefile
+++ b/libc/elf/Makefile
@@ -847,10 +847,14 @@ $(objpfx)tst-dlmodcount: $(libdl)
$(objpfx)tst-dlmodcount.out: $(test-modules)
check-data := $(firstword $(wildcard \
- $(patsubst %,../scripts/data/localplt-%.data,\
- $(addsuffix -$(config-os),\
- $(config-machine) $(base-machine))\
- generic)))
+ $(foreach D,$(add-ons) scripts/data,\
+ $(patsubst %,$(..)$D/localplt-%.data,\
+ $(abi-name) \
+ $(addsuffix -$(config-os),\
+ $(config-machine) \
+ $(base-machine)) \
+ generic))))
+
tests: $(objpfx)check-localplt.out
ifeq ($(have-thread-library),yes)
diff --git a/libc/elf/soinit.c b/libc/elf/soinit.c
index c0a881ef5..6fecbb567 100644
--- a/libc/elf/soinit.c
+++ b/libc/elf/soinit.c
@@ -20,10 +20,6 @@ run_hooks (void (*const list[]) (void))
(**list) ();
}
-static const char __EH_FRAME_BEGIN__[]
- __attribute__ ((used, section (".eh_frame")))
- = { };
-
/* This function will be called from _init in init-first.c. */
void
__libc_global_ctors (void)
diff --git a/libc/iconvdata/Depend b/libc/iconvdata/Depend
index 401deb536..38c28d0c9 100644
--- a/libc/iconvdata/Depend
+++ b/libc/iconvdata/Depend
@@ -1 +1,2 @@
iconv
+localedata
diff --git a/libc/include/inline-hashtab.h b/libc/include/inline-hashtab.h
index 1c36bd7fc..c359161c5 100644
--- a/libc/include/inline-hashtab.h
+++ b/libc/include/inline-hashtab.h
@@ -74,7 +74,7 @@ higher_prime_number (unsigned long n)
while (low != high)
{
- const unsigned long *mid = low + (high - low) / 2;
+ const uint32_t *mid = low + (high - low) / 2;
if (n > *mid)
low = mid + 1;
else
@@ -142,8 +142,7 @@ htab_delete (struct hashtab *htab)
int i;
for (i = htab->size - 1; i >= 0; i--)
- if (htab->entries[i])
- free (htab->entries[i]);
+ free (htab->entries[i]);
if (htab->free)
htab->free (htab->entries);
diff --git a/libc/libio/freopen.c b/libc/libio/freopen.c
index d94a5629f..d80815f91 100644
--- a/libc/libio/freopen.c
+++ b/libc/libio/freopen.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,95,96,97,98,2000,2001,2002,2003
+/* Copyright (C) 1993,95,96,97,98,2000,2001,2002,2003,2008
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -80,8 +80,7 @@ freopen (filename, mode, fp)
if (fd != -1)
{
__close (fd);
- if (filename != NULL)
- free ((char *) filename);
+ free ((char *) filename);
}
_IO_release_lock (fp);
return result;
diff --git a/libc/libio/freopen64.c b/libc/libio/freopen64.c
index f8da78c46..2dad6d7b4 100644
--- a/libc/libio/freopen64.c
+++ b/libc/libio/freopen64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1995,1996,1997,1998,2000,2001,2002, 2003
+/* Copyright (C) 1993,1995,1996,1997,1998,2000,2001,2002, 2003, 2008
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -64,8 +64,7 @@ freopen64 (filename, mode, fp)
if (fd != -1)
{
__close (fd);
- if (filename != NULL)
- free ((char *) filename);
+ free ((char *) filename);
}
_IO_release_lock (fp);
return result;
diff --git a/libc/libio/stdio.h b/libc/libio/stdio.h
index 1cbe9204b..9dacbe245 100644
--- a/libc/libio/stdio.h
+++ b/libc/libio/stdio.h
@@ -475,7 +475,7 @@ extern int __REDIRECT (vfscanf,
__isoc99_vfscanf)
__attribute__ ((__format__ (__scanf__, 2, 0))) __wur;
extern int __REDIRECT (vscanf, (__const char *__restrict __format,
- _G_va_list __arg), __isoc99_vfscanf)
+ _G_va_list __arg), __isoc99_vscanf)
__attribute__ ((__format__ (__scanf__, 1, 0))) __wur;
extern int __REDIRECT (vsscanf,
(__const char *__restrict __s,
diff --git a/libc/locale/programs/ld-collate.c b/libc/locale/programs/ld-collate.c
index 0805063b7..6425f1c6b 100644
--- a/libc/locale/programs/ld-collate.c
+++ b/libc/locale/programs/ld-collate.c
@@ -2817,8 +2817,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
else
{
col_elem_free:
- if (symbol != NULL)
- free ((char *) symbol);
+ free ((char *) symbol);
free (arg->val.str.startmb);
free (arg->val.str.startwc);
}
@@ -2998,8 +2997,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
arg = lr_token (ldfile, charmap, result, repertoire, verbose);
if (arg->tok != tok_bsymbol)
{
- if (newname != NULL)
- free ((char *) newname);
+ free ((char *) newname);
goto err_label;
}
@@ -3013,10 +3011,8 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
"LC_COLLATE");
sym_equiv_free:
- if (newname != NULL)
- free ((char *) newname);
- if (symname != NULL)
- free ((char *) symname);
+ free ((char *) newname);
+ free ((char *) symname);
break;
}
if (symname == NULL)
diff --git a/libc/localedata/ChangeLog b/libc/localedata/ChangeLog
index 878b10cce..1863ce0ce 100644
--- a/libc/localedata/ChangeLog
+++ b/libc/localedata/ChangeLog
@@ -1,3 +1,8 @@
+2008-05-21 Ulrich Drepper <drepper@redhat.com>
+
+ * locales/iso14651_t1_common: Remove U0C0D entry added for Telugu.
+ Reported by Pravin Satpute.
+
2008-05-16 Ulrich Drepper <drepper@redhat.com>
* locales/iso14651_t1_common: Remove duplicate U0C7B definition.
diff --git a/libc/localedata/locales/iso14651_t1_common b/libc/localedata/locales/iso14651_t1_common
index e9721fd07..fcbd897f0 100644
--- a/libc/localedata/locales/iso14651_t1_common
+++ b/libc/localedata/locales/iso14651_t1_common
@@ -3406,7 +3406,6 @@ order_start <TELUGU>;forward;forward;forward;forward,position
<U0C60> <tvw-vocalicrr>;<BAS>;<MIN>;IGNORE
<U0C0C> <tvw-vocalicl>;<BAS>;<MIN>;IGNORE
<U0C61> <tvw-vocalicll>;<BAS>;<MIN>;IGNORE
-<U0C0D> <tvw-candrae>;<BAS>;<MIN>;IGNORE
<U0C0E> <tvw-shorte>;<BAS>;<MIN>;IGNORE
<U0C0F> <tvw-e>;<BAS>;<MIN>;IGNORE
<U0C10> <tvw-ai>;<BAS>;<MIN>;IGNORE
@@ -3416,8 +3415,6 @@ order_start <TELUGU>;forward;forward;forward;forward,position
<U0C15> <t-ka>;<BAS>;<MIN>;IGNORE
<U0C16> <t-kha>;<BAS>;<MIN>;IGNORE
<U0C17> <t-ga>;<BAS>;<MIN>;IGNORE
-#XXX This is wrong since there is already a definition for U0C7B.
-#<U0C7B> <t-gga>;<BAS>;<MIN>;IGNORE
<U0C18> <t-gha>;<BAS>;<MIN>;IGNORE
<U0C19> <t-nga>;<BAS>;<MIN>;IGNORE
<U0C1A> <t-ca>;<BAS>;<MIN>;IGNORE
diff --git a/libc/math/libm-test.inc b/libc/math/libm-test.inc
index 267d6077e..6d9a3ec6c 100644
--- a/libc/math/libm-test.inc
+++ b/libc/math/libm-test.inc
@@ -2511,8 +2511,8 @@ exp_test (void)
TEST_f_f (exp, 0.75L, 2.11700001661267466854536981983709561L);
TEST_f_f (exp, 50.0L, 5184705528587072464087.45332293348538L);
TEST_f_f (exp, 88.72269439697265625L, 3.40233126623160774937554134772290447915e38L);
-#ifdef TEST_LDOUBLE
- /* The result can only be represented in long double. */
+#if defined TEST_LDOUBLE && __LDBL_MAX_EXP__ > 1024
+ /* The result can only be represented in sane long double. */
TEST_f_f (exp, 1000.0L, 0.197007111401704699388887935224332313e435L);
#endif
diff --git a/libc/misc/fstab.c b/libc/misc/fstab.c
index b434203a8..ab5581e9b 100644
--- a/libc/misc/fstab.c
+++ b/libc/misc/fstab.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 1998, 2000, 2008
+ 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
@@ -185,6 +186,5 @@ libc_freeres_fn (fstab_free)
char *buffer;
buffer = fstab_state.fs_buffer;
- if (buffer != NULL)
- free ((void *) buffer);
+ free ((void *) buffer);
}
diff --git a/libc/misc/regexp.h b/libc/misc/regexp.h
index b7b50b710..0e979d2d8 100644
--- a/libc/misc/regexp.h
+++ b/libc/misc/regexp.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 1999, 2004, 2008
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -129,8 +130,9 @@ compile (char *__restrict instring, char *__restrict expbuf,
__expr_ptr = (regex_t *) expbuf;
/* The remaining space in the buffer can be used for the compiled
pattern. */
- __expr_ptr->buffer = expbuf + sizeof (regex_t);
- __expr_ptr->allocated = endbuf - (char *) __expr_ptr->buffer;
+ __expr_ptr->__REPB_PREFIX (buffer) = expbuf + sizeof (regex_t);
+ __expr_ptr->__REPB_PREFIX (allocated)
+ = endbuf - (char *) __expr_ptr->__REPB_PREFIX (buffer);
while ((__ch = (GETC ())) != eof)
{
@@ -162,7 +164,10 @@ compile (char *__restrict instring, char *__restrict expbuf,
}
__input_buffer[__current_size++] = __ch;
}
- __input_buffer[__current_size++] = '\0';
+ if (__current_size)
+ __input_buffer[__current_size++] = '\0';
+ else
+ __input_buffer = "";
/* Now compile the pattern. */
__error = regcomp (__expr_ptr, __input_buffer, REG_NEWLINE);
@@ -198,7 +203,8 @@ compile (char *__restrict instring, char *__restrict expbuf,
}
/* Everything is ok. */
- RETURN ((char *) (__expr_ptr->buffer + __expr_ptr->used));
+ RETURN ((char *) (__expr_ptr->__REPB_PREFIX (buffer)
+ + __expr_ptr->__REPB_PREFIX (used)));
}
#endif
diff --git a/libc/nptl/ChangeLog b/libc/nptl/ChangeLog
index 0bbdd6e31..744f90d78 100644
--- a/libc/nptl/ChangeLog
+++ b/libc/nptl/ChangeLog
@@ -1,3 +1,48 @@
+2008-06-12 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/pthread/pthread.h: Remove inadvertant checkin.
+
+2008-05-17 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * sysdeps/pthread/pthread.h: Fix typo in comment.
+
+2008-05-28 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/pthread/createthread.c (do_clone): Pass accurate length
+ of CPU set to the kernel.
+
+2008-05-23 Paul Pluzhnikov <ppluzhnikov@google.com>
+
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S: Add
+ cfi directives.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+
+2008-05-22 Paul Pluzhnikov <ppluzhnikov@google.com>
+
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S: Add
+ cfi directives.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+ Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S:
+ Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+ Likewise.
+
+2008-05-26 Ulrich Drepper <drepper@redhat.com>
+
+ * tst-typesizes.c: Explicitly check __SIZEOF_PTHREAD_* constants.
+
+2008-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ David S. Miller <davem@davemloft.net>
+
+ * sysdeps/unix/sysv/linux/sparc/sparc64/Makefile: New file.
+
2008-05-10 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Access
diff --git a/libc/nptl/Makefile b/libc/nptl/Makefile
index 59f9554fb..6f72e08a8 100644
--- a/libc/nptl/Makefile
+++ b/libc/nptl/Makefile
@@ -214,9 +214,9 @@ tests = tst-typesizes \
tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \
tst-robustpi6 tst-robustpi7 tst-robustpi8 tst-robustpi9 \
- tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
- tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
- tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
+ tst-rwlock1 tst-rwlock2 tst-rwlock2a tst-rwlock3 tst-rwlock4 \
+ tst-rwlock5 tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 \
+ tst-rwlock10 tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
tst-once1 tst-once2 tst-once3 tst-once4 \
tst-key1 tst-key2 tst-key3 tst-key4 \
tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
diff --git a/libc/nptl/sysdeps/pthread/createthread.c b/libc/nptl/sysdeps/pthread/createthread.c
index 59e62c2dc..66fafe805 100644
--- a/libc/nptl/sysdeps/pthread/createthread.c
+++ b/libc/nptl/sysdeps/pthread/createthread.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -98,7 +98,7 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
if (attr->cpuset != NULL)
{
res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
- sizeof (cpu_set_t), attr->cpuset);
+ attr->cpusetsize, attr->cpuset);
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
{
diff --git a/libc/nptl/sysdeps/pthread/pthread.h b/libc/nptl/sysdeps/pthread/pthread.h
index f3ab0ae71..d5ffd383f 100644
--- a/libc/nptl/sysdeps/pthread/pthread.h
+++ b/libc/nptl/sysdeps/pthread/pthread.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -127,7 +127,7 @@ enum
# if __WORDSIZE == 64
# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
# else
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
@@ -399,7 +399,7 @@ extern int pthread_attr_getaffinity_np (__const pthread_attr_t *__attr,
/* Initialize thread attribute *ATTR with attributes corresponding to the
- already running thread TH. It shall be called on unitialized ATTR
+ already running thread TH. It shall be called on uninitialized ATTR
and destroyed with pthread_attr_destroy when no longer needed. */
extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr)
__THROW __nonnull ((2));
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S
index 77d252de8..040d7f8c3 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S
@@ -27,7 +27,10 @@
.type pthread_barrier_wait,@function
.align 16
pthread_barrier_wait:
+ cfi_startproc
pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
movl 8(%esp), %ebx
@@ -45,6 +48,8 @@ pthread_barrier_wait:
/* There are more threads to come. */
pushl %esi
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -12)
#if CURR_EVENT == 0
movl (%ebx), %edx
@@ -101,9 +106,16 @@ pthread_barrier_wait:
10: movl %esi, %eax /* != PTHREAD_BARRIER_SERIAL_THREAD */
popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
ret
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+
/* The necessary number of threads arrived. */
3:
#if CURR_EVENT == 0
@@ -140,8 +152,12 @@ pthread_barrier_wait:
5: orl $-1, %eax /* == PTHREAD_BARRIER_SERIAL_THREAD */
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
ret
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
1: movl PRIVATE(%ebx), %ecx
leal MUTEX(%ebx), %edx
xorl $LLL_SHARED, %ecx
@@ -154,6 +170,8 @@ pthread_barrier_wait:
call __lll_unlock_wake
jmp 5b
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -12)
6: movl PRIVATE(%ebx), %ecx
leal MUTEX(%ebx), %eax
xorl $LLL_SHARED, %ecx
@@ -165,4 +183,5 @@ pthread_barrier_wait:
xorl $LLL_SHARED, %ecx
call __lll_unlock_wake
jmp 10b
+ cfi_endproc
.size pthread_barrier_wait,.-pthread_barrier_wait
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
index 776c47f6c..f46b4b874 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
@@ -32,11 +32,19 @@
.type __pthread_cond_broadcast, @function
.align 16
__pthread_cond_broadcast:
-
+ cfi_startproc
pushl %ebx
+ cfi_adjust_cfa_offset(4)
pushl %esi
+ cfi_adjust_cfa_offset(4)
pushl %edi
+ cfi_adjust_cfa_offset(4)
pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+ cfi_offset(%esi, -12)
+ cfi_offset(%edi, -16)
+ cfi_offset(%ebp, -20)
movl 20(%esp), %ebx
@@ -114,11 +122,24 @@ __pthread_cond_broadcast:
10: xorl %eax, %eax
popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
ret
+ cfi_adjust_cfa_offset(16)
+ cfi_offset(%ebx, -8)
+ cfi_offset(%esi, -12)
+ cfi_offset(%edi, -16)
+ cfi_offset(%ebp, -20)
.align 16
/* Unlock. */
4: LOCK
@@ -127,11 +148,24 @@ __pthread_cond_broadcast:
6: xorl %eax, %eax
popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
ret
+ cfi_adjust_cfa_offset(16)
+ cfi_offset(%ebx, -8)
+ cfi_offset(%esi, -12)
+ cfi_offset(%edi, -16)
+ cfi_offset(%ebp, -20)
/* Initial locking failed. */
1:
#if cond_lock == 0
@@ -199,6 +233,7 @@ __pthread_cond_broadcast:
movl $SYS_futex, %eax
ENTER_KERNEL
jmp 10b
+ cfi_endproc
.size __pthread_cond_broadcast, .-__pthread_cond_broadcast
versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
GLIBC_2_3_2)
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
index 36a18036c..4909f4910 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
@@ -33,8 +33,13 @@
.align 16
__pthread_cond_signal:
+ cfi_startproc
pushl %ebx
+ cfi_adjust_cfa_offset(4)
pushl %edi
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+ cfi_offset(%edi, -12)
movl 12(%esp), %edi
@@ -69,7 +74,12 @@ __pthread_cond_signal:
/* Wake up one thread. */
pushl %esi
+ cfi_adjust_cfa_offset(4)
pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -16)
+ cfi_offset(%ebp, -20)
+
#if FUTEX_PRIVATE_FLAG > 255
xorl %ecx, %ecx
#endif
@@ -91,7 +101,11 @@ __pthread_cond_signal:
ENTER_KERNEL */
int $0x80
popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
/* For any kind of error, we try again with WAKE.
The general test also covers running on old kernels. */
@@ -100,9 +114,17 @@ __pthread_cond_signal:
6: xorl %eax, %eax
popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
ret
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%ebx, -8)
+ cfi_offset(%edi, -12)
+
7: /* %ecx should be either FUTEX_WAKE_OP or
FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG from the previous syscall. */
xorl $(FUTEX_WAKE ^ FUTEX_WAKE_OP), %ecx
@@ -152,6 +174,7 @@ __pthread_cond_signal:
call __lll_lock_wait
jmp 2b
+ cfi_endproc
.size __pthread_cond_signal, .-__pthread_cond_signal
versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
GLIBC_2_3_2)
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
index 2ddeed072..4e5f0c5b2 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
@@ -30,8 +30,13 @@
.type __pthread_rwlock_rdlock,@function
.align 16
__pthread_rwlock_rdlock:
+ cfi_startproc
pushl %esi
+ cfi_adjust_cfa_offset(4)
pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -8)
+ cfi_offset(%ebx, -12)
xorl %esi, %esi
movl 12(%esp), %ebx
@@ -113,9 +118,16 @@ __pthread_rwlock_rdlock:
movl %edx, %eax
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
ret
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%esi, -8)
+ cfi_offset(%ebx, -12)
1:
#if MUTEX == 0
movl %ebx, %edx
@@ -171,6 +183,7 @@ __pthread_rwlock_rdlock:
movzbl PSHARED(%ebx), %ecx
call __lll_lock_wait
jmp 13b
+ cfi_endproc
.size __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
.globl pthread_rwlock_rdlock
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
index 89027284e..2b84cd06c 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
@@ -30,11 +30,21 @@
.type pthread_rwlock_timedrdlock,@function
.align 16
pthread_rwlock_timedrdlock:
+ cfi_startproc
pushl %esi
+ cfi_adjust_cfa_offset(4)
pushl %edi
+ cfi_adjust_cfa_offset(4)
pushl %ebx
+ cfi_adjust_cfa_offset(4)
pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -8)
+ cfi_offset(%edi, -12)
+ cfi_offset(%ebx, -16)
+ cfi_offset(%ebp, -20)
subl $8, %esp
+ cfi_adjust_cfa_offset(8)
movl 28(%esp), %ebp
movl 32(%esp), %edi
@@ -150,12 +160,26 @@ pthread_rwlock_timedrdlock:
7: movl %edx, %eax
addl $8, %esp
+ cfi_adjust_cfa_offset(-8)
popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
ret
+ cfi_adjust_cfa_offset(24)
+ cfi_offset(%esi, -8)
+ cfi_offset(%edi, -12)
+ cfi_offset(%ebx, -16)
+ cfi_offset(%ebp, -20)
1:
#if MUTEX == 0
movl %ebp, %edx
@@ -216,4 +240,5 @@ pthread_rwlock_timedrdlock:
19: movl $EINVAL, %edx
jmp 9b
+ cfi_endproc
.size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
index 0cf02e057..91652467c 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
@@ -30,11 +30,21 @@
.type pthread_rwlock_timedwrlock,@function
.align 16
pthread_rwlock_timedwrlock:
+ cfi_startproc
pushl %esi
+ cfi_adjust_cfa_offset(4)
pushl %edi
+ cfi_adjust_cfa_offset(4)
pushl %ebx
+ cfi_adjust_cfa_offset(4)
pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -8)
+ cfi_offset(%edi, -12)
+ cfi_offset(%ebx, -16)
+ cfi_offset(%ebp, -20)
subl $8, %esp
+ cfi_adjust_cfa_offset(8)
movl 28(%esp), %ebp
movl 32(%esp), %edi
@@ -148,12 +158,26 @@ pthread_rwlock_timedwrlock:
7: movl %edx, %eax
addl $8, %esp
+ cfi_adjust_cfa_offset(-8)
popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
ret
+ cfi_adjust_cfa_offset(24)
+ cfi_offset(%esi, -8)
+ cfi_offset(%edi, -12)
+ cfi_offset(%ebx, -16)
+ cfi_offset(%ebp, -20)
1:
#if MUTEX == 0
movl %ebp, %edx
@@ -209,4 +233,5 @@ pthread_rwlock_timedwrlock:
19: movl $EINVAL, %edx
jmp 9b
+ cfi_endproc
.size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
index bf9c33ea9..aabb92960 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
@@ -29,8 +29,13 @@
.type __pthread_rwlock_unlock,@function
.align 16
__pthread_rwlock_unlock:
+ cfi_startproc
pushl %ebx
+ cfi_adjust_cfa_offset(4)
pushl %edi
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+ cfi_offset(%edi, -12)
movl 12(%esp), %edi
@@ -87,9 +92,16 @@ __pthread_rwlock_unlock:
xorl %eax, %eax
popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
ret
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%ebx, -8)
+ cfi_offset(%edi, -12)
.align 16
6: LOCK
#if MUTEX == 0
@@ -133,7 +145,7 @@ __pthread_rwlock_unlock:
movzbl PSHARED(%edi), %ecx
call __lll_unlock_wake
jmp 8b
-
+ cfi_endproc
.size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
.globl pthread_rwlock_unlock
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
index d13bb5132..100736499 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
@@ -30,8 +30,13 @@
.type __pthread_rwlock_wrlock,@function
.align 16
__pthread_rwlock_wrlock:
+ cfi_startproc
pushl %esi
+ cfi_adjust_cfa_offset(4)
pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -8)
+ cfi_offset(%ebx, -12)
xorl %esi, %esi
movl 12(%esp), %ebx
@@ -111,9 +116,16 @@ __pthread_rwlock_wrlock:
movl %edx, %eax
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
ret
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%esi, -8)
+ cfi_offset(%ebx, -12)
1:
#if MUTEX == 0
movl %ebx, %edx
@@ -162,6 +174,7 @@ __pthread_rwlock_wrlock:
movzbl PSHARED(%ebx), %ecx
call __lll_lock_wait
jmp 13b
+ cfi_endproc
.size __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
.globl pthread_rwlock_wrlock
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
index 2edcdde4f..86992c877 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
@@ -30,7 +30,10 @@
.type __new_sem_post,@function
.align 16
__new_sem_post:
+ cfi_startproc
pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
movl 8(%esp), %ebx
@@ -64,8 +67,12 @@ __new_sem_post:
2: xorl %eax, %eax
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
ret
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
1:
#ifdef PIC
call __i686.get_pc_thunk.bx
@@ -116,14 +123,20 @@ __new_sem_post:
orl $-1, %eax
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
ret
+ cfi_endproc
.size __new_sem_post,.-__new_sem_post
versioned_symbol(libpthread, __new_sem_post, sem_post, GLIBC_2_1)
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
.global __old_sem_post
.type __old_sem_post,@function
__old_sem_post:
+ cfi_startproc
pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
movl 8(%esp), %ebx
LOCK
@@ -139,7 +152,10 @@ __old_sem_post:
xorl %eax, %eax
popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
ret
+ cfi_endproc
.size __old_sem_post,.-__old_sem_post
compat_symbol(libpthread, __old_sem_post, sem_post, GLIBC_2_0)
#endif
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile b/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
new file mode 100644
index 000000000..774b267ef
--- /dev/null
+++ b/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
@@ -0,0 +1,4 @@
+ifeq ($(subdir),nptl)
+CFLAGS-pause.c += -fexceptions
+CFLAGS-sigsuspend.c += -fexceptions
+endif
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
index 0fa271442..366c96fc3 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
@@ -33,10 +33,19 @@
.type pthread_rwlock_timedrdlock,@function
.align 16
pthread_rwlock_timedrdlock:
+ cfi_startproc
pushq %r12
+ cfi_adjust_cfa_offset(8)
pushq %r13
+ cfi_adjust_cfa_offset(8)
pushq %r14
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%r12, -16)
+ cfi_offset(%r13, -24)
+ cfi_offset(%r14, -32)
+
subq $16, %rsp
+ cfi_adjust_cfa_offset(16)
movq %rdi, %r12
movq %rsi, %r13
@@ -155,11 +164,22 @@ pthread_rwlock_timedrdlock:
7: movq %rdx, %rax
addq $16, %rsp
+ cfi_adjust_cfa_offset(-16)
popq %r14
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r14)
popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
retq
+ cfi_adjust_cfa_offset(40)
+ cfi_offset(%r12, -16)
+ cfi_offset(%r13, -24)
+ cfi_offset(%r14, -32)
1: movl PSHARED(%rdi), %esi
#if MUTEX != 0
addq $MUTEX, %rdi
@@ -214,4 +234,5 @@ pthread_rwlock_timedrdlock:
19: movl $EINVAL, %edx
jmp 9b
+ cfi_endproc
.size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
index 1e43933ca..dde6b5883 100644
--- a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
+++ b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
@@ -33,10 +33,19 @@
.type pthread_rwlock_timedwrlock,@function
.align 16
pthread_rwlock_timedwrlock:
+ cfi_startproc
pushq %r12
+ cfi_adjust_cfa_offset(8)
pushq %r13
+ cfi_adjust_cfa_offset(8)
pushq %r14
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%r12, -16)
+ cfi_offset(%r13, -24)
+ cfi_offset(%r14, -32)
+
subq $16, %rsp
+ cfi_adjust_cfa_offset(16)
movq %rdi, %r12
movq %rsi, %r13
@@ -152,11 +161,22 @@ pthread_rwlock_timedwrlock:
7: movq %rdx, %rax
addq $16, %rsp
+ cfi_adjust_cfa_offset(-16)
popq %r14
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r14)
popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
retq
+ cfi_adjust_cfa_offset(40)
+ cfi_offset(%r12, -16)
+ cfi_offset(%r13, -24)
+ cfi_offset(%r14, -32)
1: movl PSHARED(%rdi), %esi
#if MUTEX != 0
addq $MUTEX, %rdi
@@ -206,4 +226,5 @@ pthread_rwlock_timedwrlock:
19: movl $EINVAL, %edx
jmp 9b
+ cfi_endproc
.size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock
diff --git a/libc/nptl/tst-rwlock2.c b/libc/nptl/tst-rwlock2.c
index 6f38682b8..2d2e8e4a3 100644
--- a/libc/nptl/tst-rwlock2.c
+++ b/libc/nptl/tst-rwlock2.c
@@ -26,15 +26,41 @@ static int
do_test (void)
{
pthread_rwlock_t r;
+ pthread_rwlockattr_t at;
int e;
- if (pthread_rwlock_init (&r, NULL) != 0)
+ if (pthread_rwlockattr_init (&at) != 0)
+ {
+ puts ("rwlockattr_init failed");
+ return 1;
+ }
+ puts ("rwlockattr_init succeeded");
+
+#ifndef TYPE
+# define TYPE PTHREAD_RWLOCK_PREFER_READER_NP
+#endif
+
+ if (pthread_rwlockattr_setkind_np (&at, TYPE) != 0)
+ {
+ puts ("rwlockattr_setkind failed");
+ return 1;
+ }
+ puts ("rwlockattr_setkind succeeded");
+
+ if (pthread_rwlock_init (&r, &at) != 0)
{
puts ("rwlock_init failed");
return 1;
}
puts ("rwlock_init succeeded");
+ if (pthread_rwlockattr_destroy (&at) != 0)
+ {
+ puts ("rwlockattr_destroy failed");
+ return 1;
+ }
+ puts ("rwlockattr_destroy succeeded");
+
if (pthread_rwlock_wrlock (&r) != 0)
{
puts ("1st rwlock_wrlock failed");
diff --git a/libc/nptl/tst-rwlock2a.c b/libc/nptl/tst-rwlock2a.c
new file mode 100644
index 000000000..615de5c01
--- /dev/null
+++ b/libc/nptl/tst-rwlock2a.c
@@ -0,0 +1,2 @@
+#define TYPE PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
+#include "tst-rwlock2.c"
diff --git a/libc/nptl/tst-typesizes.c b/libc/nptl/tst-typesizes.c
index 17a1e297d..545cee6bd 100644
--- a/libc/nptl/tst-typesizes.c
+++ b/libc/nptl/tst-typesizes.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
@@ -21,6 +21,25 @@
#include <pthreadP.h>
#include <semaphore.h>
+static const struct
+{
+ const char *name;
+ size_t expected;
+ size_t is;
+} types[] =
+ {
+#define T(t, c) \
+ { #t, c, sizeof (t) }
+ T (pthread_attr_t, __SIZEOF_PTHREAD_ATTR_T),
+ T (pthread_mutex_t, __SIZEOF_PTHREAD_MUTEX_T),
+ T (pthread_mutexattr_t, __SIZEOF_PTHREAD_MUTEXATTR_T),
+ T (pthread_cond_t, __SIZEOF_PTHREAD_COND_T),
+ T (pthread_condattr_t, __SIZEOF_PTHREAD_CONDATTR_T),
+ T (pthread_rwlock_t, __SIZEOF_PTHREAD_RWLOCK_T),
+ T (pthread_rwlockattr_t, __SIZEOF_PTHREAD_RWLOCKATTR_T),
+ T (pthread_barrier_t, __SIZEOF_PTHREAD_BARRIER_T),
+ T (pthread_barrierattr_t, __SIZEOF_PTHREAD_BARRIERATTR_T)
+ };
static int
do_test (void)
@@ -62,6 +81,14 @@ do_test (void)
TEST_TYPE2 (sem_t, struct new_sem);
TEST_TYPE2 (sem_t, struct old_sem);
+ for (size_t i = 0; i < sizeof (types) / sizeof (types[0]); ++i)
+ if (types[i].expected != types[i].is)
+ {
+ printf ("%s: expected %zu, is %zu\n",
+ types[i].name, types[i].expected, types[i].is);
+ result = 1;
+ }
+
return result;
}
diff --git a/libc/nscd/aicache.c b/libc/nscd/aicache.c
index 918efc9f3..5ffab76a0 100644
--- a/libc/nscd/aicache.c
+++ b/libc/nscd/aicache.c
@@ -114,7 +114,6 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
char *tmpbuf6 = alloca (tmpbuf6len);
size_t tmpbuf4len = 0;
char *tmpbuf4 = NULL;
- char *canon = NULL;
int32_t ttl = INT32_MAX;
ssize_t total = 0;
char *key_copy = NULL;
@@ -126,6 +125,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
int status[2] = { NSS_STATUS_UNAVAIL, NSS_STATUS_UNAVAIL };
int naddrs = 0;
size_t addrslen = 0;
+ char *canon = NULL;
size_t canonlen;
nss_gethostbyname4_r fct4 = __nss_lookup_function (nip,
@@ -136,9 +136,11 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
while (1)
{
rc6 = 0;
- status[0] = DL_CALL_FCT (fct4, (key, &at, tmpbuf6, tmpbuf6len,
+ herrno = 0;
+ status[1] = DL_CALL_FCT (fct4, (key, &at, tmpbuf6, tmpbuf6len,
&rc6, &herrno, &ttl));
- if (rc6 != ERANGE || herrno != NETDB_INTERNAL)
+ if (rc6 != ERANGE || (herrno != NETDB_INTERNAL
+ && herrno != TRY_AGAIN))
break;
tmpbuf6 = extend_alloca (tmpbuf6, tmpbuf6len, 2 * tmpbuf6len);
}
@@ -146,22 +148,21 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
if (rc6 != 0 && herrno == NETDB_INTERNAL)
goto out;
- if (status[0] != NSS_STATUS_SUCCESS)
+ if (status[1] != NSS_STATUS_SUCCESS)
goto next_nip;
/* We found the data. Count the addresses and the size. */
- for (struct gaih_addrtuple *at2 = at; at2 != NULL; at2 = at2->next)
+ for (const struct gaih_addrtuple *at2 = at; at2 != NULL;
+ at2 = at2->next)
{
++naddrs;
- /* We handle unknown types here the best we can: assume
- the maximum size for the address. */
+ /* We do not handle anything other than IPv4 and IPv6
+ addresses. The getaddrinfo implementation does not
+ either so it is not worth trying to do more. */
if (at2->family == AF_INET)
addrslen += INADDRSZ;
- else if (at2->family == AF_INET6
- && IN6ADDRSZ != sizeof (at2->addr))
+ else if (at2->family == AF_INET6)
addrslen += IN6ADDRSZ;
- else
- addrslen += sizeof (at2->addr);
}
canon = at->name;
canonlen = strlen (canon) + 1;
@@ -191,19 +192,17 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
}
/* Fill in the address and address families. */
- char *addrs = (char *) (&dataset->resp + 1);
+ char *addrs = dataset->strdata;
uint8_t *family = (uint8_t *) (addrs + addrslen);
- for (struct gaih_addrtuple *at2 = at; at2 != NULL; at2 = at2->next)
+ for (const struct gaih_addrtuple *at2 = at; at2 != NULL;
+ at2 = at2->next)
{
*family++ = at2->family;
if (at2->family == AF_INET)
addrs = mempcpy (addrs, at2->addr, INADDRSZ);
- else if (at2->family == AF_INET6
- && IN6ADDRSZ != sizeof (at2->addr))
+ else if (at2->family == AF_INET6)
addrs = mempcpy (addrs, at2->addr, IN6ADDRSZ);
- else
- addrs = mempcpy (addrs, at2->addr, sizeof (at2->addr));
}
cp = family;
@@ -373,7 +372,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
}
/* Fill in the address and address families. */
- char *addrs = (char *) (&dataset->resp + 1);
+ char *addrs = dataset->strdata;
uint8_t *family = (uint8_t *) (addrs + addrslen);
for (int j = 0; j < 2; ++j)
@@ -411,6 +410,8 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
key_copy = memcpy (cp, key, req->key_len);
+ assert (cp == (char *) dataset + total);
+
/* Now we can determine whether on refill we have to create a
new record or not. */
if (he != NULL)
@@ -557,7 +558,7 @@ next_nip:
pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, key_copy, req->key_len, &dataset->head,
- true, db, uid);
+ true, db, uid, he == NULL);
pthread_rwlock_unlock (&db->lock);
diff --git a/libc/nscd/cache.c b/libc/nscd/cache.c
index f4a9de530..cd6e6b444 100644
--- a/libc/nscd/cache.c
+++ b/libc/nscd/cache.c
@@ -135,7 +135,7 @@ cache_search (request_type type, void *key, size_t len,
int
cache_add (int type, const void *key, size_t len, struct datahead *packet,
bool first, struct database_dyn *table,
- uid_t owner)
+ uid_t owner, bool prune_wakeup)
{
if (__builtin_expect (debug_level >= 2, 0))
{
@@ -180,6 +180,7 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
assert (newp->key + newp->len <= table->head->first_free);
newp->owner = owner;
newp->packet = (char *) packet - table->data;
+ assert ((newp->packet & BLOCK_ALIGN_M1) == 0);
/* Put the new entry in the first position. */
do
@@ -211,19 +212,27 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
(char *) &table->head->array[hash] - (char *) table->head
+ sizeof (ref_t), MS_ASYNC);
- /* Perhaps the prune thread for the data is not running in a long
- time. Wake it if necessary. */
- time_t next_wakeup = table->wakeup_time;
- while (next_wakeup + CACHE_PRUNE_INTERVAL > packet->timeout)
- if (atomic_compare_and_exchange_bool_acq (&table->wakeup_time,
- packet->timeout,
- next_wakeup) == 0)
- {
+ /* We do not have to worry about the pruning thread if we are
+ re-adding the data since this is done by the pruning thread. We
+ also do not have to do anything in case this is not the first
+ time the data is entered since different data heads all have the
+ same timeout. */
+ if (first && prune_wakeup)
+ {
+ /* Perhaps the prune thread for the table is not running in a long
+ time. Wake it if necessary. */
+ pthread_mutex_lock (&table->prune_lock);
+ time_t next_wakeup = table->wakeup_time;
+ bool do_wakeup = false;
+ if (next_wakeup > packet->timeout + CACHE_PRUNE_INTERVAL)
+ {
+ table->wakeup_time = packet->timeout;
+ do_wakeup = true;
+ }
+ pthread_mutex_unlock (&table->prune_lock);
+ if (do_wakeup)
pthread_cond_signal (&table->prune_cond);
- break;
- }
- else
- next_wakeup = table->wakeup_time;
+ }
/* Mark the in-flight memory as unused. */
for (enum in_flight idx = 0; idx < IDX_last; ++idx)
@@ -265,7 +274,7 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
/* If we check for the modification of the underlying file we invalidate
the entries also in this case. */
- if (table->check_file && now != LONG_MAX)
+ if (table->inotify_descr < 0 && table->check_file && now != LONG_MAX)
{
struct stat64 st;
@@ -436,7 +445,8 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
ref_t *old = &table->head->array[first];
ref_t run = table->head->array[first];
- while (run != ENDREF)
+ assert (run != ENDREF);
+ do
{
struct hashentry *runp = (struct hashentry *) (data + run);
struct datahead *dh
@@ -462,6 +472,7 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
run = runp->next;
}
}
+ while (run != ENDREF);
}
++first;
diff --git a/libc/nscd/connections.c b/libc/nscd/connections.c
index 15148bdf3..0afc95a22 100644
--- a/libc/nscd/connections.c
+++ b/libc/nscd/connections.c
@@ -35,6 +35,9 @@
#ifdef HAVE_EPOLL
# include <sys/epoll.h>
#endif
+#ifdef HAVE_INOTIFY
+# include <sys/inotify.h>
+#endif
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/poll.h>
@@ -48,6 +51,7 @@
#include "nscd.h"
#include "dbg_log.h"
#include "selinux.h"
+#include <resolv/resolv.h>
#ifdef HAVE_SENDFILE
# include <kernel-features.h>
#endif
@@ -222,6 +226,14 @@ int max_nthreads = 32;
/* Socket for incoming connections. */
static int sock;
+#ifdef HAVE_INOTIFY
+/* Inotify descriptor. */
+static int inotify_fd = -1;
+
+/* Watch descriptor for resolver configuration file. */
+static int resolv_conf_descr = -1;
+#endif
+
/* Number of times clients had to wait. */
unsigned long int client_queued;
@@ -503,6 +515,13 @@ nscd_init (void)
/* No configuration for this value, assume a default. */
nthreads = 4;
+#ifdef HAVE_INOTIFY
+ /* Use inotify to recognize changed files. */
+ inotify_fd = inotify_init ();
+ if (inotify_fd != -1)
+ fcntl (inotify_fd, F_SETFL, O_NONBLOCK);
+#endif
+
for (size_t cnt = 0; cnt < lastdb; ++cnt)
if (dbs[cnt].enabled)
{
@@ -805,21 +824,39 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
assert (dbs[cnt].ro_fd == -1);
}
+ dbs[cnt].inotify_descr = -1;
if (dbs[cnt].check_file)
{
- /* We need the modification date of the file. */
- struct stat64 st;
-
- if (stat64 (dbs[cnt].filename, &st) < 0)
+#ifdef HAVE_INOTIFY
+ if (inotify_fd < 0
+ || (dbs[cnt].inotify_descr
+ = inotify_add_watch (inotify_fd, dbs[cnt].filename,
+ IN_DELETE_SELF | IN_MODIFY)) < 0)
+ /* We cannot notice changes in the main thread. */
+#endif
{
- /* We cannot stat() the file, disable file checking. */
- dbg_log (_("cannot stat() file `%s': %s"),
- dbs[cnt].filename, strerror (errno));
- dbs[cnt].check_file = 0;
+ /* We need the modification date of the file. */
+ struct stat64 st;
+
+ if (stat64 (dbs[cnt].filename, &st) < 0)
+ {
+ /* We cannot stat() the file, disable file checking. */
+ dbg_log (_("cannot stat() file `%s': %s"),
+ dbs[cnt].filename, strerror (errno));
+ dbs[cnt].check_file = 0;
+ }
+ else
+ dbs[cnt].file_mtime = st.st_mtime;
}
- else
- dbs[cnt].file_mtime = st.st_mtime;
}
+
+#ifdef HAVE_INOTIFY
+ if (cnt == hstdb && inotify_fd >= -1)
+ /* We also monitor the resolver configuration file. */
+ resolv_conf_descr = inotify_add_watch (inotify_fd,
+ _PATH_RESCONF,
+ IN_DELETE_SELF | IN_MODIFY);
+#endif
}
/* Create the socket. */
@@ -1330,11 +1367,14 @@ cannot change to old working directory: %s; disabling paranoia mode"),
}
/* Synchronize memory. */
+ int32_t certainly[lastdb];
for (int cnt = 0; cnt < lastdb; ++cnt)
if (dbs[cnt].enabled)
{
/* Make sure nobody keeps using the database. */
dbs[cnt].head->timestamp = 0;
+ certainly[cnt] = dbs[cnt].head->nscd_certainly_running;
+ dbs[cnt].head->nscd_certainly_running = 0;
if (dbs[cnt].persistent)
// XXX async OK?
@@ -1357,6 +1397,15 @@ cannot change to old working directory: %s; disabling paranoia mode"),
dbg_log (_("cannot change current working directory to \"/\": %s"),
strerror (errno));
paranoia = 0;
+
+ /* Reenable the databases. */
+ time_t now = time (NULL);
+ for (int cnt = 0; cnt < lastdb; ++cnt)
+ if (dbs[cnt].enabled)
+ {
+ dbs[cnt].head->timestamp = now;
+ dbs[cnt].head->nscd_certainly_running = certainly[cnt];
+ }
}
@@ -1394,42 +1443,75 @@ nscd_run_prune (void *p)
int dont_need_update = setup_thread (&dbs[my_number]);
+ time_t now = time (NULL);
+
/* We are running. */
- dbs[my_number].head->timestamp = time (NULL);
+ dbs[my_number].head->timestamp = now;
struct timespec prune_ts;
- if (clock_gettime (timeout_clock, &prune_ts) == -1)
+ if (__builtin_expect (clock_gettime (timeout_clock, &prune_ts) == -1, 0))
/* Should never happen. */
abort ();
/* Compute the initial timeout time. Prevent all the timers to go
off at the same time by adding a db-based value. */
prune_ts.tv_sec += CACHE_PRUNE_INTERVAL + my_number;
+ dbs[my_number].wakeup_time = now + CACHE_PRUNE_INTERVAL + my_number;
- pthread_mutex_lock (&dbs[my_number].prune_lock);
+ pthread_mutex_t *prune_lock = &dbs[my_number].prune_lock;
+ pthread_cond_t *prune_cond = &dbs[my_number].prune_cond;
+
+ pthread_mutex_lock (prune_lock);
while (1)
{
/* Wait, but not forever. */
- int e = pthread_cond_timedwait (&dbs[my_number].prune_cond,
- &dbs[my_number].prune_lock,
- &prune_ts);
- assert (e == 0 || e == ETIMEDOUT);
+ int e = 0;
+ if (! dbs[my_number].clear_cache)
+ e = pthread_cond_timedwait (prune_cond, prune_lock, &prune_ts);
+ assert (__builtin_expect (e == 0 || e == ETIMEDOUT, 1));
time_t next_wait;
- time_t now = time (NULL);
- if (e == ETIMEDOUT || now >= dbs[my_number].wakeup_time)
+ now = time (NULL);
+ if (e == ETIMEDOUT || now >= dbs[my_number].wakeup_time
+ || dbs[my_number].clear_cache)
{
- next_wait = prune_cache (&dbs[my_number], now, -1);
+ /* We will determine the new timout values based on the
+ cache content. Should there be concurrent additions to
+ the cache which are not accounted for in the cache
+ pruning we want to know about it. Therefore set the
+ timeout to the maximum. It will be descreased when adding
+ new entries to the cache, if necessary. */
+ if (sizeof (time_t) == sizeof (long int))
+ dbs[my_number].wakeup_time = LONG_MAX;
+ else
+ dbs[my_number].wakeup_time = INT_MAX;
+
+ /* Unconditionally reset the flag. */
+ time_t prune_now = dbs[my_number].clear_cache ? LONG_MAX : now;
+ dbs[my_number].clear_cache = 0;
+
+ pthread_mutex_unlock (prune_lock);
+
+ next_wait = prune_cache (&dbs[my_number], prune_now, -1);
+
next_wait = MAX (next_wait, CACHE_PRUNE_INTERVAL);
/* If clients cannot determine for sure whether nscd is running
we need to wake up occasionally to update the timestamp.
Wait 90% of the update period. */
#define UPDATE_MAPPING_TIMEOUT (MAPPING_TIMEOUT * 9 / 10)
if (__builtin_expect (! dont_need_update, 0))
- next_wait = MIN (UPDATE_MAPPING_TIMEOUT, next_wait);
+ {
+ next_wait = MIN (UPDATE_MAPPING_TIMEOUT, next_wait);
+ dbs[my_number].head->timestamp = now;
+ }
+
+ pthread_mutex_lock (prune_lock);
/* Make it known when we will wake up again. */
- dbs[my_number].wakeup_time = now + next_wait;
+ if (now + next_wait < dbs[my_number].wakeup_time)
+ dbs[my_number].wakeup_time = now + next_wait;
+ else
+ next_wait = dbs[my_number].wakeup_time - now;
}
else
/* The cache was just pruned. Do not do it again now. Just
@@ -1665,6 +1747,16 @@ main_loop_poll (void)
size_t nused = 1;
size_t firstfree = 1;
+#ifdef HAVE_INOTIFY
+ if (inotify_fd != -1)
+ {
+ conns[1].fd = inotify_fd;
+ conns[1].events = POLLRDNORM;
+ nused = 2;
+ firstfree = 2;
+ }
+#endif
+
while (1)
{
/* Wait for any event. We wait at most a couple of seconds so
@@ -1712,7 +1804,52 @@ main_loop_poll (void)
--n;
}
- for (size_t cnt = 1; cnt < nused && n > 0; ++cnt)
+ size_t first = 1;
+#ifdef HAVE_INOTIFY
+ if (conns[1].fd == inotify_fd)
+ {
+ if (conns[1].revents != 0)
+ {
+ bool done[lastdb] = { false, };
+ union
+ {
+ struct inotify_event i;
+ char buf[100];
+ } inev;
+
+ while (TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
+ sizeof (inev)))
+ >= (ssize_t) sizeof (struct inotify_event))
+ {
+ /* Check which of the files changed. */
+ for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
+ if (!done[dbcnt]
+ && (inev.i.wd == dbs[dbcnt].inotify_descr
+ || (dbcnt == hstdb
+ && inev.i.wd == resolv_conf_descr)))
+ {
+ if (dbcnt == hstdb
+ && inev.i.wd == resolv_conf_descr)
+ res_init ();
+
+ pthread_mutex_lock (&dbs[dbcnt].prune_lock);
+ dbs[dbcnt].clear_cache = 1;
+ pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
+ pthread_cond_signal (&dbs[dbcnt].prune_cond);
+
+ done[dbcnt] = true;
+ break;
+ }
+ }
+
+ --n;
+ }
+
+ first = 2;
+ }
+#endif
+
+ for (size_t cnt = first; cnt < nused && n > 0; ++cnt)
if (conns[cnt].revents != 0)
{
fd_ready (conns[cnt].fd);
@@ -1778,6 +1915,18 @@ main_loop_epoll (int efd)
/* We cannot use epoll. */
return;
+#ifdef HAVE_INOTIFY
+ if (inotify_fd != -1)
+ {
+ ev.events = EPOLLRDNORM;
+ ev.data.fd = inotify_fd;
+ if (epoll_ctl (efd, EPOLL_CTL_ADD, inotify_fd, &ev) == -1)
+ /* We cannot use epoll. */
+ return;
+ nused = 2;
+ }
+#endif
+
while (1)
{
struct epoll_event revs[100];
@@ -1814,6 +1963,32 @@ main_loop_epoll (int efd)
}
}
}
+#ifdef HAVE_INOTIFY
+ else if (revs[cnt].data.fd == inotify_fd)
+ {
+ union
+ {
+ struct inotify_event i;
+ char buf[100];
+ } inev;
+
+ while (TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
+ sizeof (inev)))
+ >= (ssize_t) sizeof (struct inotify_event))
+ {
+ /* Check which of the files changed. */
+ for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
+ if (inev.i.wd == dbs[dbcnt].inotify_descr)
+ {
+ pthread_mutex_trylock (&dbs[dbcnt].prune_lock);
+ dbs[dbcnt].clear_cache = 1;
+ pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
+ pthread_cond_signal (&dbs[dbcnt].prune_cond);
+ break;
+ }
+ }
+ }
+#endif
else
{
/* Remove the descriptor from the epoll descriptor. */
diff --git a/libc/nscd/grpcache.c b/libc/nscd/grpcache.c
index 9921ae313..c49c0e190 100644
--- a/libc/nscd/grpcache.c
+++ b/libc/nscd/grpcache.c
@@ -147,7 +147,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, &dataset->strdata, req->key_len,
- &dataset->head, true, db, owner);
+ &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock);
@@ -190,7 +190,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
gr_mem_len_total += gr_mem_len[gr_mem_cnt];
}
- written = total = (sizeof (struct dataset)
+ written = total = (offsetof (struct dataset, strdata)
+ gr_mem_cnt * sizeof (uint32_t)
+ gr_name_len + gr_passwd_len + gr_mem_len_total);
@@ -252,6 +252,9 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
char *key_copy = cp + key_offset;
assert (key_copy == (char *) rawmemchr (cp, '\0') + 1);
+ assert (cp == dataset->strdata + total - offsetof (struct dataset,
+ strdata));
+
/* Now we can determine whether on refill we have to create a new
record or not. */
if (he != NULL)
@@ -353,7 +356,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
if (req->type == GETGRBYGID)
{
if (cache_add (GETGRBYGID, cp, key_offset, &dataset->head, true,
- db, owner) < 0)
+ db, owner, he == NULL) < 0)
goto out;
first = false;
@@ -362,7 +365,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
else if (strcmp (key_copy, gr_name) != 0)
{
if (cache_add (GETGRBYNAME, key_copy, key_len + 1,
- &dataset->head, true, db, owner) < 0)
+ &dataset->head, true, db, owner, he == NULL) < 0)
goto out;
first = false;
@@ -372,12 +375,13 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
if ((req->type == GETGRBYNAME || db->propagate)
&& __builtin_expect (cache_add (GETGRBYNAME, gr_name,
gr_name_len,
- &dataset->head, first, db, owner)
+ &dataset->head, first, db, owner,
+ he == NULL)
== 0, 1))
{
if (req->type == GETGRBYNAME && db->propagate)
(void) cache_add (GETGRBYGID, cp, key_offset, &dataset->head,
- false, db, owner);
+ false, db, owner, false);
}
out:
diff --git a/libc/nscd/hstcache.c b/libc/nscd/hstcache.c
index 3ceb6715c..4333917ba 100644
--- a/libc/nscd/hstcache.c
+++ b/libc/nscd/hstcache.c
@@ -83,8 +83,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
struct hashentry *he, struct datahead *dh, int errval,
int32_t ttl)
{
- ssize_t total;
- ssize_t written;
+ bool all_written = true;
time_t t = time (NULL);
/* We allocate all data in one memory block: the iov vector,
@@ -108,18 +107,17 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
if (reload_count != UINT_MAX)
/* Do not reset the value if we never not reload the record. */
dh->nreloads = reload_count - 1;
-
- written = total = 0;
}
else
{
/* We have no data. This means we send the standard reply for this
case. */
- written = total = sizeof (notfound);
+ ssize_t total = sizeof (notfound);
- if (fd != -1)
- written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
- MSG_NOSIGNAL));
+ if (fd != -1 &&
+ TEMP_FAILURE_RETRY (send (fd, &notfound, total,
+ MSG_NOSIGNAL)) != total)
+ all_written = false;
dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
IDX_result_data);
@@ -156,7 +154,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, &dataset->strdata, req->key_len,
- &dataset->head, true, db, owner);
+ &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock);
@@ -181,6 +179,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
char *key_copy = NULL;
char *cp;
size_t cnt;
+ ssize_t total;
/* Determine the number of aliases. */
h_aliases_cnt = 0;
@@ -208,7 +207,6 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
+ h_name_len
+ h_aliases_cnt * sizeof (uint32_t)
+ h_addr_list_cnt * hst->h_length);
- written = total;
/* If we refill the cache, first assume the reconrd did not
change. Allocate memory on the cache since it is likely
@@ -260,6 +258,9 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
dataset->resp.h_addr_list_cnt = h_addr_list_cnt;
dataset->resp.error = NETDB_SUCCESS;
+ /* Make sure there is no gap. */
+ assert ((char *) (&dataset->resp.error + 1) == dataset->strdata);
+
cp = dataset->strdata;
cp = mempcpy (cp, hst->h_name, h_name_len);
@@ -286,6 +287,8 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
we explicitly add the name here. */
key_copy = memcpy (cp, key, req->key_len);
+ assert ((char *) &dataset->resp + dataset->head.recsize == cp);
+
/* Now we can determine whether on refill we have to create a new
record or not. */
if (he != NULL)
@@ -351,20 +354,27 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
<= (sizeof (struct database_pers_head)
+ db->head->module * sizeof (ref_t)
+ db->head->data_size));
- written = sendfileall (fd, db->wr_fd,
- (char *) &dataset->resp
- - (char *) db->head, total);
+ ssize_t written = sendfileall (fd, db->wr_fd,
+ (char *) &dataset->resp
+ - (char *) db->head,
+ dataset->head.recsize);
+ if (written != dataset->head.recsize)
+ {
# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
+ if (written == -1 && errno == ENOSYS)
+ goto use_write;
# endif
+ all_written = false;
+ }
}
else
# ifndef __ASSUME_SENDFILE
use_write:
# endif
#endif
- written = writeall (fd, &dataset->resp, total);
+ if (writeall (fd, &dataset->resp, dataset->head.recsize)
+ != dataset->head.recsize)
+ all_written = false;
}
/* Add the record to the database. But only if it has not been
@@ -408,13 +418,13 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
|| req->type == GETHOSTBYADDRv6);
(void) cache_add (req->type, key_copy, req->key_len,
- &dataset->head, true, db, owner);
+ &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock);
}
}
- if (__builtin_expect (written != total, 0) && debug_level > 0)
+ if (__builtin_expect (!all_written, 0) && debug_level > 0)
{
char buf[256];
dbg_log (_("short write in %s: %s"), __FUNCTION__,
diff --git a/libc/nscd/initgrcache.c b/libc/nscd/initgrcache.c
index 94e909d4a..c5693c6be 100644
--- a/libc/nscd/initgrcache.c
+++ b/libc/nscd/initgrcache.c
@@ -231,7 +231,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, key_copy, req->key_len,
- &dataset->head, true, db, uid);
+ &dataset->head, true, db, uid, he == NULL);
pthread_rwlock_unlock (&db->lock);
@@ -246,7 +246,8 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
else
{
- written = total = sizeof (struct dataset) + start * sizeof (int32_t);
+ written = total = (offsetof (struct dataset, strdata)
+ + start * sizeof (int32_t));
/* If we refill the cache, first assume the reconrd did not
change. Allocate memory on the cache since it is likely
@@ -307,6 +308,9 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
/* Finally the user name. */
memcpy (cp, key, req->key_len);
+ assert (cp == dataset->strdata + total - offsetof (struct dataset,
+ strdata));
+
/* Now we can determine whether on refill we have to create a new
record or not. */
if (he != NULL)
@@ -398,7 +402,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock);
(void) cache_add (INITGROUPS, cp, req->key_len, &dataset->head, true,
- db, uid);
+ db, uid, he == NULL);
pthread_rwlock_unlock (&db->lock);
}
diff --git a/libc/nscd/mem.c b/libc/nscd/mem.c
index 14928d633..e821729da 100644
--- a/libc/nscd/mem.c
+++ b/libc/nscd/mem.c
@@ -24,6 +24,7 @@
#include <inttypes.h>
#include <libintl.h>
#include <limits.h>
+#include <obstack.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -79,6 +80,7 @@ static void
markrange (BITMAP_T *mark, ref_t start, size_t len)
{
/* Adjust parameters for block alignment. */
+ assert ((start & BLOCK_ALIGN_M1) == 0);
start /= BLOCK_ALIGN;
len = (len + BLOCK_ALIGN_M1) / BLOCK_ALIGN;
@@ -93,7 +95,7 @@ markrange (BITMAP_T *mark, ref_t start, size_t len)
return;
}
- mark[elem++] |= 0xff << (start % BITS);
+ mark[elem++] |= ALLBITS << (start % BITS);
len -= BITS - (start % BITS);
}
@@ -130,14 +132,14 @@ gc (struct database_dyn *db)
size_t stack_used = sizeof (bool) * db->head->module;
if (__builtin_expect (stack_used > MAX_STACK_USE, 0))
stack_used = 0;
- size_t memory_needed = ((db->head->first_free / BLOCK_ALIGN + BITS - 1)
- / BITS) * sizeof (BITMAP_T);
- if (memory_needed <= MAX_STACK_USE)
+ size_t nmark = (db->head->first_free / BLOCK_ALIGN + BITS - 1) / BITS;
+ size_t memory_needed = nmark * sizeof (BITMAP_T);
+ if (stack_used + memory_needed <= MAX_STACK_USE)
{
mark = (BITMAP_T *) alloca (memory_needed);
mark_use_malloc = false;
memset (mark, '\0', memory_needed);
- stack_used = memory_needed;
+ stack_used += memory_needed;
}
else
{
@@ -156,6 +158,7 @@ gc (struct database_dyn *db)
he = alloca (db->head->nentries * sizeof (struct hashentry *));
he_data = alloca (db->head->nentries * sizeof (struct hashentry *));
he_use_malloc = false;
+ stack_used += memory_needed;
}
else
{
@@ -212,11 +215,12 @@ gc (struct database_dyn *db)
for (enum in_flight idx = IDX_result_data;
idx < IDX_last && mrunp->block[idx].dbidx == db - dbs; ++idx)
{
- assert ((char *) mrunp->block[idx].blockaddr > db->data);
- assert ((char *) mrunp->block[idx].blockaddr
- + mrunp->block[0].blocklen <= db->data + db->memsize);
- markrange (mark, (char *) mrunp->block[idx].blockaddr - db->data,
- mrunp->block[idx].blocklen);
+ assert (mrunp->block[idx].blockoff >= 0);
+ assert (mrunp->block[idx].blocklen < db->memsize);
+ assert (mrunp->block[idx].blockoff
+ + mrunp->block[0].blocklen <= db->memsize);
+ markrange (mark, mrunp->block[idx].blockoff,
+ mrunp->block[idx].blocklen);
}
mrunp = mrunp->next;
@@ -231,8 +235,13 @@ gc (struct database_dyn *db)
/* Sort the entries by their address. */
qsort (he, cnt, sizeof (struct hashentry *), sort_he);
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+ struct obstack ob;
+ obstack_init (&ob);
+
/* Determine the highest used address. */
- size_t high = sizeof (mark);
+ size_t high = nmark;
while (high > 0 && mark[high - 1] == 0)
--high;
@@ -363,8 +372,14 @@ gc (struct database_dyn *db)
displacement. */
ref_t disp = off_alloc - off_free;
- struct moveinfo *new_move
- = (struct moveinfo *) alloca (sizeof (*new_move));
+ struct moveinfo *new_move;
+ if (stack_used + sizeof (*new_move) <= MAX_STACK_USE)
+ {
+ new_move = alloca (sizeof (*new_move));
+ stack_used += sizeof (*new_move);
+ }
+ else
+ new_move = obstack_alloc (&ob, sizeof (*new_move));
new_move->from = db->data + off_alloc;
new_move->to = db->data + off_free;
new_move->size = off_allocend - off_alloc;
@@ -524,6 +539,8 @@ gc (struct database_dyn *db)
free (he);
if (mark_use_malloc)
free (mark);
+
+ obstack_free (&ob, NULL);
}
@@ -589,15 +606,16 @@ mempool_alloc (struct database_dyn *db, size_t len, enum in_flight idx)
}
else
{
- db->head->first_free += len;
-
- db->last_alloc_failed = false;
-
/* Remember that we have allocated this memory. */
assert (idx >= 0 && idx < IDX_last);
mem_in_flight.block[idx].dbidx = db - dbs;
mem_in_flight.block[idx].blocklen = len;
- mem_in_flight.block[idx].blockaddr = res;
+ mem_in_flight.block[idx].blockoff = db->head->first_free;
+
+ db->head->first_free += len;
+
+ db->last_alloc_failed = false;
+
}
pthread_mutex_unlock (&db->memlock);
diff --git a/libc/nscd/nscd.h b/libc/nscd/nscd.h
index 66813e748..5c77dd3c4 100644
--- a/libc/nscd/nscd.h
+++ b/libc/nscd/nscd.h
@@ -73,6 +73,8 @@ struct database_dyn
int enabled;
int check_file;
+ int inotify_descr;
+ int clear_cache;
int persistent;
int shared;
int propagate;
@@ -197,7 +199,7 @@ extern __thread struct mem_in_flight
{
int dbidx;
nscd_ssize_t blocklen;
- void *blockaddr;
+ nscd_ssize_t blockoff;
} block[IDX_last];
struct mem_in_flight *next;
@@ -231,7 +233,8 @@ extern struct datahead *cache_search (request_type, void *key, size_t len,
uid_t owner);
extern int cache_add (int type, const void *key, size_t len,
struct datahead *packet, bool first,
- struct database_dyn *table, uid_t owner);
+ struct database_dyn *table, uid_t owner,
+ bool prune_wakeup);
extern time_t prune_cache (struct database_dyn *table, time_t now, int fd);
/* pwdcache.c */
diff --git a/libc/nscd/nscd_getserv_r.c b/libc/nscd/nscd_getserv_r.c
index 3cd5a2429..b1ad7e2e4 100644
--- a/libc/nscd/nscd_getserv_r.c
+++ b/libc/nscd/nscd_getserv_r.c
@@ -53,7 +53,7 @@ __nscd_getservbyport_r (int port, const char *proto,
portstr[sizeof (portstr) - 1] = '\0';
char *cp = _itoa_word (port, portstr + sizeof (portstr) - 1, 10, 0);
- return nscd_getserv_r (portstr, portstr + sizeof (portstr) - cp, proto,
+ return nscd_getserv_r (cp, portstr + sizeof (portstr) - cp, proto,
GETSERVBYPORT, result_buf, buf, buflen, result);
}
diff --git a/libc/nscd/pwdcache.c b/libc/nscd/pwdcache.c
index 2d0a26592..782b10137 100644
--- a/libc/nscd/pwdcache.c
+++ b/libc/nscd/pwdcache.c
@@ -154,7 +154,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, key_copy, req->key_len,
- &dataset->head, true, db, owner);
+ &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock);
@@ -185,7 +185,8 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
n = snprintf (buf, buf_len, "%d%c%n%s", pwd->pw_uid, '\0',
&key_offset, (char *) key) + 1;
- written = total = (sizeof (struct dataset) + pw_name_len + pw_passwd_len
+ written = total = (offsetof (struct dataset, strdata)
+ + pw_name_len + pw_passwd_len
+ pw_gecos_len + pw_dir_len + pw_shell_len);
/* If we refill the cache, first assume the reconrd did not
@@ -247,16 +248,28 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
char *key_copy = cp + key_offset;
assert (key_copy == (char *) rawmemchr (cp, '\0') + 1);
+ assert (cp == dataset->strdata + total - offsetof (struct dataset,
+ strdata));
+
/* Now we can determine whether on refill we have to create a new
record or not. */
if (he != NULL)
{
assert (fd == -1);
- if (total + n == dh->allocsize
- && total - offsetof (struct dataset, resp) == dh->recsize
+#if 0
+ if (dataset->head.datasize == dh->allocsize
+ && dataset->head.recsize == dh->recsize
&& memcmp (&dataset->resp, dh->data,
dh->allocsize - offsetof (struct dataset, resp)) == 0)
+#else
+ if (dataset->head.allocsize != dh->allocsize)
+ goto nnn;
+ if (dataset->head.recsize != dh->recsize)
+ goto nnn;
+ if(memcmp (&dataset->resp, dh->data,
+ dh->allocsize - offsetof (struct dataset, resp)) == 0)
+#endif
{
/* The data has not changed. We will just bump the
timeout value. Note that the new record has been
@@ -266,6 +279,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
}
else
{
+ nnn:;
/* We have to create a new record. Just allocate
appropriate memory and copy it. */
struct dataset *newp
@@ -348,7 +362,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
if (req->type == GETPWBYUID)
{
if (cache_add (GETPWBYUID, cp, key_offset, &dataset->head, true,
- db, owner) < 0)
+ db, owner, he == NULL) < 0)
goto out;
first = false;
@@ -357,7 +371,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
else if (strcmp (key_copy, dataset->strdata) != 0)
{
if (cache_add (GETPWBYNAME, key_copy, key_len + 1,
- &dataset->head, true, db, owner) < 0)
+ &dataset->head, true, db, owner, he == NULL) < 0)
goto out;
first = false;
@@ -367,11 +381,12 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
if ((req->type == GETPWBYNAME || db->propagate)
&& __builtin_expect (cache_add (GETPWBYNAME, dataset->strdata,
pw_name_len, &dataset->head,
- first, db, owner) == 0, 1))
+ first, db, owner, he == NULL)
+ == 0, 1))
{
if (req->type == GETPWBYNAME && db->propagate)
(void) cache_add (GETPWBYUID, cp, key_offset, &dataset->head,
- false, db, owner);
+ false, db, owner, false);
}
out:
diff --git a/libc/nscd/servicescache.c b/libc/nscd/servicescache.c
index c6f0b47e3..44f12a3c6 100644
--- a/libc/nscd/servicescache.c
+++ b/libc/nscd/servicescache.c
@@ -137,7 +137,7 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, &dataset->strdata, req->key_len,
- &dataset->head, true, db, owner);
+ &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock);
@@ -173,7 +173,7 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
total += s_aliases_len[cnt];
}
- total += (sizeof (struct dataset)
+ total += (offsetof (struct dataset, strdata)
+ s_name_len
+ s_proto_len
+ s_aliases_cnt * sizeof (uint32_t));
@@ -331,7 +331,7 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, key_copy, req->key_len,
- &dataset->head, true, db, owner);
+ &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock);
}
diff --git a/libc/posix/glob.c b/libc/posix/glob.c
index 464859a75..ae1b6f6e0 100644
--- a/libc/posix/glob.c
+++ b/libc/posix/glob.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007
+/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -1080,8 +1080,7 @@ globfree (pglob)
{
size_t i;
for (i = 0; i < pglob->gl_pathc; ++i)
- if (pglob->gl_pathv[pglob->gl_offs + i] != NULL)
- free (pglob->gl_pathv[pglob->gl_offs + i]);
+ free (pglob->gl_pathv[pglob->gl_offs + i]);
free (pglob->gl_pathv);
pglob->gl_pathv = NULL;
}
diff --git a/libc/resolv/arpa/nameser_compat.h b/libc/resolv/arpa/nameser_compat.h
index 43bcd3aff..8bc6e913d 100644
--- a/libc/resolv/arpa/nameser_compat.h
+++ b/libc/resolv/arpa/nameser_compat.h
@@ -1,6 +1,6 @@
/* Copyright (c) 1983, 1989
* The Regents of the University of California. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -161,6 +161,7 @@ typedef struct {
#define T_SRV ns_t_srv
#define T_ATMA ns_t_atma
#define T_NAPTR ns_t_naptr
+#define T_DNAME ns_t_dname
#define T_TSIG ns_t_tsig
#define T_IXFR ns_t_ixfr
#define T_AXFR ns_t_axfr
diff --git a/libc/resolv/nss_dns/dns-host.c b/libc/resolv/nss_dns/dns-host.c
index c52f9f7f8..cae077445 100644
--- a/libc/resolv/nss_dns/dns-host.c
+++ b/libc/resolv/nss_dns/dns-host.c
@@ -990,6 +990,9 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
char *h_name = NULL;
int h_namelen = 0;
+ if (ancount == 0)
+ return NSS_STATUS_NOTFOUND;
+
while (ancount-- > 0 && cp < end_of_message && had_error == 0)
{
n = __ns_name_unpack (answer->buf, end_of_message, cp,
@@ -1069,12 +1072,13 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
if (__builtin_expect (type == T_SIG, 0)
|| __builtin_expect (type == T_KEY, 0)
|| __builtin_expect (type == T_NXT, 0)
- || __builtin_expect (type == T_PTR, 0))
+ || __builtin_expect (type == T_PTR, 0)
+ || __builtin_expect (type == T_DNAME, 0))
{
/* We don't support DNSSEC yet. For now, ignore the record
and send a low priority message to syslog.
- We also don't expect T_PTR messages. */
+ We also don't expect T_PTR or T_DNAME messages. */
syslog (LOG_DEBUG | LOG_AUTH,
"getaddrinfo*.gaih_getanswer: got type \"%s\"",
p_type (type));
@@ -1093,11 +1097,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
if (__builtin_expect (buflen < sizeof (struct gaih_addrtuple),
0))
- {
- *errnop = ERANGE;
- *h_errnop = NETDB_INTERNAL;
- return NSS_STATUS_TRYAGAIN;
- }
+ goto too_small;
*pat = (struct gaih_addrtuple *) buffer;
buffer += sizeof (struct gaih_addrtuple);
@@ -1164,15 +1164,24 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
{
int first = 1;
- enum nss_status status = gaih_getanswer_slice(answer1, anslen1, qname,
- &pat, &buffer, &buflen,
- errnop, h_errnop, ttlp,
- &first);
- if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND)
- && answer2 != NULL)
- status = gaih_getanswer_slice(answer2, anslen2, qname,
+ enum nss_status status = NSS_STATUS_NOTFOUND;
+
+ if (anslen1 > 0)
+ status = gaih_getanswer_slice(answer1, anslen1, qname,
&pat, &buffer, &buflen,
- errnop, h_errnop, ttlp, &first);
+ errnop, h_errnop, ttlp,
+ &first);
+ if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
+ || status == NSS_STATUS_TRYAGAIN)
+ && answer2 != NULL && anslen2 > 0)
+ {
+ enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname,
+ &pat, &buffer, &buflen,
+ errnop, h_errnop, ttlp,
+ &first);
+ if (status != NSS_STATUS_SUCCESS)
+ status = status2;
+ }
return status;
}
diff --git a/libc/resolv/res_query.c b/libc/resolv/res_query.c
index a8e8d7b73..3d2f2fe3a 100644
--- a/libc/resolv/res_query.c
+++ b/libc/resolv/res_query.c
@@ -224,6 +224,21 @@ __libc_res_nquery(res_state statp,
tests of HP2. */
HEADER *hp2 = answerp2 ? (HEADER *) *answerp2 : hp;
+ if (n < sizeof (HEADER) && nanswerp2 != NULL
+ && *nanswerp2 > sizeof (HEADER))
+ {
+ /* Special case of partial answer. */
+ assert (hp != hp2);
+ hp = hp2;
+ }
+ else if (nanswerp2 != NULL
+ && *nanswerp2 < sizeof (HEADER) && n > sizeof (HEADER))
+ {
+ /* Special case of partial answer. */
+ assert (hp != hp2);
+ hp2 = hp;
+ }
+
if ((hp->rcode != NOERROR || ntohs(hp->ancount) == 0)
&& (hp2->rcode != NOERROR || ntohs(hp2->ancount) == 0)) {
#ifdef DEBUG
diff --git a/libc/resolv/res_send.c b/libc/resolv/res_send.c
index b3dbd702a..e78ff967a 100644
--- a/libc/resolv/res_send.c
+++ b/libc/resolv/res_send.c
@@ -975,6 +975,8 @@ send_dg(res_state statp,
int recvresp2 = buf2 == NULL;
pfd[0].fd = EXT(statp).nssocks[ns];
pfd[0].events = POLLOUT;
+ if (resplen2 != NULL)
+ *resplen2 = 0;
wait:
if (need_recompute) {
recompute_resend:
@@ -999,8 +1001,13 @@ send_dg(res_state statp,
need_recompute = 1;
}
if (n == 0) {
- Dprint(statp->options & RES_DEBUG, (stdout,
- ";; timeout sending\n"));
+ Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
+ if (recvresp1 || (buf2 != NULL && recvresp2))
+ {
+ *resplen2 = 1;
+ return resplen;
+ }
+
*gotsomewhere = 1;
return (0);
}
@@ -1177,6 +1184,24 @@ send_dg(res_state statp,
thisansp,
(*thisresplen > *thisanssiz)
? *thisanssiz : *thisresplen);
+
+ if (recvresp1 || (buf2 != NULL && recvresp2))
+ {
+ *resplen2 = 1;
+ return resplen;
+ }
+ if (buf2 != NULL)
+ {
+ /* We are waiting for a possible second reply. */
+ resplen = 1;
+ if (hp->id == anhp->id)
+ recvresp1 = 1;
+ else
+ recvresp2 = 1;
+
+ goto wait;
+ }
+
next_ns:
__res_iclose(statp, false);
/* don't retry if called from dig */
diff --git a/libc/scripts/data/localplt-sparc-linux-gnu.data b/libc/scripts/data/localplt-sparc-linux-gnu.data
new file mode 100644
index 000000000..5ceed16c9
--- /dev/null
+++ b/libc/scripts/data/localplt-sparc-linux-gnu.data
@@ -0,0 +1,18 @@
+libc.so: _Q_add
+libc.so: _Q_div
+libc.so: _Q_feq
+libc.so: _Q_fge
+libc.so: _Q_fle
+libc.so: _Q_flt
+libc.so: _Q_fne
+libc.so: _Q_itoq
+libc.so: _Q_mul
+libc.so: _Q_sub
+libc.so: _Unwind_Find_FDE
+libc.so: calloc
+libc.so: ffs
+libc.so: free
+libc.so: malloc
+libc.so: memalign
+libc.so: realloc
+libm.so: matherr
diff --git a/libc/scripts/data/localplt-sparc64-linux-gnu.data b/libc/scripts/data/localplt-sparc64-linux-gnu.data
new file mode 100644
index 000000000..5e6e42d67
--- /dev/null
+++ b/libc/scripts/data/localplt-sparc64-linux-gnu.data
@@ -0,0 +1,20 @@
+libc.so: _Qp_add
+libc.so: _Qp_div
+libc.so: _Qp_feq
+libc.so: _Qp_fge
+libc.so: _Qp_fle
+libc.so: _Qp_flt
+libc.so: _Qp_fne
+libc.so: _Qp_itoq
+libc.so: _Qp_mul
+libc.so: _Qp_qtod
+libc.so: _Qp_sub
+libc.so: _Qp_xtoq
+libc.so: _Unwind_Find_FDE
+libc.so: calloc
+libc.so: ffs
+libc.so: free
+libc.so: malloc
+libc.so: memalign
+libc.so: realloc
+libm.so: matherr
diff --git a/libc/scripts/soversions.awk b/libc/scripts/soversions.awk
index 32ce076ba..55577ccc7 100644
--- a/libc/scripts/soversions.awk
+++ b/libc/scripts/soversions.awk
@@ -18,6 +18,16 @@ $2 ~ /WORDSIZE[3264]/ {
next;
}
+$2 == "ABI" {
+ if ((config ~ thiscf) && !abiname) {
+ abiname = $3;
+ sub(/@CPU@/, cpu, abiname);
+ sub(/@VENDOR@/, vendor, abiname);
+ sub(/@OS@/, os, abiname);
+ }
+ next;
+}
+
# Obey the first matching DEFAULT line.
$2 == "DEFAULT" {
$1 = $2 = "";
@@ -66,6 +76,9 @@ END {
}
}
}
+ if (abiname) {
+ print "ABI", abiname
+ }
for (c in lines) {
print lines[c]
}
diff --git a/libc/shlib-versions b/libc/shlib-versions
index 9a10fc056..65e772bbb 100644
--- a/libc/shlib-versions
+++ b/libc/shlib-versions
@@ -43,6 +43,11 @@ powerpc.*-.*-.* WORDSIZE64 powerpc64-@VENDOR@-@OS@
sparc64.*-.*-.* WORDSIZE32 sparc-@VENDOR@-@OS@
sparc.*-.*-.* WORDSIZE64 sparc64-@VENDOR@-@OS@
+# Configuration ABI Identifier for ABI data files
+# ------------- ---------- -----------------------------
+sparc64.*-.*-.* ABI sparc64-@OS@
+sparc.*-.*-.* ABI sparc-@OS@
+
# Configuration Library=version Earliest symbol set (optional)
# ------------- --------------- ------------------------------
diff --git a/libc/stdio-common/Makefile b/libc/stdio-common/Makefile
index d4525c33f..252ca1d34 100644
--- a/libc/stdio-common/Makefile
+++ b/libc/stdio-common/Makefile
@@ -65,7 +65,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
tst-sprintf tst-rndseek tst-fdopen tst-fphex \
tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
tst-fwrite bug16 bug17 tst-sprintf2 bug18 \
- bug19 tst-popen2 scanf14 scanf15 bug21 bug22
+ bug19 tst-popen2 scanf14 scanf15 bug21 bug22 scanf16 scanf17
tests-$(OPTION_EGLIBC_LOCALE_CODE) \
+= tst-sscanf tst-swprintf bug15 test-vfprintf bug14 scanf13
tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
@@ -123,11 +123,13 @@ CFLAGS-isoc99_scanf.c += $(exceptions)
CFLAGS-errlist.c = $(fno-unit-at-a-time)
CFLAGS-siglist.c = $(fno-unit-at-a-time)
-# The following is a hack since we must compile scanf15.c without any
+# The following is a hack since we must compile scanf1{5,7}.c without any
# GNU extension. The latter are needed, though, when internal headers
# are used. So made sure we see the installed headers first.
CFLAGS-scanf15.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \
-I../wctype
+CFLAGS-scanf17.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \
+ -I../wctype
# We know the test has a format string problem.
CFLAGS-tst-sprintf.c = -Wno-format
diff --git a/libc/stdio-common/scanf14.c b/libc/stdio-common/scanf14.c
index b31505c0d..575b849b6 100644
--- a/libc/stdio-common/scanf14.c
+++ b/libc/stdio-common/scanf14.c
@@ -62,5 +62,58 @@ main (void)
else if (d != 5.25 || memcmp (c, " x", 2) != 0)
FAIL ();
+ const char *tmpdir = getenv ("TMPDIR");
+ if (tmpdir == NULL || tmpdir[0] == '\0')
+ tmpdir = "/tmp";
+
+ char fname[strlen (tmpdir) + sizeof "/tst-scanf14.XXXXXX"];
+ sprintf (fname, "%s/tst-scanf14.XXXXXX", tmpdir);
+ if (fname == NULL)
+ FAIL ();
+
+ /* Create a temporary file. */
+ int fd = mkstemp (fname);
+ if (fd == -1)
+ FAIL ();
+
+ FILE *fp = fdopen (fd, "w+");
+ if (fp == NULL)
+ FAIL ();
+ else
+ {
+ if (fputs (" 1.25s x", fp) == EOF)
+ FAIL ();
+ if (fseek (fp, 0, SEEK_SET) != 0)
+ FAIL ();
+ if (fscanf (fp, "%as%2c", &sp, c) != 2)
+ FAIL ();
+ else
+ {
+ if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ memset (sp, 'x', sizeof "1.25s");
+ free (sp);
+ }
+
+ if (freopen (fname, "r", stdin) == NULL)
+ FAIL ();
+ else
+ {
+ if (scanf ("%as%2c", &sp, c) != 2)
+ FAIL ();
+ else
+ {
+ if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ memset (sp, 'x', sizeof "1.25s");
+ free (sp);
+ }
+ }
+
+ fclose (fp);
+ }
+
+ remove (fname);
+
return result;
}
diff --git a/libc/stdio-common/scanf15.c b/libc/stdio-common/scanf15.c
index cc8aa2e6a..c56715c48 100644
--- a/libc/stdio-common/scanf15.c
+++ b/libc/stdio-common/scanf15.c
@@ -50,5 +50,48 @@ main (void)
else if (d != 5.25 || memcmp (c, " x", 2) != 0)
FAIL ();
+ const char *tmpdir = getenv ("TMPDIR");
+ if (tmpdir == NULL || tmpdir[0] == '\0')
+ tmpdir = "/tmp";
+
+ char fname[strlen (tmpdir) + sizeof "/tst-scanf15.XXXXXX"];
+ sprintf (fname, "%s/tst-scanf15.XXXXXX", tmpdir);
+ if (fname == NULL)
+ FAIL ();
+
+ /* Create a temporary file. */
+ int fd = mkstemp (fname);
+ if (fd == -1)
+ FAIL ();
+
+ FILE *fp = fdopen (fd, "w+");
+ if (fp == NULL)
+ FAIL ();
+ else
+ {
+ if (fputs (" 1.25s x", fp) == EOF)
+ FAIL ();
+ if (fseek (fp, 0, SEEK_SET) != 0)
+ FAIL ();
+ if (fscanf (fp, "%as%2c", &f, c) != 2)
+ FAIL ();
+ else if (f != 1.25 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+
+ if (freopen (fname, "r", stdin) == NULL)
+ FAIL ();
+ else
+ {
+ if (scanf ("%as%2c", &f, c) != 2)
+ FAIL ();
+ else if (f != 1.25 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ }
+
+ fclose (fp);
+ }
+
+ remove (fname);
+
return result;
}
diff --git a/libc/stdio-common/scanf16.c b/libc/stdio-common/scanf16.c
new file mode 100644
index 000000000..3e3cb417f
--- /dev/null
+++ b/libc/stdio-common/scanf16.c
@@ -0,0 +1,147 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#define FAIL() \
+ do { \
+ result = 1; \
+ printf ("test at line %d failed\n", __LINE__); \
+ } while (0)
+
+static int
+xsscanf (const char *str, const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ int ret = vsscanf (str, fmt, ap);
+ va_end (ap);
+ return ret;
+}
+
+static int
+xscanf (const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ int ret = vscanf (fmt, ap);
+ va_end (ap);
+ return ret;
+}
+
+static int
+xfscanf (FILE *f, const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ int ret = vfscanf (f, fmt, ap);
+ va_end (ap);
+ return ret;
+}
+
+int
+main (void)
+{
+ wchar_t *lsp;
+ char *sp;
+ float f;
+ double d;
+ char c[8];
+ int result = 0;
+
+ if (xsscanf (" 0.25s x", "%e%3c", &f, c) != 2)
+ FAIL ();
+ else if (f != 0.25 || memcmp (c, "s x", 3) != 0)
+ FAIL ();
+ if (xsscanf (" 1.25s x", "%as%2c", &sp, c) != 2)
+ FAIL ();
+ else
+ {
+ if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ memset (sp, 'x', sizeof "1.25s");
+ free (sp);
+ }
+ if (xsscanf (" 2.25s x", "%las%2c", &d, c) != 2)
+ FAIL ();
+ else if (d != 2.25 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ if (xsscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2)
+ FAIL ();
+ else
+ {
+ if (wcscmp (lsp, L"3.25") != 0 || memcmp (c, "S x", 3) != 0)
+ FAIL ();
+ memset (lsp, 'x', sizeof L"3.25");
+ free (lsp);
+ }
+ if (xsscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2)
+ FAIL ();
+ else
+ {
+ if (strcmp (sp, "4.25") != 0 || memcmp (c, "[0-9.] x", 8) != 0)
+ FAIL ();
+ memset (sp, 'x', sizeof "4.25");
+ free (sp);
+ }
+ if (xsscanf ("5.25[0-9.] x", "%la[0-9.]%2c", &d, c) != 2)
+ FAIL ();
+ else if (d != 5.25 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+
+ const char *tmpdir = getenv ("TMPDIR");
+ if (tmpdir == NULL || tmpdir[0] == '\0')
+ tmpdir = "/tmp";
+
+ char fname[strlen (tmpdir) + sizeof "/tst-scanf16.XXXXXX"];
+ sprintf (fname, "%s/tst-scanf16.XXXXXX", tmpdir);
+ if (fname == NULL)
+ FAIL ();
+
+ /* Create a temporary file. */
+ int fd = mkstemp (fname);
+ if (fd == -1)
+ FAIL ();
+
+ FILE *fp = fdopen (fd, "w+");
+ if (fp == NULL)
+ FAIL ();
+ else
+ {
+ if (fputs (" 1.25s x", fp) == EOF)
+ FAIL ();
+ if (fseek (fp, 0, SEEK_SET) != 0)
+ FAIL ();
+ if (xfscanf (fp, "%as%2c", &sp, c) != 2)
+ FAIL ();
+ else
+ {
+ if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ memset (sp, 'x', sizeof "1.25s");
+ free (sp);
+ }
+
+ if (freopen (fname, "r", stdin) == NULL)
+ FAIL ();
+ else
+ {
+ if (xscanf ("%as%2c", &sp, c) != 2)
+ FAIL ();
+ else
+ {
+ if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ memset (sp, 'x', sizeof "1.25s");
+ free (sp);
+ }
+ }
+
+ fclose (fp);
+ }
+
+ remove (fname);
+
+ return result;
+}
diff --git a/libc/stdio-common/scanf17.c b/libc/stdio-common/scanf17.c
new file mode 100644
index 000000000..ee9024f9b
--- /dev/null
+++ b/libc/stdio-common/scanf17.c
@@ -0,0 +1,128 @@
+#undef _GNU_SOURCE
+#define _XOPEN_SOURCE 600
+/* The following macro definitions are a hack. They word around disabling
+ the GNU extension while still using a few internal headers. */
+#define u_char unsigned char
+#define u_short unsigned short
+#define u_int unsigned int
+#define u_long unsigned long
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#define FAIL() \
+ do { \
+ result = 1; \
+ printf ("test at line %d failed\n", __LINE__); \
+ } while (0)
+
+static int
+xsscanf (const char *str, const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ int ret = vsscanf (str, fmt, ap);
+ va_end (ap);
+ return ret;
+}
+
+static int
+xscanf (const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ int ret = vscanf (fmt, ap);
+ va_end (ap);
+ return ret;
+}
+
+static int
+xfscanf (FILE *f, const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ int ret = vfscanf (f, fmt, ap);
+ va_end (ap);
+ return ret;
+}
+
+int
+main (void)
+{
+ float f;
+ double d;
+ char c[8];
+ int result = 0;
+
+ if (xsscanf (" 0.25s x", "%e%3c", &f, c) != 2)
+ FAIL ();
+ else if (f != 0.25 || memcmp (c, "s x", 3) != 0)
+ FAIL ();
+ if (xsscanf (" 1.25s x", "%as%2c", &f, c) != 2)
+ FAIL ();
+ else if (f != 1.25 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ if (xsscanf (" 2.25s x", "%las%2c", &d, c) != 2)
+ FAIL ();
+ else if (d != 2.25 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ if (xsscanf (" 3.25S x", "%4aS%2c", &f, c) != 2)
+ FAIL ();
+ else if (f != 3.25 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ if (xsscanf (" 4.25[0-9.] x", "%a[0-9.]%2c", &f, c) != 2)
+ FAIL ();
+ else if (f != 4.25 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ if (xsscanf (" 5.25[0-9.] x", "%la[0-9.]%2c", &d, c) != 2)
+ FAIL ();
+ else if (d != 5.25 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+
+ const char *tmpdir = getenv ("TMPDIR");
+ if (tmpdir == NULL || tmpdir[0] == '\0')
+ tmpdir = "/tmp";
+
+ char fname[strlen (tmpdir) + sizeof "/tst-scanf17.XXXXXX"];
+ sprintf (fname, "%s/tst-scanf17.XXXXXX", tmpdir);
+ if (fname == NULL)
+ FAIL ();
+
+ /* Create a temporary file. */
+ int fd = mkstemp (fname);
+ if (fd == -1)
+ FAIL ();
+
+ FILE *fp = fdopen (fd, "w+");
+ if (fp == NULL)
+ FAIL ();
+ else
+ {
+ if (fputs (" 1.25s x", fp) == EOF)
+ FAIL ();
+ if (fseek (fp, 0, SEEK_SET) != 0)
+ FAIL ();
+ if (xfscanf (fp, "%as%2c", &f, c) != 2)
+ FAIL ();
+ else if (f != 1.25 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+
+ if (freopen (fname, "r", stdin) == NULL)
+ FAIL ();
+ else
+ {
+ if (xscanf ("%as%2c", &f, c) != 2)
+ FAIL ();
+ else if (f != 1.25 || memcmp (c, " x", 2) != 0)
+ FAIL ();
+ }
+
+ fclose (fp);
+ }
+
+ remove (fname);
+
+ return result;
+}
diff --git a/libc/string/Makefile b/libc/string/Makefile
index cee45de17..36325e7ae 100644
--- a/libc/string/Makefile
+++ b/libc/string/Makefile
@@ -52,7 +52,7 @@ o-objects.ob := memcpy.o memset.o memchr.o
strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \
stpcpy stpncpy strcat strchr strcmp strcpy strcspn \
- strlen strncmp strncpy strpbrk strrchr strspn
+ strlen strncmp strncpy strpbrk strrchr strspn memmem
tests := tester inl-tester noinl-tester testcopy test-ffs \
tst-strlen stratcliff tst-svc tst-inlcall \
bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \
diff --git a/libc/string/endian.h b/libc/string/endian.h
index 430fb3a5c..37d030a25 100644
--- a/libc/string/endian.h
+++ b/libc/string/endian.h
@@ -56,39 +56,41 @@
#endif
+#ifdef __USE_BSD
/* Conversion interfaces. */
-#include <bits/byteswap.h>
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-# define htobe16(x) __bswap_16 (x)
-# define htole16(x) (x)
-# define be16toh(x) __bswap_16 (x)
-# define le16toh(x) (x)
-
-# define htobe32(x) __bswap_32 (x)
-# define htole32(x) (x)
-# define be32toh(x) __bswap_32 (x)
-# define le32toh(x) (x)
-
-# define htobe64(x) __bswap_64 (x)
-# define htole64(x) (x)
-# define be64toh(x) __bswap_64 (x)
-# define le64toh(x) (x)
-#else
-# define htobe16(x) (x)
-# define htole16(x) __bswap_16 (x)
-# define be16toh(x) (x)
-# define le16toh(x) __bswap_16 (x)
-
-# define htobe32(x) (x)
-# define htole32(x) __bswap_32 (x)
-# define be32toh(x) (x)
-# define le32toh(x) __bswap_32 (x)
-
-# define htobe64(x) (x)
-# define htole64(x) __bswap_64 (x)
-# define be64toh(x) (x)
-# define le64toh(x) __bswap_64 (x)
+# include <bits/byteswap.h>
+
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define htobe16(x) __bswap_16 (x)
+# define htole16(x) (x)
+# define be16toh(x) __bswap_16 (x)
+# define le16toh(x) (x)
+
+# define htobe32(x) __bswap_32 (x)
+# define htole32(x) (x)
+# define be32toh(x) __bswap_32 (x)
+# define le32toh(x) (x)
+
+# define htobe64(x) __bswap_64 (x)
+# define htole64(x) (x)
+# define be64toh(x) __bswap_64 (x)
+# define le64toh(x) (x)
+# else
+# define htobe16(x) (x)
+# define htole16(x) __bswap_16 (x)
+# define be16toh(x) (x)
+# define le16toh(x) __bswap_16 (x)
+
+# define htobe32(x) (x)
+# define htole32(x) __bswap_32 (x)
+# define be32toh(x) (x)
+# define le32toh(x) __bswap_32 (x)
+
+# define htobe64(x) (x)
+# define htole64(x) __bswap_64 (x)
+# define be64toh(x) (x)
+# define le64toh(x) __bswap_64 (x)
+# endif
#endif
#endif /* endian.h */
diff --git a/libc/string/test-memmem.c b/libc/string/test-memmem.c
new file mode 100644
index 000000000..91b661b16
--- /dev/null
+++ b/libc/string/test-memmem.c
@@ -0,0 +1,185 @@
+/* Test and measure memmem functions.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2008.
+
+ 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. */
+
+#define TEST_MAIN
+#define BUF1PAGES 20
+#define ITERATIONS 500
+#include "test-string.h"
+
+typedef char *(*proto_t) (const void *, size_t, const void *, size_t);
+void *simple_memmem (const void *, size_t, const void *, size_t);
+
+IMPL (simple_memmem, 0)
+IMPL (memmem, 1)
+
+void *
+simple_memmem (const void *haystack, size_t haystack_len, const void *needle,
+ size_t needle_len)
+{
+ const char *begin;
+ const char *const last_possible
+ = (const char *) haystack + haystack_len - needle_len;
+
+ if (needle_len == 0)
+ /* The first occurrence of the empty string is deemed to occur at
+ the beginning of the string. */
+ return (void *) haystack;
+
+ /* Sanity check, otherwise the loop might search through the whole
+ memory. */
+ if (__builtin_expect (haystack_len < needle_len, 0))
+ return NULL;
+
+ for (begin = (const char *) haystack; begin <= last_possible; ++begin)
+ if (begin[0] == ((const char *) needle)[0] &&
+ !memcmp ((const void *) &begin[1],
+ (const void *) ((const char *) needle + 1),
+ needle_len - 1))
+ return (void *) begin;
+
+ return NULL;
+}
+
+static void
+do_one_test (impl_t *impl, const void *haystack, size_t haystack_len,
+ const void *needle, size_t needle_len, const void *expected)
+{
+ void *res;
+
+ res = CALL (impl, haystack, haystack_len, needle, needle_len);
+ if (res != expected)
+ {
+ error (0, 0, "Wrong result in function %s %p %p", impl->name,
+ res, expected);
+ ret = 1;
+ return;
+ }
+
+ if (HP_TIMING_AVAIL)
+ {
+ hp_timing_t start __attribute ((unused));
+ hp_timing_t stop __attribute ((unused));
+ hp_timing_t best_time = ~ (hp_timing_t) 0;
+ size_t i;
+
+ for (i = 0; i < 32; ++i)
+ {
+ HP_TIMING_NOW (start);
+ CALL (impl, haystack, haystack_len, needle, needle_len);
+ HP_TIMING_NOW (stop);
+ HP_TIMING_BEST (best_time, start, stop);
+ }
+
+ printf ("\t%zd", (size_t) best_time);
+ }
+}
+
+static void
+do_test (const char *str, size_t len, size_t idx)
+{
+ char tmpbuf[len];
+
+ memcpy (tmpbuf, buf1 + idx, len);
+ memcpy (buf1 + idx, str, len);
+
+ if (HP_TIMING_AVAIL)
+ printf ("String %s, offset %zd:", str, idx);
+
+ FOR_EACH_IMPL (impl, 0)
+ do_one_test (impl, buf1, BUF1PAGES * page_size, str, len, buf1 + idx);
+
+ memcpy (buf1 + idx, tmpbuf, len);
+
+ if (HP_TIMING_AVAIL)
+ putchar ('\n');
+}
+
+static void
+do_random_tests (void)
+{
+ for (size_t n = 0; n < ITERATIONS; ++n)
+ {
+ char tmpbuf[32];
+
+ size_t shift = random () % 11;
+ size_t rel = random () % ((2 << (shift + 1)) * 64);
+ size_t idx = MIN ((2 << shift) * 64 + rel, BUF1PAGES * page_size - 2);
+ size_t len = random () % (sizeof (tmpbuf) - 1) + 1;
+ len = MIN (len, BUF1PAGES * page_size - idx - 1);
+ memcpy (tmpbuf, buf1 + idx, len);
+ for (size_t i = random () % len / 2 + 1; i > 0; --i)
+ {
+ size_t off = random () % len;
+ char ch = '0' + random () % 10;
+
+ buf1[idx + off] = ch;
+ }
+
+ if (HP_TIMING_AVAIL)
+ printf ("String %.*s, offset %zd:", (int) len, buf1 + idx, idx);
+
+ FOR_EACH_IMPL (impl, 0)
+ do_one_test (impl, buf1, BUF1PAGES * page_size, buf1 + idx, len,
+ buf1 + idx);
+
+ if (HP_TIMING_AVAIL)
+ putchar ('\n');
+
+ memcpy (buf1 + idx, tmpbuf, len);
+ }
+}
+
+
+static const char *const strs[] =
+ {
+ "00000", "00112233", "0123456789", "0000111100001111",
+ "00000111110000022222", "012345678901234567890",
+ "abc0", "aaaa0", "abcabc0"
+ };
+
+
+int
+test_main (void)
+{
+ size_t i;
+
+ test_init ();
+
+ printf ("%23s", "");
+ FOR_EACH_IMPL (impl, 0)
+ printf ("\t%s", impl->name);
+ putchar ('\n');
+
+ for (i = 0; i < BUF1PAGES * page_size; ++i)
+ buf1[i] = 60 + random () % 32;
+
+ for (i = 0; i < sizeof (strs) / sizeof (strs[0]); ++i)
+ for (size_t j = 0; j < 120; j += 7)
+ {
+ size_t len = strlen (strs[i]);
+
+ do_test (strs[i], len, j);
+ }
+
+ do_random_tests ();
+ return ret;
+}
+
+#include "../test-skeleton.c"
diff --git a/libc/string/test-string.h b/libc/string/test-string.h
index 381c140d9..1aea4c9cb 100644
--- a/libc/string/test-string.h
+++ b/libc/string/test-string.h
@@ -1,5 +1,5 @@
/* Test and measure string and memory functions.
- Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -118,6 +118,10 @@ size_t iterations = 100000;
} \
while (0)
+#ifndef BUF1PAGES
+# define BUF1PAGES 1
+#endif
+
static void
test_init (void)
{
@@ -126,11 +130,11 @@ test_init (void)
if (page_size < MIN_PAGE_SIZE)
page_size = MIN_PAGE_SIZE;
#endif
- buf1 = mmap (0, 2 * page_size, PROT_READ | PROT_WRITE,
+ buf1 = mmap (0, (BUF1PAGES + 1) * page_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
if (buf1 == MAP_FAILED)
error (EXIT_FAILURE, errno, "mmap failed");
- if (mprotect (buf1 + page_size, page_size, PROT_NONE))
+ if (mprotect (buf1 + BUF1PAGES * page_size, page_size, PROT_NONE))
error (EXIT_FAILURE, errno, "mprotect failed");
buf2 = mmap (0, 2 * page_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
@@ -145,7 +149,7 @@ test_init (void)
srandom (seed);
}
- memset (buf1, 0xa5, page_size);
+ memset (buf1, 0xa5, BUF1PAGES * page_size);
memset (buf2, 0x5a, page_size);
}
diff --git a/libc/sysdeps/posix/getaddrinfo.c b/libc/sysdeps/posix/getaddrinfo.c
index 2515d23c2..4987505c5 100644
--- a/libc/sysdeps/posix/getaddrinfo.c
+++ b/libc/sysdeps/posix/getaddrinfo.c
@@ -660,7 +660,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
goto process_list;
}
- else if (err != 0 && __nss_not_use_nscd_hosts == 0)
+ else if (err == 0)
+ /* The database contains a negative entry. */
+ return 0;
+ else if (__nss_not_use_nscd_hosts == 0)
{
if (herrno == NETDB_INTERNAL && errno == ENOMEM)
return -EAI_MEMORY;
@@ -681,6 +684,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
"dns [!UNAVAIL=return] files",
&nip);
+ /* Initialize configurations. */
+ if (__builtin_expect (!_res_hconf.initialized, 0))
+ _res_hconf_init ();
if (__res_maybe_init (&_res, 0) == -1)
no_more = 1;
@@ -880,9 +886,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
}
}
- if (pai == NULL)
- return 0;
-
{
struct gaih_servtuple *st2;
struct gaih_addrtuple *at2 = at;
@@ -2088,10 +2091,6 @@ getaddrinfo (const char *name, const char *service,
if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
return EAI_BADFLAGS;
- /* Initialize configurations. */
- if (__builtin_expect (!_res_hconf.initialized, 0))
- _res_hconf_init ();
-
struct in6addrinfo *in6ai = NULL;
size_t in6ailen = 0;
bool seen_ipv4 = false;
@@ -2146,11 +2145,7 @@ getaddrinfo (const char *name, const char *service,
else
pservice = NULL;
- struct addrinfo **end;
- if (pai)
- end = &p;
- else
- end = NULL;
+ struct addrinfo **end = &p;
unsigned int naddrs = 0;
if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
@@ -2164,12 +2159,11 @@ getaddrinfo (const char *name, const char *service,
return -(last_i & GAIH_EAI);
}
- if (end)
- while (*end)
- {
- end = &((*end)->ai_next);
- ++nresults;
- }
+ while (*end)
+ {
+ end = &((*end)->ai_next);
+ ++nresults;
+ }
}
else
{
@@ -2365,9 +2359,6 @@ getaddrinfo (const char *name, const char *service,
return 0;
}
- if (pai == NULL && last_i == 0)
- return 0;
-
return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
}
libc_hidden_def (getaddrinfo)
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_lround.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_lround.S
index ebaccccd9..d73749e13 100644
--- a/libc/sysdeps/powerpc/powerpc32/fpu/s_lround.S
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_lround.S
@@ -1,5 +1,5 @@
/* lround function. PowerPC32 version.
- Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006, 2007, 2008 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
@@ -65,10 +65,10 @@ ENTRY (__lround)
fabs fp2, fp1 /* Get the absolute value of x. */
fsub fp12,fp10,fp10 /* Compute 0.0. */
fcmpu cr6, fp2, fp10 /* if |x| < 0.5 */
- fcmpu cr3, fp1, fp12 /* x is negative? x < 0.0 */
+ fcmpu cr7, fp1, fp12 /* x is negative? x < 0.0 */
blt- cr6,.Lretzero
fadd fp3,fp2,fp10 /* |x|+=0.5 bias to prepare to round. */
- bge cr3,.Lconvert /* x is positive so don't negate x. */
+ bge cr7,.Lconvert /* x is positive so don't negate x. */
fnabs fp3,fp3 /* -(|x|+=0.5) */
.Lconvert:
fctiwz fp4,fp3 /* Convert to Integer word lround toward 0. */
diff --git a/libc/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S b/libc/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S
index 4b1691efd..e10a37977 100644
--- a/libc/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S
+++ b/libc/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S
@@ -1,5 +1,5 @@
/* llround function. PowerPC32 on PowerPC64 version.
- Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006, 2007, 2008 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
@@ -75,12 +75,12 @@ ENTRY (__llround)
fabs fp2,fp1 /* Get the absolute value of x. */
fsub fp12,fp10,fp10 /* Compute 0.0 into fpr12. */
fcmpu cr6,fp2,fp10 /* if |x| < 0.5 */
- fcmpu cr4,fp2,fp9 /* if |x| >= 2^52 */
- fcmpu cr3,fp1,fp12 /* x is negative? x < 0.0 */
+ fcmpu cr7,fp2,fp9 /* if |x| >= 2^52 */
+ fcmpu cr1,fp1,fp12 /* x is negative? x < 0.0 */
blt- cr6,.Lretzero /* 0.5 > x < -0.5 so just return 0. */
- bge- cr4,.Lnobias /* 2^52 > x < -2^52 just convert with no bias. */
+ bge- cr7,.Lnobias /* 2^52 > x < -2^52 just convert with no bias. */
fadd fp3,fp2,fp10 /* |x|+=0.5 bias to prepare to round. */
- bge cr3,.Lconvert /* x is positive so don't negate x. */
+ bge cr1,.Lconvert /* x is positive so don't negate x. */
fnabs fp3,fp3 /* -(|x|+=0.5) */
.Lconvert:
fctidz fp4,fp3 /* Convert to Integer double word round toward 0. */
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_llround.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_llround.S
index 413484753..cdfdd02c3 100644
--- a/libc/sysdeps/powerpc/powerpc64/fpu/s_llround.S
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_llround.S
@@ -1,5 +1,5 @@
/* llround function. PowerPC64 version.
- Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006, 2007, 2008 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
@@ -52,12 +52,12 @@ ENTRY (__llround)
fabs fp2,fp1 /* Get the absolute value of x. */
fsub fp12,fp10,fp10 /* Compute 0.0 into fp12. */
fcmpu cr6,fp2,fp10 /* if |x| < 0.5 */
- fcmpu cr4,fp2,fp9 /* if |x| >= 2^52 */
- fcmpu cr3,fp1,fp12 /* x is negative? x < 0.0 */
+ fcmpu cr7,fp2,fp9 /* if |x| >= 2^52 */
+ fcmpu cr1,fp1,fp12 /* x is negative? x < 0.0 */
blt- cr6,.Lretzero /* 0.5 > x < -0.5 so just return 0. */
- bge- cr4,.Lnobias /* 2^52 > x < -2^52 just convert with no bias. */
+ bge- cr7,.Lnobias /* 2^52 > x < -2^52 just convert with no bias. */
fadd fp3,fp2,fp10 /* |x|+=0.5 bias to prepare to round. */
- bge cr3,.Lconvert /* x is positive so don't negate x. */
+ bge cr1,.Lconvert /* x is positive so don't negate x. */
fnabs fp3,fp3 /* -(|x|+=0.5) */
.Lconvert:
fctidz fp4,fp3 /* Convert to Integer double word round toward 0. */
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S
index a21187939..e617bca44 100644
--- a/libc/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S
@@ -1,5 +1,5 @@
/* llroundf function. PowerPC64 version.
- Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006, 2007, 2008 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
@@ -51,12 +51,12 @@ ENTRY (__llroundf)
fabs fp2,fp1 /* Get the absolute value of x. */
fsub fp12,fp10,fp10 /* Compute 0.0 into fp12. */
fcmpu cr6,fp2,fp10 /* if |x| < 0.5 */
- fcmpu cr4,fp2,fp9 /* if |x| >= 2^23 */
- fcmpu cr3,fp1,fp12 /* x is negative? x < 0.0 */
+ fcmpu cr7,fp2,fp9 /* if |x| >= 2^23 */
+ fcmpu cr1,fp1,fp12 /* x is negative? x < 0.0 */
blt- cr6,.Lretzero /* 0.5 > x < -0.5 so just return 0. */
- bge- cr4,.Lnobias /* 2^23 > x < -2^23 just convert with no bias. */
+ bge- cr7,.Lnobias /* 2^23 > x < -2^23 just convert with no bias. */
fadd fp3,fp2,fp10 /* |x|+=0.5 bias to prepare to round. */
- bge cr3,.Lconvert /* x is positive so don't negate x. */
+ bge cr1,.Lconvert /* x is positive so don't negate x. */
fnabs fp3,fp3 /* -(|x|+=0.5) */
.Lconvert:
fctidz fp4,fp3 /* Convert to Integer double word round toward 0. */
diff --git a/libc/sysdeps/sparc/Makefile b/libc/sysdeps/sparc/Makefile
index 40323a064..9fa5324b4 100644
--- a/libc/sysdeps/sparc/Makefile
+++ b/libc/sysdeps/sparc/Makefile
@@ -1,6 +1,10 @@
# The Sparc `long double' is a distinct type we support.
long-double-fcts = yes
+ifeq ($(subdir),gmon)
+sysdep_routines += sparc-mcount
+endif
+
ifeq ($(subdir),db2)
CPPFLAGS += -DHAVE_SPINLOCKS=1 -DHAVE_ASSEM_SPARC_GCC=1
endif
diff --git a/libc/sysdeps/sparc/machine-gmon.h b/libc/sysdeps/sparc/machine-gmon.h
new file mode 100644
index 000000000..296c5ff4d
--- /dev/null
+++ b/libc/sysdeps/sparc/machine-gmon.h
@@ -0,0 +1,33 @@
+/* sparc-specific implementation of profiling support.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller <davem@davemloft.net>, 2008
+
+ 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 <sysdep.h>
+
+/* We must not pollute the global namespace. */
+#define mcount_internal __mcount_internal
+
+extern void mcount_internal (u_long frompc, u_long selfpc) internal_function;
+
+#define _MCOUNT_DECL(frompc, selfpc) \
+void internal_function mcount_internal (u_long frompc, u_long selfpc)
+
+/* Define MCOUNT as empty since we have the implementation in another
+ file. */
+#define MCOUNT
diff --git a/libc/sysdeps/sparc/sparc-mcount.S b/libc/sysdeps/sparc/sparc-mcount.S
new file mode 100644
index 000000000..573b08f51
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc-mcount.S
@@ -0,0 +1,29 @@
+/* sparc-specific implemetation of profiling support.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller <davem@davemloft.net>, 2008.
+
+ 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 <sysdep.h>
+
+ENTRY(_mcount)
+ mov %i7, %o0
+ ba __mcount_internal
+ mov %o7, %o1
+END(_mcount)
+
+weak_alias (_mcount, mcount)
diff --git a/libc/sysdeps/sparc/sparc64/backtrace.c b/libc/sysdeps/sparc/sparc64/backtrace.c
new file mode 100644
index 000000000..6d7e429e2
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/backtrace.c
@@ -0,0 +1,58 @@
+/* Return backtrace of current program state.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller <davem@davemloft.net>
+
+ 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 <execinfo.h>
+#include <stddef.h>
+#include <bp-checks.h>
+#include <sysdep.h>
+
+struct layout
+{
+ unsigned long locals[8];
+ unsigned long ins[6];
+ unsigned long next;
+ void *__unbounded return_address;
+};
+
+int
+__backtrace (void **array, int size)
+{
+ struct layout *current;
+ unsigned long fp;
+ int count;
+
+ asm volatile ("flushw");
+ asm volatile ("mov %%fp, %0" : "=r"(fp));
+ current = (struct layout *__unbounded) (fp + STACK_BIAS);
+ current = BOUNDED_1 (current);
+
+ for (count = 0; count < size; count++)
+ {
+ array[count] = current->return_address;
+ if (!current->next)
+ break;
+ current = (struct layout *__unbounded) (current->next + STACK_BIAS);
+ current = BOUNDED_1 (current);
+ }
+
+ return count;
+}
+weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
diff --git a/libc/sysdeps/unix/sysv/linux/Makefile b/libc/sysdeps/unix/sysv/linux/Makefile
index 3b86e6eb3..aa364df5e 100644
--- a/libc/sysdeps/unix/sysv/linux/Makefile
+++ b/libc/sysdeps/unix/sysv/linux/Makefile
@@ -155,7 +155,7 @@ CFLAGS-mq_receive.c += -fexceptions
endif
ifeq ($(subdir),nscd)
-CFLAGS-connections.c += -DHAVE_EPOLL -DHAVE_SENDFILE
+CFLAGS-connections.c += -DHAVE_EPOLL -DHAVE_SENDFILE -DHAVE_INOTIFY
CFLAGS-pwdcache.c += -DHAVE_SENDFILE
CFLAGS-grpcache.c += -DHAVE_SENDFILE
CFLAGS-hstcache.c += -DHAVE_SENDFILE
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S
index 33e40ac65..a38cd30c0 100644
--- a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S
@@ -111,7 +111,7 @@ ENTRY(__start_context)
mov %g1, %o0
/* If this returns (which can happen if the syscall fails) we'll
exit the program with the return error value (-1). */
-1: call exit
+1: call HIDDEN_JUMPTARGET(exit)
nop
/* The 'exit' call should never return. In case it does cause
the process to terminate. */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
index 2c2770d07..59656978b 100644
--- a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
@@ -20,6 +20,9 @@
#define SIGCONTEXT struct sigcontext *
#define SIGCONTEXT_EXTRA_ARGS
#define GET_PC(__ctx) ((void *) ((__ctx)->si_regs.pc))
+#define FIRST_FRAME_POINTER \
+ ({ void *ret; \
+ asm volatile ("ta 3; add %%fp, 56, %0" : "=r" (ret)); ret; })
#define ADVANCE_STACK_FRAME(__next) \
((void *) (((unsigned *)(__next))+14))
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
index c808a97fc..3cb0a48c9 100644
--- a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 2002, 2003, 2004, 2006, 2008
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, January 1997.
@@ -89,6 +90,13 @@ ENTRY(name); \
#else /* __ASSEMBLER__ */
+#if defined SHARED && defined DO_VERSIONING && defined PIC \
+ && !defined NO_HIDDEN && !defined NOT_IN_libc
+# define CALL_ERRNO_LOCATION "call __GI___errno_location;"
+#else
+# define CALL_ERRNO_LOCATION "call __errno_location;"
+#endif
+
#define __SYSCALL_STRING \
"ta 0x10;" \
"bcs 2f;" \
@@ -97,7 +105,7 @@ ENTRY(name); \
".subsection 2;" \
"2:" \
"save %%sp, -192, %%sp;" \
- "call __errno_location;" \
+ CALL_ERRNO_LOCATION \
" nop;" \
"st %%i0,[%%o0];" \
"ba 1b;" \
@@ -113,7 +121,7 @@ ENTRY(name); \
".subsection 2;" \
"2:" \
"save %%sp, -192, %%sp;" \
- "call __errno_location;" \
+ CALL_ERRNO_LOCATION \
" nop;" \
"st %%i0, [%%o0];" \
"ba 1b;" \
@@ -126,7 +134,7 @@ ENTRY(name); \
" sub %%g0, %%o0, %%o0;" \
"1:"
-#define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6", \
+#define __SYSCALL_CLOBBERS \
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
index 134ce789f..ccc558992 100644
--- a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
@@ -86,7 +86,11 @@ ENTRY (__brk)
#endif
st %o0, [%g1]
#else
+#ifndef NOT_IN_libc
+ call HIDDEN_JUMPTARGET(__errno_location)
+#else
call __errno_location
+#endif
mov %o0,%l1
st %l1, [%o0]
#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
index f156f9241..79fa13de7 100644
--- a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 2000, 2002, 2003, 2004, 2006
+/* Copyright (C) 1997, 2000, 2002, 2003, 2004, 2006, 2008
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
@@ -106,12 +106,19 @@ ENTRY(name); \
#else /* __ASSEMBLER__ */
+#if defined SHARED && defined DO_VERSIONING && defined PIC \
+ && !defined NO_HIDDEN && !defined NOT_IN_libc
+# define CALL_ERRNO_LOCATION "call __GI___errno_location;"
+#else
+# define CALL_ERRNO_LOCATION "call __errno_location;"
+#endif
+
#define __SYSCALL_STRING \
"ta 0x6d;" \
"bcc,pt %%xcc, 1f;" \
" nop;" \
"save %%sp, -192, %%sp;" \
- "call __errno_location;" \
+ CALL_ERRNO_LOCATION \
" nop;" \
"st %%i0,[%%o0];" \
"restore %%g0, -1, %%o0;" \
@@ -122,7 +129,7 @@ ENTRY(name); \
"bcc,pt %%xcc, 1f;" \
" sub %%o1, 1, %%o1;" \
"save %%sp, -192, %%sp;" \
- "call __errno_location;" \
+ CALL_ERRNO_LOCATION \
" mov -1, %%i1;" \
"st %%i0,[%%o0];" \
"restore %%g0, -1, %%o0;" \
@@ -135,7 +142,7 @@ ENTRY(name); \
" sub %%g0, %%o0, %%o0;" \
"1:"
-#define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6", \
+#define __SYSCALL_CLOBBERS \
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
diff --git a/libc/time/strftime_l.c b/libc/time/strftime_l.c
index eb8f06ce6..2f9668495 100644
--- a/libc/time/strftime_l.c
+++ b/libc/time/strftime_l.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2004, 2007, 2008 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
@@ -459,7 +459,8 @@ static CHAR_T const month_name[][10] =
#endif
static size_t __strftime_internal (CHAR_T *, size_t, const CHAR_T *,
- const struct tm *, bool ut_argument_spec_iso
+ const struct tm *, bool *
+ ut_argument_spec_iso
LOCALE_PARAM_PROTO) __THROW;
/* Write information from TP into S according to the format
@@ -485,7 +486,8 @@ my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
tmcopy = *tp;
tp = &tmcopy;
#endif
- return __strftime_internal (s, maxsize, format, tp, false
+ bool tzset_called = false;
+ return __strftime_internal (s, maxsize, format, tp, &tzset_called
ut_argument LOCALE_ARG);
}
#ifdef _LIBC
@@ -499,7 +501,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
size_t maxsize;
const CHAR_T *format;
const struct tm *tp;
- bool tzset_called;
+ bool *tzset_called;
ut_argument_spec
LOCALE_PARAM_DECL
{
@@ -567,16 +569,6 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
if (! (zone && *zone))
zone = "GMT";
}
- else
- {
- /* POSIX.1 requires that local time zone information is used as
- though strftime called tzset. */
-# if HAVE_TZSET
- if (!tzset_called)
- tzset ();
- tzset_called = true;
-# endif
- }
#endif
if (hour12 > 12)
@@ -1329,7 +1321,18 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
#if HAVE_TZNAME
/* The tzset() call might have changed the value. */
if (!(zone && *zone) && tp->tm_isdst >= 0)
- zone = tzname[tp->tm_isdst];
+ {
+ /* POSIX.1 requires that local time zone information is used as
+ though strftime called tzset. */
+# if HAVE_TZSET
+ if (!*tzset_called)
+ {
+ tzset ();
+ *tzset_called = true;
+ }
+# endif
+ zone = tzname[tp->tm_isdst];
+ }
#endif
if (! zone)
zone = "";
@@ -1365,6 +1368,16 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
struct tm ltm;
time_t lt;
+ /* POSIX.1 requires that local time zone information is used as
+ though strftime called tzset. */
+# if HAVE_TZSET
+ if (!*tzset_called)
+ {
+ tzset ();
+ *tzset_called = true;
+ }
+# endif
+
ltm = *tp;
lt = mktime (&ltm);
diff --git a/ports/ChangeLog.arm b/ports/ChangeLog.arm
index f05963022..212231a69 100644
--- a/ports/ChangeLog.arm
+++ b/ports/ChangeLog.arm
@@ -1,3 +1,23 @@
+2008-06-01 Paul Brook <paul@codesourcery.com>
+ Zack Weinberg <zack@codesourcery.com>
+ Daniel Jacobowitz <dan@codesourcery.com>
+
+ * sysdeps/arm/nptl/pthread_spin_lock.S,
+ sysdeps/arm/nptl/pthread_spin_trylock.S: Delete.
+ * sysdeps/arm/nptl/pthread_spin_lock.c,
+ sysdeps/arm/nptl/pthread_spin_trylock.c: New files using
+ atomic_compare_and_exchange_val_acq to take spinlocks.
+ * sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h (lll_trylock,
+ lll_cond_trylock): Use atomic_compare_and_exchange_val_acq.
+ (__lll_trylock, __lll_cond_trylock): Delete.
+ * sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h
+ (atomic_exchange_acq): Delete.
+ (atomic_full_barrier): Define.
+ (__arch_compare_and_exchange_val_32_acq): Use named operands.
+ * sysdeps/unix/sysv/linux/arm/eabi/configure.in: Update
+ arch_minimum_kernel to 2.6.16.
+ * sysdeps/unix/sysv/linux/arm/eabi/configure: Regenerated.
+
2008-04-21 Daniel Jacobowitz <dan@codesourcery.com>
* sysdeps/unix/sysv/linux/arm/check_pf.c: Update from generic
diff --git a/ports/ChangeLog.hppa b/ports/ChangeLog.hppa
index 67524bae3..2a4a712db 100644
--- a/ports/ChangeLog.hppa
+++ b/ports/ChangeLog.hppa
@@ -1,3 +1,18 @@
+2008-06-17 Aurelian Jarno <aurelien@aurel32.net>
+ Carlos O'Donell <carlos@systemhalted.org>
+
+ [BZ #6037]
+ * sysdeps/unix/sysv/linux/hppa/bits/atomic.h: Check for -11
+ (-EAGAIN) instead of 11. Loop again when the kernel
+ returns -45 (-EDEADLOCK). Add back memory clobber.
+ Do not initialize lws_ret and lws_errno.
+
+2008-06-17 Guy Martin <gmsoft@tuxicoman.be>
+
+ [BZ #5957]
+ * sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h:
+ Use shared futex in lll_wait_tid().
+
2008-05-12 Aurelien Jarno <aurelien@aurel32.net>
[BZ #6506]
diff --git a/ports/ChangeLog.mips b/ports/ChangeLog.mips
index 398fac9ce..8a90a3d40 100644
--- a/ports/ChangeLog.mips
+++ b/ports/ChangeLog.mips
@@ -1,3 +1,8 @@
+2008-05-21 Joseph Myers <joseph@codesourcery.com>
+
+ * sysdeps/unix/sysv/linux/mips/bits/socket.h: Cleanup namespace.
+ (SOCK_DCCP): Define.
+
2008-05-01 Joseph Myers <joseph@codesourcery.com>
* sysdeps/unix/sysv/linux/mips/bits/resource.h: Define
diff --git a/ports/sysdeps/arm/nptl/pthread_spin_lock.c b/ports/sysdeps/arm/nptl/pthread_spin_lock.c
index 9661d13d4..1217b899a 100644
--- a/ports/sysdeps/arm/nptl/pthread_spin_lock.c
+++ b/ports/sysdeps/arm/nptl/pthread_spin_lock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2008 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,7 @@
int
pthread_spin_lock (pthread_spinlock_t *lock)
{
- while (atomic_compare_and_exchange_val_acq(lock, 1, 0) != 0)
+ while (atomic_compare_and_exchange_val_acq (lock, 1, 0) != 0)
while (*lock != 0)
;
diff --git a/ports/sysdeps/arm/nptl/pthread_spin_trylock.c b/ports/sysdeps/arm/nptl/pthread_spin_trylock.c
index 8e65e7326..fb998d243 100644
--- a/ports/sysdeps/arm/nptl/pthread_spin_trylock.c
+++ b/ports/sysdeps/arm/nptl/pthread_spin_trylock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2008 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
@@ -23,5 +23,5 @@
int
pthread_spin_trylock (pthread_spinlock_t *lock)
{
- return atomic_compare_and_exchange_val_acq(lock, 1, 0) ? EBUSY : 0;
+ return atomic_compare_and_exchange_val_acq (lock, 1, 0) ? EBUSY : 0;
}
diff --git a/ports/sysdeps/unix/sysv/linux/arm/eabi/configure b/ports/sysdeps/unix/sysv/linux/arm/eabi/configure
index ab8304889..28fb9ef2d 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/eabi/configure
+++ b/ports/sysdeps/unix/sysv/linux/arm/eabi/configure
@@ -1,5 +1,5 @@
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
# Local configure fragment for sysdeps/unix/sysv/linux/arm/eabi.
-arch_minimum_kernel=2.6.14
+arch_minimum_kernel=2.6.16
libc_cv_gcc_unwind_find_fde=no
diff --git a/ports/sysdeps/unix/sysv/linux/arm/eabi/configure.in b/ports/sysdeps/unix/sysv/linux/arm/eabi/configure.in
index 83aa8fccb..d1fb7f422 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/eabi/configure.in
+++ b/ports/sysdeps/unix/sysv/linux/arm/eabi/configure.in
@@ -1,5 +1,5 @@
GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
# Local configure fragment for sysdeps/unix/sysv/linux/arm/eabi.
-arch_minimum_kernel=2.6.14
+arch_minimum_kernel=2.6.16
libc_cv_gcc_unwind_find_fde=no
diff --git a/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h b/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
index b8959f7b6..2964732f4 100644
--- a/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
+++ b/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
@@ -51,34 +51,41 @@ typedef uintmax_t uatomic_max_t;
*addr = new;
return prev; */
-/* Use the kernel atomic light weight syscalls on hppa */
-#define LWS "0xb0"
-#define LWS_CAS "0"
-/* Note r31 is the link register */
-#define LWS_CLOBBER "r1", "r26", "r25", "r24", "r23", "r22", "r21", "r20", "r28", "r31"
-#define ASM_EAGAIN "11"
+/* Use the kernel atomic light weight syscalls on hppa. */
+#define _LWS "0xb0"
+#define _LWS_CAS "0"
+/* Note r31 is the link register. */
+#define _LWS_CLOBBER "r1", "r26", "r25", "r24", "r23", "r22", "r21", "r20", "r28", "r31", "memory"
+/* String constant for -EAGAIN. */
+#define _ASM_EAGAIN "-11"
+/* String constant for -EDEADLOCK. */
+#define _ASM_EDEADLOCK "-45"
#if __ASSUME_LWS_CAS
/* The only basic operation needed is compare and exchange. */
# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
({ \
- volatile int lws_errno = EFAULT; \
- volatile int lws_ret = 0xdeadbeef; \
+ volatile int lws_errno; \
+ volatile int lws_ret; \
asm volatile( \
"0: \n\t" \
- "copy %3, %%r26 \n\t" \
- "copy %4, %%r25 \n\t" \
- "copy %5, %%r24 \n\t" \
- "ble " LWS "(%%sr2, %%r0) \n\t" \
- "ldi " LWS_CAS ", %%r20 \n\t" \
- "cmpib,=,n " ASM_EAGAIN ",%%r21,0b \n\t" \
+ "copy %2, %%r26 \n\t" \
+ "copy %3, %%r25 \n\t" \
+ "copy %4, %%r24 \n\t" \
+ "ble " _LWS "(%%sr2, %%r0) \n\t" \
+ "ldi " _LWS_CAS ", %%r20 \n\t" \
+ "ldi " _ASM_EAGAIN ", %%r24 \n\t" \
+ "cmpb,=,n %%r24, %%r21, 0b \n\t" \
+ "nop \n\t" \
+ "ldi " _ASM_EDEADLOCK ", %%r25 \n\t" \
+ "cmpb,=,n %%r25, %%r21, 0b \n\t" \
"nop \n\t" \
"stw %%r28, %0 \n\t" \
"sub %%r0, %%r21, %%r21 \n\t" \
"stw %%r21, %1 \n\t" \
- : "=m" (lws_ret), "=m" (lws_errno), "+m" (*mem) \
+ : "=m" (lws_ret), "=m" (lws_errno) \
: "r" (mem), "r" (oldval), "r" (newval) \
- : LWS_CLOBBER \
+ : _LWS_CLOBBER \
); \
\
if(lws_errno == EFAULT || lws_errno == ENOSYS) \
@@ -91,7 +98,7 @@ typedef uintmax_t uatomic_max_t;
({ \
int ret; \
ret = atomic_compare_and_exchange_val_acq(mem, newval, oldval); \
- /* Return 1 if it was already acquired */ \
+ /* Return 1 if it was already acquired. */ \
(ret != oldval); \
})
#else
diff --git a/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h b/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h
index ec907aefb..6998a91b6 100644
--- a/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h
+++ b/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h
@@ -325,12 +325,12 @@ extern int lll_unlock_wake_cb (lll_lock_t *__futex) attribute_hidden;
thread ID while the clone is running and is reset to zero
afterwards. */
#define lll_wait_tid(tid) \
- do \
- { \
- __typeof (tid) __tid; \
- while ((__tid = (tid)) != 0) \
- lll_futex_wait (&(tid), __tid, 0); \
- } \
+ do \
+ { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait (&(tid), __tid, LLL_SHARED); \
+ } \
while (0)
extern int __lll_timedwait_tid (int *, const struct timespec *)
diff --git a/ports/sysdeps/unix/sysv/linux/mips/bits/socket.h b/ports/sysdeps/unix/sysv/linux/mips/bits/socket.h
index 8748c0a04..f3adf5f1a 100644
--- a/ports/sysdeps/unix/sysv/linux/mips/bits/socket.h
+++ b/ports/sysdeps/unix/sysv/linux/mips/bits/socket.h
@@ -1,5 +1,5 @@
/* System-specific socket constants and types. Linux/MIPS version.
- Copyright (C) 1991, 92, 1994-1999, 2000, 2001, 2004, 2005, 2006, 2007
+ Copyright (C) 1991, 92, 1994-1999, 2000, 2001, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -26,10 +26,8 @@
#endif
#define __need_size_t
-#define __need_NULL
#include <stddef.h>
-#include <limits.h>
#include <sys/types.h>
/* Type for length arguments in socket calls. */
@@ -54,6 +52,8 @@ enum __socket_type
SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based,
datagrams of fixed maximum length. */
#define SOCK_SEQPACKET SOCK_SEQPACKET
+ SOCK_DCCP = 6,
+#define SOCK_DCCP SOCK_DCCP /* Datagram Congestion Control Protocol. */
SOCK_PACKET = 10 /* Linux specific way of getting packets
at the dev level. For writing rarp and
other similar things on the user level. */
@@ -156,11 +156,7 @@ struct sockaddr
/* Structure large enough to hold any socket address (with the historical
exception of AF_UNIX). We reserve 128 bytes. */
-#if ULONG_MAX > 0xffffffff
-# define __ss_aligntype __uint64_t
-#else
-# define __ss_aligntype __uint32_t
-#endif
+#define __ss_aligntype unsigned long int
#define _SS_SIZE 128
#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype)))
@@ -257,7 +253,7 @@ struct cmsghdr
#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr (mhdr, cmsg)
#define CMSG_FIRSTHDR(mhdr) \
((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) \
- ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) NULL)
+ ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)
#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \
& (size_t) ~(sizeof (size_t) - 1))
#define CMSG_SPACE(len) (CMSG_ALIGN (len) \
@@ -301,18 +297,74 @@ enum
#endif
};
+#ifdef __USE_GNU
/* User visible structure for SCM_CREDENTIALS message */
-
struct ucred
{
pid_t pid; /* PID of sending process. */
uid_t uid; /* UID of sending process. */
gid_t gid; /* GID of sending process. */
};
+#endif
+
+/* Ugly workaround for unclean kernel headers. */
+#if !defined __USE_MISC && !defined __USE_GNU
+# ifndef FIOGETOWN
+# define __SYS_SOCKET_H_undef_FIOGETOWN
+# endif
+# ifndef FIOSETOWN
+# define __SYS_SOCKET_H_undef_FIOSETOWN
+# endif
+# ifndef SIOCATMARK
+# define __SYS_SOCKET_H_undef_SIOCATMARK
+# endif
+# ifndef SIOCGPGRP
+# define __SYS_SOCKET_H_undef_SIOCGPGRP
+# endif
+# ifndef SIOCGSTAMP
+# define __SYS_SOCKET_H_undef_SIOCGSTAMP
+# endif
+# ifndef SIOCGSTAMPNS
+# define __SYS_SOCKET_H_undef_SIOCGSTAMPNS
+# endif
+# ifndef SIOCSPGRP
+# define __SYS_SOCKET_H_undef_SIOCSPGRP
+# endif
+#endif
/* Get socket manipulation related informations from kernel headers. */
#include <asm/socket.h>
+#if !defined __USE_MISC && !defined __USE_GNU
+# ifdef __SYS_SOCKET_H_undef_FIOGETOWN
+# undef __SYS_SOCKET_H_undef_FIOGETOWN
+# undef FIOGETOWN
+# endif
+# ifdef __SYS_SOCKET_H_undef_FIOSETOWN
+# undef __SYS_SOCKET_H_undef_FIOSETOWN
+# undef FIOSETOWN
+# endif
+# ifdef __SYS_SOCKET_H_undef_SIOCATMARK
+# undef __SYS_SOCKET_H_undef_SIOCATMARK
+# undef SIOCATMARK
+# endif
+# ifdef __SYS_SOCKET_H_undef_SIOCGPGRP
+# undef __SYS_SOCKET_H_undef_SIOCGPGRP
+# undef SIOCGPGRP
+# endif
+# ifdef __SYS_SOCKET_H_undef_SIOCGSTAMP
+# undef __SYS_SOCKET_H_undef_SIOCGSTAMP
+# undef SIOCGSTAMP
+# endif
+# ifdef __SYS_SOCKET_H_undef_SIOCGSTAMPNS
+# undef __SYS_SOCKET_H_undef_SIOCGSTAMPNS
+# undef SIOCGSTAMPNS
+# endif
+# ifdef __SYS_SOCKET_H_undef_SIOCSPGRP
+# undef __SYS_SOCKET_H_undef_SIOCSPGRP
+# undef SIOCSPGRP
+# endif
+#endif
/* Structure used to manipulate the SO_LINGER option. */
struct linger