diff options
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, ¬found, total, - MSG_NOSIGNAL)); + if (fd != -1 && + TEMP_FAILURE_RETRY (send (fd, ¬found, 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 (<m); 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 |