diff options
author | jimb <jimb@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2007-10-15 20:14:17 +0000 |
---|---|---|
committer | jimb <jimb@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2007-10-15 20:14:17 +0000 |
commit | 2578d0508a978254dda6fd63a066e5383ed4a92e (patch) | |
tree | b9377779d9760df1a993a07e5a5e3833f9b9dbc3 | |
parent | a6a5dd0d5b707d7da7fce387d68dfb5de2905978 (diff) |
Merge changes between r3777 and r3809 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@3819 7b3dc134-2b1b-0410-93df-9e9f96275f8d
37 files changed, 732 insertions, 375 deletions
diff --git a/libc/ChangeLog b/libc/ChangeLog index 7ca024625..89156b949 100644 --- a/libc/ChangeLog +++ b/libc/ChangeLog @@ -1,3 +1,121 @@ +2007-10-14 Ulrich Drepper <drepper@redhat.com> + + * posix/glob.c: Reimplement link_exists_p to use fstatat64. + + * posix/glob.c: Add some branch prediction throughout. + + * nscd/nscd_getgr_r.c (nscd_getgr_r): Store result of successful + read from nscd. + + * sysdeps/posix/getaddrinfo.c (struct sort_result): Add + service_order. + (rfc3484_sort): Make sure that even if qsort doesn't support + stable sorting out sorting here is stable by comparing service_order. + (getaddrinfo): Initialize service_order. + * posix/tst-rfc3484.c (do_test): Adjust for addition of + service_order field to sorting structure. + * posix/tst-rfc3484-2.c (do_test): Likewise. + + * include/time.h: Declare __tzset_parse_tz and __tzset_compute. + * time/tzset.c (tzset_internal): Break TZ string parsing out into + __tzset_parse_tz and updating of daylight, timezone, tzname into + update_vars. + (__tz_compute): Renamed from tz_compute. Take additional parameters. + (__tz_convert): Updating of tm_isdst, tm_zone, and tm_gmtoff now + happens in __tz_compute. + * time/tzfile.c (__tzfile_read): Also read TZ string. + (find_transition): Fold into __tzfile_compute. + (__tzfile_compute): For times beyond the last transition try to + use the TZ string. + * timezone/tst-timezone.c: Information in daylight and tzname does + change for Asia/Tokyo timezone with more concrete information. + Remove the test. + + * include/stdio.h: Add libc_hidden_proto for ftello. + * libio/ftello.c: Add libc_hidden_def. + + [BZ #1140] + * time/tzfile.c (__tzfile_compute): Compute tzname[] values based + on the specified time and not the last entries in the file. Move + code to determine tzname[] to... + (find_transition): ...here. Add ugly guess for times before the + first transition. + +2007-10-13 Ulrich Drepper <drepper@redhat.com> + + [BZ #3195] + * nscd/nscd_getai.c (__nscd_getai): Set errno to 0 in case we found + no entry. + * nscd/nscd_getgr.c (nscd_getgr_r): Likewise. + * nscd/nscd_gethst_r.c (nscd_gethst_r): Likewise. + * nscd/nscd_getpw_r.c (nscd_getpw_r): Likewise. + * nscd/nscd_getserv_r.c (nscd_getserv_r): Likewise. + + * nscd/nscd_getgr_r.c (nscd_getgr_r): Optimize a bit: use simpler + read mechanism when there are no group members and avoid no-op + read syscall in this case. + + [BZ #3242] + * nscd/nscd_helper.c (wait_on_socket): Take timeout as parameter. + (__readall): If reading failed due to EAGAIN error wait a bit + and possibly try again. + (__readvall): Likewise. + +2007-10-13 Bruno Haible <bruno@clisp.org> + + * intl/dcigettext.c (_nl_find_msg): Unlock the conversions_lock + when we cannot recode the message. + +2007-10-13 Ulrich Drepper <drepper@redhat.com> + + [BZ #4359] + * libio/__freading.c (__freading): Don't return true for + write-only streams. For read/write streams, check whether we + performed a read operation already. + * libio/Makefile (tests): Add tst-ext2. + * libio/tst-ext2.c: New file. + +2007-10-12 Ulrich Drepper <drepper@redhat.com> + + * locale/programs/repertoire.c (repertoire_read): Always free + memory for repertoire file name [Coverity CID 270]. + + * elf/cache.c (save_aux_cache): Free memory allocated for + temporary file name [Coverity CID 267]. + +2007-10-12 Jakub Jelinek <jakub@redhat.com> + + * misc/Makefile (headers): Add bits/error.h. + +2007-10-12 Ulrich Drepper <drepper@redhat.com> + + * posix/fnmatch_loop.c: Take rule index returned as part of + findidx return value into account when accessing weights. + * posix/regcomp.c: Likewise. + * posix/regexec.c: Likewise. + + * locale/programs/ld-collate.c (collate_read): Optimize a bit. + (skip_to): Fix problems with parameter of elifdef/elifndef. + +2007-10-11 Ulrich Drepper <drepper@redhat.com> + + * iconv/gconv_simple.c: Add some branch prediction. + +2007-10-12 Jakub Jelinek <jakub@redhat.com> + + * locale/programs/ld-collate.c (collate_read): If ignore_content + and nowtok is tok_define, eat any tok_eol tokens. + +2007-10-11 Jakub Jelinek <jakub@redhat.com> + + * sysdeps/gnu/netinet/tcp.h: Include sys/socket.h if __USE_MISC. + (struct tcp_md5sig): Change tcpm_addr type to struct sockaddr_storage. + + * inet/netinet/in.h: Don't include bits/socket.h. + * sysdeps/unix/sysv/linux/bits/socket.h: Only check _SYS_SOCKET_H + macro. + * sysdeps/unix/bsd/bsd4.4/bits/socket.h: Likewise. + 2007-10-10 Ulrich Drepper <drepper@redhat.com> * locale/programs/locfile-token.h: Remove tok_elif, add tok_elifdef diff --git a/libc/crypt/sha512c-test.c b/libc/crypt/sha512c-test.c index 4c888feb4..410eb5c45 100644 --- a/libc/crypt/sha512c-test.c +++ b/libc/crypt/sha512c-test.c @@ -59,4 +59,5 @@ do_test (void) } #define TEST_FUNCTION do_test () +#define TIMEOUT 4 #include "../test-skeleton.c" diff --git a/libc/elf/cache.c b/libc/elf/cache.c index 9a600ea53..b8561e4b5 100644 --- a/libc/elf/cache.c +++ b/libc/elf/cache.c @@ -800,5 +800,6 @@ save_aux_cache (const char *aux_cache_name) out_fail: /* Free allocated memory. */ + free (temp_name); free (file_entries); } diff --git a/libc/iconv/gconv_simple.c b/libc/iconv/gconv_simple.c index 343c27521..ec8f38a96 100644 --- a/libc/iconv/gconv_simple.c +++ b/libc/iconv/gconv_simple.c @@ -1,5 +1,5 @@ /* Simple transformations functions. - Copyright (C) 1997-2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1997-2003, 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -880,7 +880,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step, { \ uint32_t wc = *((const uint32_t *) inptr); \ \ - if (wc < 0x80) \ + if (__builtin_expect (wc < 0x80, 1)) \ /* It's an one byte sequence. */ \ *outptr++ = (unsigned char) wc; \ else if (__builtin_expect (wc <= 0x7fffffff, 1)) \ @@ -940,21 +940,19 @@ ucs4le_internal_loop_single (struct __gconv_step *step, #define LOOPFCT FROM_LOOP #define BODY \ { \ - uint32_t ch; \ - uint_fast32_t cnt; \ - uint_fast32_t i; \ - \ /* Next input byte. */ \ - ch = *inptr; \ + uint32_t ch = *inptr; \ \ - if (ch < 0x80) \ + if (__builtin_expect (ch < 0x80, 1)) \ { \ /* One byte sequence. */ \ - cnt = 1; \ ++inptr; \ } \ else \ { \ + uint_fast32_t cnt; \ + uint_fast32_t i; \ + \ if (ch >= 0xc2 && ch < 0xe0) \ { \ /* We expect two bytes. The first byte cannot be 0xc0 or 0xc1, \ diff --git a/libc/include/stdio.h b/libc/include/stdio.h index 084c02ea1..3c1103749 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -138,6 +138,7 @@ libc_hidden_proto (rewind) libc_hidden_proto (fileno) libc_hidden_proto (fwrite) libc_hidden_proto (fseek) +libc_hidden_proto (ftello) libc_hidden_proto (fflush_unlocked) libc_hidden_proto (fread_unlocked) libc_hidden_proto (fwrite_unlocked) diff --git a/libc/include/time.h b/libc/include/time.h index ed6cb3669..e896406db 100644 --- a/libc/include/time.h +++ b/libc/include/time.h @@ -46,6 +46,9 @@ extern void __tzfile_compute (time_t timer, int use_localtime, struct tm *tp); extern void __tzfile_default (const char *std, const char *dst, long int stdoff, long int dstoff); +extern void __tzset_parse_tz (const char *tz); +extern void __tz_compute (time_t timer, struct tm *tm, int use_localtime) + __THROW internal_function; /* Subroutine of `mktime'. Return the `time_t' representation of TP and normalize TP, given that a `struct tm *' maps to a `time_t' as performed diff --git a/libc/inet/netinet/in.h b/libc/inet/netinet/in.h index 4fdc0fadf..136619831 100644 --- a/libc/inet/netinet/in.h +++ b/libc/inet/netinet/in.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1991-2001, 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1991-2001, 2003, 2004, 2006, 2007 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -211,9 +212,6 @@ extern const struct in6_addr in6addr_loopback; /* ::1 */ #define INET_ADDRSTRLEN 16 #define INET6_ADDRSTRLEN 46 -/* Get the definition of the macro to define the common sockaddr members. */ -#include <bits/socket.h> - /* Structure describing an Internet socket address. */ struct sockaddr_in diff --git a/libc/intl/dcigettext.c b/libc/intl/dcigettext.c index 1d8ed919c..74c6de634 100644 --- a/libc/intl/dcigettext.c +++ b/libc/intl/dcigettext.c @@ -978,6 +978,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) translation at all. */ if (__builtin_expect (r != __GCONV_NULCONV, 1)) { + __libc_rwlock_unlock (domain->conversions_lock); free ((char *) encoding); return NULL; } diff --git a/libc/libio/Makefile b/libc/libio/Makefile index 08af69390..a6120633b 100644 --- a/libc/libio/Makefile +++ b/libc/libio/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1995-2002,2003,2004,2006 Free Software Foundation, Inc. +# Copyright (C) 1995-2002,2003,2004,2006,2007 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -48,7 +48,7 @@ routines := \ libc_fatal fmemopen tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ - tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-fopenloc \ + tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 tst-fopenloc \ tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-sscanf \ tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof \ tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \ diff --git a/libc/libio/__freading.c b/libc/libio/__freading.c index 37200bba7..43e50bce7 100644 --- a/libc/libio/__freading.c +++ b/libc/libio/__freading.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2002, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,5 +22,6 @@ int __freading (FILE *fp) { return ((fp->_flags & _IO_NO_WRITES) - || (fp->_flags & _IO_CURRENTLY_PUTTING) == 0); + || ((fp->_flags & (_IO_CURRENTLY_PUTTING | _IO_NO_READS)) == 0 + && fp->_IO_read_base != NULL)); } diff --git a/libc/libio/ftello.c b/libc/libio/ftello.c index e58daacad..d250e55c0 100644 --- a/libc/libio/ftello.c +++ b/libc/libio/ftello.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995-2001, 2002, 2003, 2004 +/* Copyright (C) 1993, 1995-2001, 2002, 2003, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -63,3 +63,4 @@ ftello (fp) } return pos; } +libc_hidden_def (ftello) diff --git a/libc/libio/tst-ext2.c b/libc/libio/tst-ext2.c new file mode 100644 index 000000000..ed72efa0c --- /dev/null +++ b/libc/libio/tst-ext2.c @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <stdio_ext.h> + + +static char *fname; + +#define PREPARE(argc, argv) \ + do { \ + int fd = create_temp_file ("tst-ext2", &fname); \ + if (fd == -1) \ + { \ + puts ("cannot create temporary file"); \ + exit (1); \ + } \ + close (fd); \ + } while (0) + + +static int +do_test (void) +{ + int res = 0; + + FILE *fp; + + fp = fopen (fname, "w"); + printf ("Initial state for write-only stream: %d %d\n", + __freading (fp) != 0, __fwriting (fp) != 0); + res |= ((__freading (fp) != 0) != 0 + || (__fwriting (fp) != 0) != 1); + fclose (fp); + + fp = fopen (fname, "r"); + printf ("Initial state for read-only stream: %d %d\n", + __freading (fp) != 0, __fwriting (fp) != 0); + res |= ((__freading (fp) != 0) != 1 + || (__fwriting (fp) != 0) != 0); + fclose (fp); + + fp = fopen (fname, "r+"); + printf ("Initial state for read-write stream: %d %d\n", + __freading (fp) != 0, __fwriting (fp) != 0); + res |= ((__freading (fp) != 0) != 0 + || (__fwriting (fp) != 0) != 0); + fclose (fp); + + fp = fopen (fname, "w+"); + printf ("Initial state for read-write stream: %d %d\n", + __freading (fp) != 0, __fwriting (fp) != 0); + res |= ((__freading (fp) != 0) != 0 + || (__fwriting (fp) != 0) != 0); + fclose (fp); + + return res; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/libc/locale/programs/ld-collate.c b/libc/locale/programs/ld-collate.c index 67eb2b21c..9b32b9fe3 100644 --- a/libc/locale/programs/ld-collate.c +++ b/libc/locale/programs/ld-collate.c @@ -2518,13 +2518,16 @@ skip_to (struct linereader *ldfile, struct locale_collate_t *collate, if (nowtok == tok_eof || nowtok == tok_end) return nowtok; } - else if ((!to_endif && (nowtok == tok_else || nowtok == tok_elifdef - || nowtok == tok_elifndef)) - || nowtok == tok_endif) + else if (nowtok == tok_endif || (!to_endif && nowtok == tok_else)) { lr_ignore_rest (ldfile, 1); return nowtok; } + else if (!to_endif && (nowtok == tok_elifdef || nowtok == tok_elifndef)) + { + /* Do not read the rest of the line. */ + return nowtok; + } else if (nowtok == tok_else) { lr_error (ldfile, _("%s: more then one 'else'"), "LC_COLLATE"); @@ -2565,43 +2568,38 @@ collate_read (struct linereader *ldfile, struct localedef_t *result, /* The rest of the line containing `LC_COLLATE' must be free. */ lr_ignore_rest (ldfile, 1); - do - { - now = lr_token (ldfile, charmap, result, NULL, verbose); - nowtok = now->tok; - } - while (nowtok == tok_eol); - - while (nowtok == tok_define) + while (1) { - if (ignore_content) + do { - lr_ignore_rest (ldfile, 0); - continue; + now = lr_token (ldfile, charmap, result, NULL, verbose); + nowtok = now->tok; } + while (nowtok == tok_eol); - arg = lr_token (ldfile, charmap, result, NULL, verbose); - if (arg->tok != tok_ident) - SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE"); + if (nowtok != tok_define) + break; + + if (ignore_content) + lr_ignore_rest (ldfile, 0); else { - /* Simply add the new symbol. */ - struct name_list *newsym = xmalloc (sizeof (*newsym) - + arg->val.str.lenmb + 1); - memcpy (newsym->str, arg->val.str.startmb, arg->val.str.lenmb); - newsym->str[arg->val.str.lenmb] = '\0'; - newsym->next = defined; - defined = newsym; - - lr_ignore_rest (ldfile, 1); - } + arg = lr_token (ldfile, charmap, result, NULL, verbose); + if (arg->tok != tok_ident) + SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE"); + else + { + /* Simply add the new symbol. */ + struct name_list *newsym = xmalloc (sizeof (*newsym) + + arg->val.str.lenmb + 1); + memcpy (newsym->str, arg->val.str.startmb, arg->val.str.lenmb); + newsym->str[arg->val.str.lenmb] = '\0'; + newsym->next = defined; + defined = newsym; - do - { - now = lr_token (ldfile, charmap, result, NULL, verbose); - nowtok = now->tok; + lr_ignore_rest (ldfile, 1); + } } - while (nowtok == tok_eol); } if (nowtok == tok_copy) diff --git a/libc/locale/programs/repertoire.c b/libc/locale/programs/repertoire.c index cc83374c9..366580e80 100644 --- a/libc/locale/programs/repertoire.c +++ b/libc/locale/programs/repertoire.c @@ -113,8 +113,7 @@ repertoire_read (const char *filename) filename); repfile = lr_open (buf, repertoiremap_hash); - if (repfile == NULL) - free (buf); + free (buf); } } diff --git a/libc/localedata/ChangeLog b/libc/localedata/ChangeLog index 934f5d4ee..784f71d1b 100644 --- a/libc/localedata/ChangeLog +++ b/libc/localedata/ChangeLog @@ -1,3 +1,9 @@ +2007-10-14 Ulrich Drepper <drepper@redhat.com> + + [BZ #4098] + * locales/pl_PL: Change abmon, abday, and d_fmt according to + results of vote. + 2007-10-10 Ulrich Drepper <drepper@redhat.com> * locales/iso14651_t1_common: If DIACRIT_FORWARD is defined, define diff --git a/libc/localedata/locales/pl_PL b/libc/localedata/locales/pl_PL index 2f17b364f..0527eee51 100644 --- a/libc/localedata/locales/pl_PL +++ b/libc/localedata/locales/pl_PL @@ -2150,13 +2150,17 @@ grouping 0;0 END LC_NUMERIC LC_TIME -abday "<U004E>";/ - "<U0050><U006E>";/ - "<U0057><U0074>";/ - "<U015A><U0072>";/ - "<U0043><U007A>";/ - "<U0050><U0074>";/ - "<U0053><U006F>" +% The abday, abmon, and d_fmt information has been changed (back) to match +% the preference expressed in the poll organized to get some concensus. +% The results were not entirely clear on all easpects but the choices +% here seem to have the most support. For more details: +% +% https://bugzilla.redhat.com/show_bug.cgi?id=242296 +% +abday "<U006E><U0069><U0065>";"<U0070><U006F><U006E>";/ + "<U0077><U0074><U006F>";"<U015B><U0072><U006F>";/ + "<U0063><U007A><U0077>";"<U0070><U0069><U0105>";/ + "<U0073><U006F><U0062>" day "<U006E><U0069><U0065><U0064><U007A><U0069><U0065><U006C><U0061>";/ "<U0070><U006F><U006E><U0069><U0065><U0064><U007A><U0069><U0061><U0142><U0065><U006B>";/ "<U0077><U0074><U006F><U0072><U0065><U006B>";/ @@ -2164,18 +2168,12 @@ day "<U006E><U0069><U0065><U0064><U007A><U0069><U0065><U006C><U0061>";/ "<U0063><U007A><U0077><U0061><U0072><U0074><U0065><U006B>";/ "<U0070><U0069><U0105><U0074><U0065><U006B>";/ "<U0073><U006F><U0062><U006F><U0074><U0061>" -abmon "<U0049>";/ - "<U0049><U0049>";/ - "<U0049><U0049><U0049>";/ - "<U0049><U0056>";/ - "<U0056>";/ - "<U0056><U0049>";/ - "<U0056><U0049><U0049>";/ - "<U0056><U0049><U0049><U0049>";/ - "<U0049><U0058>";/ - "<U0058>";/ - "<U0058><U0049>";/ - "<U0058><U0049><U0049>" +abmon "<U0073><U0074><U0079>";"<U006C><U0075><U0074>";/ + "<U006D><U0061><U0072>";"<U006B><U0077><U0069>";/ + "<U006D><U0061><U006A>";"<U0063><U007A><U0065>";/ + "<U006C><U0069><U0070>";"<U0073><U0069><U0065>";/ + "<U0077><U0072><U007A>";"<U0070><U0061><U017A>";/ + "<U006C><U0069><U0073>";"<U0067><U0072><U0075>" mon "<U0073><U0074><U0079><U0063><U007A><U0065><U0144>";/ "<U006C><U0075><U0074><U0079>";/ "<U006D><U0061><U0072><U007A><U0065><U0063>";/ @@ -2191,7 +2189,7 @@ mon "<U0073><U0074><U0079><U0063><U007A><U0065><U0144>";/ d_t_fmt "<U0025><U0061><U002C><U0020>/ <U0025><U002D><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U002C><U0020>/ <U0025><U0054>" -d_fmt "<U0025><U002D><U0064><U0020><U0025><U0062><U0020><U0025><U0059>" +d_fmt "<U0025><U0064><U002E><U0025><U006D><U002E><U0025><U0059>" t_fmt "<U0025><U0054>" am_pm "";"" t_fmt_ampm "" diff --git a/libc/localedata/show-ucs-data.c b/libc/localedata/show-ucs-data.c index 9992ece42..85d265974 100644 --- a/libc/localedata/show-ucs-data.c +++ b/libc/localedata/show-ucs-data.c @@ -10,6 +10,13 @@ main (int argc, char *argv[]) char *line = NULL; size_t len = 0; + if (argc == 1) + { + static char *new_argv[] = { NULL, (char *) "/dev/stdin", NULL }; + argv = new_argv; + argc = 2; + } + for (n = 1; n < argc; ++n) { FILE *fp = fopen (argv[n], "r"); diff --git a/libc/misc/Makefile b/libc/misc/Makefile index 651eb621d..207cc69cd 100644 --- a/libc/misc/Makefile +++ b/libc/misc/Makefile @@ -35,7 +35,7 @@ headers := sys/uio.h bits/uio.h sys/ioctl.h bits/ioctls.h bits/ioctl-types.h \ sys/select.h ustat.h sys/ustat.h bits/ustat.h sys/sysinfo.h \ regexp.h bits/select.h bits/mman.h sys/xattr.h \ syslog.h sys/syslog.h \ - bits/syslog.h bits/syslog-ldbl.h bits/syslog-path.h + bits/syslog.h bits/syslog-ldbl.h bits/syslog-path.h bits/error.h routines := brk sbrk sstk ioctl \ readv writev \ diff --git a/libc/nscd/nscd_getai.c b/libc/nscd/nscd_getai.c index 5df32dc6d..56f963776 100644 --- a/libc/nscd/nscd_getai.c +++ b/libc/nscd/nscd_getai.c @@ -168,8 +168,8 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop) /* Store the error number. */ *h_errnop = ai_resp.error; - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); + /* Set errno to 0 to indicate no error, just no found record. */ + __set_errno (0); /* Even though we have not found anything, the result is zero. */ retval = 0; } diff --git a/libc/nscd/nscd_getgr_r.c b/libc/nscd/nscd_getgr_r.c index fc036f288..b84b06b3c 100644 --- a/libc/nscd/nscd_getgr_r.c +++ b/libc/nscd/nscd_getgr_r.c @@ -190,26 +190,37 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, /* Read the length information, group name, and password. */ if (gr_name == NULL) { - /* Allocate array to store lengths. */ - if (lensize == 0) + /* Handle a simple, usual case: no group members. */ + if (__builtin_expect (gr_resp.gr_mem_cnt == 0, 1)) { - lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t); - len = (uint32_t *) alloca (lensize); + size_t n = gr_resp.gr_name_len + gr_resp.gr_passwd_len; + if (__builtin_expect (__readall (sock, resultbuf->gr_name, n) + != (ssize_t) n, 0)) + goto out_close; + } + else + { + /* Allocate array to store lengths. */ + if (lensize == 0) + { + lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t); + len = (uint32_t *) alloca (lensize); + } + else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize) + len = extend_alloca (len, lensize, + gr_resp.gr_mem_cnt * sizeof (uint32_t)); + + vec[0].iov_base = (void *) len; + vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t); + vec[1].iov_base = resultbuf->gr_name; + vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len; + total_len = vec[0].iov_len + vec[1].iov_len; + + /* Get this data. */ + size_t n = __readvall (sock, vec, 2); + if (__builtin_expect (n != total_len, 0)) + goto out_close; } - else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize) - len = extend_alloca (len, lensize, - gr_resp.gr_mem_cnt * sizeof (uint32_t)); - - vec[0].iov_base = (void *) len; - vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t); - vec[1].iov_base = resultbuf->gr_name; - vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len; - total_len = vec[0].iov_len + vec[1].iov_len; - - /* Get this data. */ - size_t n = __readvall (sock, vec, 2); - if (__builtin_expect (n != total_len, 0)) - goto out_close; } else /* We already have the data. Just copy the group name and @@ -251,10 +262,13 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, } retval = 0; + + /* If there are no group members TOTAL_LEN is zero. */ if (gr_name == NULL) { - size_t n = __readall (sock, resultbuf->gr_mem[0], total_len); - if (__builtin_expect (n != total_len, 0)) + if (total_len > 0 + && __builtin_expect (__readall (sock, resultbuf->gr_mem[0], + total_len) != total_len, 0)) { /* The `errno' to some value != ERANGE. */ __set_errno (ENOENT); @@ -272,9 +286,9 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, if (resultbuf->gr_name[gr_name_len - 1] != '\0' || resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0' || ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt) - if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0') - break; - cnt < gr_resp.gr_mem_cnt; })) + if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0') + break; + cnt < gr_resp.gr_mem_cnt; })) { /* We cannot use the database. */ retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1; @@ -286,8 +300,8 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, } else { - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); + /* Set errno to 0 to indicate no error, just no found record. */ + __set_errno (0); /* Even though we have not found anything, the result is zero. */ retval = 0; } diff --git a/libc/nscd/nscd_gethst_r.c b/libc/nscd/nscd_gethst_r.c index 03b73a4a4..a21140475 100644 --- a/libc/nscd/nscd_gethst_r.c +++ b/libc/nscd/nscd_gethst_r.c @@ -379,8 +379,8 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type, /* Store the error number. */ *h_errnop = hst_resp.error; - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); + /* Set errno to 0 to indicate no error, just no found record. */ + __set_errno (0); /* Even though we have not found anything, the result is zero. */ retval = 0; } diff --git a/libc/nscd/nscd_getpw_r.c b/libc/nscd/nscd_getpw_r.c index b84baa1a6..21f792bb4 100644 --- a/libc/nscd/nscd_getpw_r.c +++ b/libc/nscd/nscd_getpw_r.c @@ -211,8 +211,8 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type, } else { - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); + /* Set errno to 0 to indicate no error, just no found record. */ + __set_errno (0); /* Even though we have not found anything, the result is zero. */ retval = 0; } diff --git a/libc/nscd/nscd_getserv_r.c b/libc/nscd/nscd_getserv_r.c index a725b1d3d..3cd5a2429 100644 --- a/libc/nscd/nscd_getserv_r.c +++ b/libc/nscd/nscd_getserv_r.c @@ -301,8 +301,8 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto, } else { - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); + /* Set errno to 0 to indicate no error, just no found record. */ + __set_errno (0); /* Even though we have not found anything, the result is zero. */ retval = 0; } diff --git a/libc/nscd/nscd_helper.c b/libc/nscd/nscd_helper.c index 6718d922f..866535200 100644 --- a/libc/nscd/nscd_helper.c +++ b/libc/nscd/nscd_helper.c @@ -38,6 +38,45 @@ #include "nscd-client.h" +/* Extra time we wait if the socket is still receiving data. This + value is in milliseconds. Note that the other side is nscd on the + local machine and it is already transmitting data. So the wait + time need not be long. */ +#define EXTRA_RECEIVE_TIME 200 + + +static int +wait_on_socket (int sock, long int usectmo) +{ + struct pollfd fds[1]; + fds[0].fd = sock; + fds[0].events = POLLIN | POLLERR | POLLHUP; + int n = __poll (fds, 1, usectmo); + if (n == -1 && __builtin_expect (errno == EINTR, 0)) + { + /* Handle the case where the poll() call is interrupted by a + signal. We cannot just use TEMP_FAILURE_RETRY since it might + lead to infinite loops. */ + struct timeval now; + (void) __gettimeofday (&now, NULL); + long int end = now.tv_sec * 1000 + usectmo + (now.tv_usec + 500) / 1000; + long int timeout = usectmo; + while (1) + { + n = __poll (fds, 1, timeout); + if (n != -1 || errno != EINTR) + break; + + /* Recompute the timeout time. */ + (void) __gettimeofday (&now, NULL); + timeout = end - (now.tv_sec * 1000 + (now.tv_usec + 500) / 1000); + } + } + + return n; +} + + ssize_t __readall (int fd, void *buf, size_t len) { @@ -45,9 +84,17 @@ __readall (int fd, void *buf, size_t len) ssize_t ret; do { + again: ret = TEMP_FAILURE_RETRY (__read (fd, buf, n)); if (ret <= 0) - break; + { + if (__builtin_expect (ret < 0 && errno == EAGAIN, 0) + /* The socket is still receiving data. Wait a bit more. */ + && wait_on_socket (fd, EXTRA_RECEIVE_TIME) > 0) + goto again; + + break; + } buf = (char *) buf + ret; n -= ret; } @@ -61,7 +108,15 @@ __readvall (int fd, const struct iovec *iov, int iovcnt) { ssize_t ret = TEMP_FAILURE_RETRY (__readv (fd, iov, iovcnt)); if (ret <= 0) - return ret; + { + if (__builtin_expect (ret == 0 || errno != EAGAIN, 1)) + /* A genuine error or no data to read. */ + return ret; + + /* The data has not all yet been received. Do as if we have not + read anything yet. */ + ret = 0; + } size_t total = 0; for (int i = 0; i < iovcnt; ++i) @@ -83,9 +138,17 @@ __readvall (int fd, const struct iovec *iov, int iovcnt) } iovp->iov_base = (char *) iovp->iov_base + r; iovp->iov_len -= r; + again: r = TEMP_FAILURE_RETRY (__readv (fd, iovp, iovcnt)); if (r <= 0) - break; + { + if (__builtin_expect (r < 0 && errno == EAGAIN, 0) + /* The socket is still receiving data. Wait a bit more. */ + && wait_on_socket (fd, EXTRA_RECEIVE_TIME) > 0) + goto again; + + break; + } ret += r; } while (ret < total); @@ -187,36 +250,6 @@ __nscd_unmap (struct mapped_database *mapped) } -static int -wait_on_socket (int sock) -{ - struct pollfd fds[1]; - fds[0].fd = sock; - fds[0].events = POLLIN | POLLERR | POLLHUP; - int n = __poll (fds, 1, 5 * 1000); - if (n == -1 && __builtin_expect (errno == EINTR, 0)) - { - /* Handle the case where the poll() call is interrupted by a - signal. We cannot just use TEMP_FAILURE_RETRY since it might - lead to infinite loops. */ - struct timeval now; - (void) __gettimeofday (&now, NULL); - long int end = (now.tv_sec + 5) * 1000 + (now.tv_usec + 500) / 1000; - while (1) - { - long int timeout = end - (now.tv_sec * 1000 - + (now.tv_usec + 500) / 1000); - n = __poll (fds, 1, timeout); - if (n != -1 || errno != EINTR) - break; - (void) __gettimeofday (&now, NULL); - } - } - - return n; -} - - /* Try to get a file descriptor for the shared meory segment containing the database. */ static struct mapped_database * @@ -265,7 +298,7 @@ get_mapping (request_type type, const char *key, msg.msg_controllen = cmsg->cmsg_len; - if (wait_on_socket (sock) <= 0) + if (wait_on_socket (sock, 5 * 1000) <= 0) goto out_close2; # ifndef MSG_CMSG_CLOEXEC @@ -497,7 +530,7 @@ __nscd_open_socket (const char *key, size_t keylen, request_type type, if (sock >= 0) { /* Wait for data. */ - if (wait_on_socket (sock) > 0) + if (wait_on_socket (sock, 5 * 1000) > 0) { ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, response, responselen)); diff --git a/libc/posix/fnmatch_loop.c b/libc/posix/fnmatch_loop.c index 2bdd83718..67c0ee4ab 100644 --- a/libc/posix/fnmatch_loop.c +++ b/libc/posix/fnmatch_loop.c @@ -1,5 +1,5 @@ -/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2003,2004,2005, - 2007 Free Software Foundation, Inc. +/* Copyright (C) 1991-1993,1996-2001,2003-2005,2007 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -418,15 +418,20 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends) /* We found a table entry. Now see whether the character we are currently at has the same equivalance class value. */ - int len = weights[idx]; + int len = weights[idx & 0xffffff]; int32_t idx2; const UCHAR *np = (const UCHAR *) n; idx2 = findidx (&np); - if (idx2 != 0 && len == weights[idx2]) + if (idx2 != 0 + && (idx >> 24) == (idx2 >> 24) + && len == weights[idx2 & 0xffffff]) { int cnt = 0; + idx &= 0xffffff; + idx2 &= 0xffffff; + while (cnt < len && (weights[idx + 1 + cnt] == weights[idx2 + 1 + cnt])) diff --git a/libc/posix/glob.c b/libc/posix/glob.c index fb2cb49ae..4687f9e7a 100644 --- a/libc/posix/glob.c +++ b/libc/posix/glob.c @@ -776,7 +776,7 @@ glob (pattern, flags, errfunc, pglob) /* Return the directory if we don't check for error or if it exists. */ if ((flags & GLOB_NOCHECK) - || (((flags & GLOB_ALTDIRFUNC) + || (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)) ? ((*pglob->gl_stat) (dirname, &st) == 0 && S_ISDIR (st.st_mode)) : (__stat64 (dirname, &st64) == 0 && S_ISDIR (st64.st_mode))))) @@ -848,7 +848,7 @@ glob (pattern, flags, errfunc, pglob) *(char *) &dirname[--dirlen] = '\0'; } - if ((flags & GLOB_ALTDIRFUNC) != 0) + if (__builtin_expect ((flags & GLOB_ALTDIRFUNC) != 0, 0)) { /* Use the alternative access functions also in the recursive call. */ @@ -1032,7 +1032,7 @@ glob (pattern, flags, errfunc, pglob) struct_stat64 st64; for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i) - if (((flags & GLOB_ALTDIRFUNC) + if ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) ? ((*pglob->gl_stat) (pglob->gl_pathv[i], &st) == 0 && S_ISDIR (st.st_mode)) : (__stat64 (pglob->gl_pathv[i], &st64) == 0 @@ -1224,21 +1224,42 @@ weak_alias (__glob_pattern_p, glob_pattern_p) allocated with alloca to be recycled. */ #if !defined _LIBC || !defined GLOB_ONLY_P static int -link_exists_p (const char *dir, size_t dirlen, const char *fname, - glob_t *pglob, int flags) +__attribute_noinline__ +link_exists2_p (const char *dir, size_t dirlen, const char *fname, + glob_t *pglob +# ifndef _LIBC + , int flags +# endif + ) { size_t fnamelen = strlen (fname); char *fullname = (char *) __alloca (dirlen + 1 + fnamelen + 1); struct stat st; +# ifndef _LIBC struct_stat64 st64; +# endif mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1), fname, fnamelen + 1); - return (((flags & GLOB_ALTDIRFUNC) +# ifdef _LIBC + return (*pglob->gl_stat) (fullname, &st) == 0; +# else + return ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) ? (*pglob->gl_stat) (fullname, &st) : __stat64 (fullname, &st64)) == 0); +# endif } +# ifdef _LIBC +# define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \ + (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) \ + ? link_exists2_p (dirname, dirnamelen, fname, pglob) \ + : ({ struct stat64 st64; \ + __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0) == 0; })) +# else +# define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \ + link_exists2_p (dirname, dirnamelen, fname, pglob, flags) +# endif #endif @@ -1292,7 +1313,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), "/", 1), pattern, patlen + 1); - if (((flags & GLOB_ALTDIRFUNC) + if ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) ? (*pglob->gl_stat) (fullname, &st) : __stat64 (fullname, &st64)) == 0) /* We found this file to be existing. Now tell the rest @@ -1301,7 +1322,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, } else { - stream = ((flags & GLOB_ALTDIRFUNC) + stream = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) ? (*pglob->gl_opendir) (directory) : opendir (directory)); if (stream == NULL) @@ -1313,6 +1334,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags, } else { +#ifdef _LIBC + int dfd = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) + ? -1 : dirfd ((DIR *) stream)); +#endif int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) #if defined _AMIGA || defined VMS @@ -1335,7 +1360,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, } d64buf; - if (flags & GLOB_ALTDIRFUNC) + if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)) { struct dirent *d32 = (*pglob->gl_readdir) (stream); if (d32 != NULL) @@ -1349,7 +1374,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, else d = __readdir64 (stream); #else - struct dirent *d = ((flags & GLOB_ALTDIRFUNC) + struct dirent *d = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) ? ((struct dirent *) (*pglob->gl_readdir) (stream)) : __readdir (stream)); @@ -1371,7 +1396,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, /* If the file we found is a symlink we have to make sure the target file exists. */ if (!DIRENT_MIGHT_BE_SYMLINK (d) - || link_exists_p (directory, dirlen, name, pglob, + || link_exists_p (dfd, directory, dirlen, name, pglob, flags)) { if (cur == names->count) @@ -1487,7 +1512,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, if (stream != NULL) { save = errno; - if (flags & GLOB_ALTDIRFUNC) + if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)) (*pglob->gl_closedir) (stream); else closedir (stream); diff --git a/libc/posix/regcomp.c b/libc/posix/regcomp.c index 129546c32..4cf168821 100644 --- a/libc/posix/regcomp.c +++ b/libc/posix/regcomp.c @@ -3378,7 +3378,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) /* Build single byte matcing table for this equivalence class. */ char_buf[1] = (unsigned char) '\0'; - len = weights[idx1]; + len = weights[idx1 & 0xffffff]; for (ch = 0; ch < SBC_MAX; ++ch) { char_buf[0] = ch; @@ -3390,11 +3390,15 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) if (idx2 == 0) /* This isn't a valid character. */ continue; - if (len == weights[idx2]) + /* Compare only if the length matches and the collation rule + index is the same. */ + if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24)) { int cnt = 0; + while (cnt <= len && - weights[idx1 + 1 + cnt] == weights[idx2 + 1 + cnt]) + weights[(idx1 & 0xffffff) + 1 + cnt] + == weights[(idx2 & 0xffffff) + 1 + cnt]) ++cnt; if (cnt > len) diff --git a/libc/posix/regexec.c b/libc/posix/regexec.c index bdfa3550a..135efe744 100644 --- a/libc/posix/regexec.c +++ b/libc/posix/regexec.c @@ -1,5 +1,5 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. @@ -3825,7 +3825,6 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx, const int32_t *table, *indirect; const unsigned char *weights, *extra; const char *collseqwc; - int32_t idx; /* This #include defines a local function! */ # include <locale/weight.h> @@ -3883,15 +3882,20 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx, _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); - idx = findidx (&cp); + int32_t idx = findidx (&cp); if (idx > 0) for (i = 0; i < cset->nequiv_classes; ++i) { int32_t equiv_class_idx = cset->equiv_classes[i]; - size_t weight_len = weights[idx]; - if (weight_len == weights[equiv_class_idx]) + size_t weight_len = weights[idx & 0xffffff]; + if (weight_len == weights[equiv_class_idx & 0xffffff] + && (idx >> 24) == (equiv_class_idx >> 24)) { int cnt = 0; + + idx &= 0xffffff; + equiv_class_idx &= 0xffffff; + while (cnt <= weight_len && (weights[equiv_class_idx + 1 + cnt] == weights[idx + 1 + cnt])) diff --git a/libc/posix/tst-rfc3484-2.c b/libc/posix/tst-rfc3484-2.c index ae802c065..f318523ed 100644 --- a/libc/posix/tst-rfc3484-2.c +++ b/libc/posix/tst-rfc3484-2.c @@ -98,12 +98,14 @@ do_test (void) results[0].got_source_addr = true; results[0].source_addr_len = sizeof (so1); results[0].source_addr_flags = 0; + results[0].service_order = 0; memcpy (&results[0].source_addr, &so1, sizeof (so1)); results[1].dest_addr = &ai2; results[1].got_source_addr = true; results[1].source_addr_len = sizeof (so2); results[1].source_addr_flags = 0; + results[1].service_order = 1; memcpy (&results[1].source_addr, &so2, sizeof (so2)); @@ -122,12 +124,14 @@ do_test (void) results[1].got_source_addr = true; results[1].source_addr_len = sizeof (so1); results[1].source_addr_flags = 0; + results[1].service_order = 1; memcpy (&results[1].source_addr, &so1, sizeof (so1)); results[0].dest_addr = &ai2; results[0].got_source_addr = true; results[0].source_addr_len = sizeof (so2); results[0].source_addr_flags = 0; + results[0].service_order = 0; memcpy (&results[0].source_addr, &so2, sizeof (so2)); diff --git a/libc/posix/tst-rfc3484.c b/libc/posix/tst-rfc3484.c index 352a7579a..08d57a66e 100644 --- a/libc/posix/tst-rfc3484.c +++ b/libc/posix/tst-rfc3484.c @@ -93,6 +93,7 @@ do_test (void) memcpy(&results[i].source_addr, &so, sizeof (so)); results[i].source_addr_len = sizeof (so); results[i].source_addr_flags = 0; + results[i].service_order = i; } qsort (results, naddrs, sizeof (results[0]), rfc3484_sort); diff --git a/libc/sysdeps/gnu/netinet/tcp.h b/libc/sysdeps/gnu/netinet/tcp.h index 2ab2909f2..06e8414b5 100644 --- a/libc/sysdeps/gnu/netinet/tcp.h +++ b/libc/sysdeps/gnu/netinet/tcp.h @@ -54,6 +54,7 @@ #ifdef __USE_MISC # include <sys/types.h> +# include <sys/socket.h> # ifdef __FAVOR_BSD typedef u_int32_t tcp_seq; @@ -233,7 +234,7 @@ struct tcp_info struct tcp_md5sig { - struct __kernel_sockaddr_storage tcpm_addr; /* Address associated. */ + struct sockaddr_storage tcpm_addr; /* Address associated. */ u_int16_t __tcpm_pad1; /* Zero. */ u_int16_t tcpm_keylen; /* Key length. */ u_int32_t __tcpm_pad2; /* Zero. */ diff --git a/libc/sysdeps/posix/getaddrinfo.c b/libc/sysdeps/posix/getaddrinfo.c index 221b41dd0..8f37ec5c1 100644 --- a/libc/sysdeps/posix/getaddrinfo.c +++ b/libc/sysdeps/posix/getaddrinfo.c @@ -1002,6 +1002,7 @@ struct sort_result { struct addrinfo *dest_addr; struct sockaddr_storage source_addr; + size_t service_order; uint8_t source_addr_len; bool got_source_addr; uint8_t source_addr_flags; @@ -1403,8 +1404,11 @@ rfc3484_sort (const void *p1, const void *p2) } - /* Rule 10: Otherwise, leave the order unchanged. */ - return 0; + /* Rule 10: Otherwise, leave the order unchanged. To ensure this + compare with the value indicating the order in which the entries + have been received from the services. NB: no two entries can have + the same order so the test will never return zero. */ + return a1->service_order < a2->service_order ? -1 : 1; } @@ -1951,6 +1955,7 @@ getaddrinfo (const char *name, const char *service, { results[i].dest_addr = q; results[i].got_source_addr = false; + results[i].service_order = i; /* If we just looked up the address for a different protocol, reuse the result. */ diff --git a/libc/sysdeps/unix/bsd/bsd4.4/bits/socket.h b/libc/sysdeps/unix/bsd/bsd4.4/bits/socket.h index f74603f94..67db4d846 100644 --- a/libc/sysdeps/unix/bsd/bsd4.4/bits/socket.h +++ b/libc/sysdeps/unix/bsd/bsd4.4/bits/socket.h @@ -20,7 +20,7 @@ #ifndef __BITS_SOCKET_H #define __BITS_SOCKET_H 1 -#if !defined _SYS_SOCKET_H && !defined _NETINET_IN_H +#ifndef _SYS_SOCKET_H # error "Never include <bits/socket.h> directly; use <sys/socket.h> instead." #endif diff --git a/libc/sysdeps/unix/sysv/linux/bits/socket.h b/libc/sysdeps/unix/sysv/linux/bits/socket.h index 89a9106b2..11bb607d0 100644 --- a/libc/sysdeps/unix/sysv/linux/bits/socket.h +++ b/libc/sysdeps/unix/sysv/linux/bits/socket.h @@ -21,7 +21,7 @@ #ifndef __BITS_SOCKET_H #define __BITS_SOCKET_H -#if !defined _SYS_SOCKET_H && !defined _NETINET_IN_H +#ifndef _SYS_SOCKET_H # error "Never include <bits/socket.h> directly; use <sys/socket.h> instead." #endif diff --git a/libc/time/tzfile.c b/libc/time/tzfile.c index 0d48c8ca0..44d661477 100644 --- a/libc/time/tzfile.c +++ b/libc/time/tzfile.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-1993,1995-2001,2003,2004,2006 +/* Copyright (C) 1991-1993,1995-2001,2003,2004,2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -50,7 +50,6 @@ struct leap long int change; /* Seconds of correction to apply. */ }; -static struct ttinfo *find_transition (time_t timer) internal_function; static void compute_tzname_max (size_t) internal_function; static size_t num_transitions; @@ -63,6 +62,7 @@ static long int rule_stdoff; static long int rule_dstoff; static size_t num_leaps; static struct leap *leaps; +static char *tzspec; #include <endian.h> #include <byteswap.h> @@ -114,6 +114,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) size_t leaps_idx; int was_using_tzfile = __use_tzfile; int trans_width = 4; + size_t tzspec_len; if (sizeof (time_t) != 4 && sizeof (time_t) != 8) abort (); @@ -242,10 +243,18 @@ __tzfile_read (const char *file, size_t extra, char **extrap) & ~(__alignof__ (struct leap) - 1)); leaps_idx = total_size; total_size += num_leaps * sizeof (struct leap); + tzspec_len = (trans_width == 8 + ? st.st_size - (ftello (f) + + num_transitions * (8 + 1) + + num_types * 6 + + chars + + num_leaps * 8 + + num_isstd + + num_isgmt) - 1 : 0); /* Allocate enough memory including the extra block requested by the caller. */ - transitions = (time_t *) malloc (total_size + extra); + transitions = (time_t *) malloc (total_size + tzspec_len + extra); if (transitions == NULL) goto lose; @@ -254,6 +263,10 @@ __tzfile_read (const char *file, size_t extra, char **extrap) types = (struct ttinfo *) ((char *) transitions + types_idx); zone_names = (char *) types + num_types * sizeof (struct ttinfo); leaps = (struct leap *) ((char *) transitions + leaps_idx); + if (trans_width == 8) + tzspec = (char *) leaps + num_leaps * sizeof (struct leap); + else + tzspec = NULL; if (extra > 0) *extrap = (char *) &leaps[num_leaps]; @@ -357,11 +370,16 @@ __tzfile_read (const char *file, size_t extra, char **extrap) while (i < num_types) types[i++].isgmt = 0; - /* XXX When a version 2 file is available it can contain a POSIX TZ-style - formatted string which specifies how times past the last one specified - are supposed to be handled. We might want to handle this at some - point. But it might be overhead since most/all? files have an - open-ended last entry. */ + /* Read the POSIX TZ-style information if possible. */ + if (tzspec != NULL) + { + /* Skip over the newline first. */ + if (getc_unlocked (f) != '\n' + || fread_unlocked (tzspec, 1, tzspec_len - 1, f) != tzspec_len - 1) + tzspec = NULL; + else + tzspec[tzspec_len - 1] = '\0'; + } fclose (f); @@ -531,111 +549,151 @@ __tzfile_default (const char *std, const char *dst, compute_tzname_max (stdlen + dstlen); } -static struct ttinfo * -internal_function -find_transition (time_t timer) +void +__tzfile_compute (time_t timer, int use_localtime, + long int *leap_correct, int *leap_hit, + struct tm *tp) { - size_t i; + register size_t i; - if (num_transitions == 0 || timer < transitions[0]) - { - /* TIMER is before any transition (or there are no transitions). - Choose the first non-DST type - (or the first if they're all DST types). */ - i = 0; - while (i < num_types && types[i].isdst) - ++i; - if (i == num_types) - i = 0; - } - else if (timer >= transitions[num_transitions - 1]) - i = type_idxs[num_transitions - 1]; - else + if (use_localtime) { - /* Find the first transition after TIMER, and - then pick the type of the transition before it. */ - size_t lo = 0; - size_t hi = num_transitions - 1; - /* Assume that DST is changing twice a year and guess initial - search spot from it. - Half of a gregorian year has on average 365.2425 * 86400 / 2 - = 15778476 seconds. */ - i = (transitions[num_transitions - 1] - timer) / 15778476; - if (i < num_transitions) + __tzname[0] = NULL; + __tzname[1] = NULL; + + if (num_transitions == 0 || timer < transitions[0]) { - i = num_transitions - 1 - i; - if (timer < transitions[i]) + /* TIMER is before any transition (or there are no transitions). + Choose the first non-DST type + (or the first if they're all DST types). */ + i = 0; + while (i < num_types && types[i].isdst) { - if (i < 10 || timer >= transitions[i - 10]) - { - /* Linear search. */ - while (timer < transitions[i - 1]) - --i; - goto found; - } - hi = i - 10; + if (__tzname[1] == NULL) + __tzname[1] = __tzstring (&zone_names[types[i].idx]); + + ++i; } - else + + if (i == num_types) + i = 0; + __tzname[0] = __tzstring (&zone_names[types[i].idx]); + if (__tzname[1] == NULL) { - if (i + 10 >= num_transitions || timer < transitions[i + 10]) - { - /* Linear search. */ - while (timer >= transitions[i]) - ++i; - goto found; - } - lo = i + 10; + size_t j = i; + while (j < num_types) + if (types[j].isdst) + { + __tzname[1] = __tzstring (&zone_names[types[j].idx]); + break; + } + else + ++j; } } - - /* Binary search. */ - /* assert (timer >= transitions[lo] && timer < transitions[hi]); */ - while (lo + 1 < hi) + else if (timer >= transitions[num_transitions - 1]) { - i = (lo + hi) / 2; - if (timer < transitions[i]) - hi = i; - else - lo = i; - } - i = hi; + if (tzspec == NULL) + { + use_last: + i = num_transitions - 1; + goto found; + } - found: - /* assert (timer >= transitions[i - 1] && timer < transitions[i]); */ - i = type_idxs[i - 1]; - } + /* Parse the POSIX TZ-style string. */ + __tzset_parse_tz (tzspec); - return &types[i]; -} - -void -__tzfile_compute (time_t timer, int use_localtime, - long int *leap_correct, int *leap_hit, - struct tm *tp) -{ - register size_t i; + /* Convert to broken down structure. If this fails do not + use the string. */ + if (! __offtime (&timer, 0, tp)) + goto use_last; - if (use_localtime) - { - struct ttinfo *info = find_transition (timer); - __daylight = rule_stdoff != rule_dstoff; - __timezone = -rule_stdoff; - __tzname[0] = NULL; - __tzname[1] = NULL; - for (i = num_transitions; i > 0; ) + /* Use the rules from the TZ string to compute the change. */ + __tz_compute (timer, tp, 1); + + *leap_correct = 0L; + *leap_hit = 0; + return; + } + else { - int type = type_idxs[--i]; - int dst = types[type].isdst; - int idx = types[type].idx; + /* Find the first transition after TIMER, and + then pick the type of the transition before it. */ + size_t lo = 0; + size_t hi = num_transitions - 1; + /* Assume that DST is changing twice a year and guess initial + search spot from it. + Half of a gregorian year has on average 365.2425 * 86400 / 2 + = 15778476 seconds. */ + i = (transitions[num_transitions - 1] - timer) / 15778476; + if (i < num_transitions) + { + i = num_transitions - 1 - i; + if (timer < transitions[i]) + { + if (i < 10 || timer >= transitions[i - 10]) + { + /* Linear search. */ + while (timer < transitions[i - 1]) + --i; + goto found; + } + hi = i - 10; + } + else + { + if (i + 10 >= num_transitions || timer < transitions[i + 10]) + { + /* Linear search. */ + while (timer >= transitions[i]) + ++i; + goto found; + } + lo = i + 10; + } + } - if (__tzname[dst] == NULL) + /* Binary search. */ + /* assert (timer >= transitions[lo] && timer < transitions[hi]); */ + while (lo + 1 < hi) + { + i = (lo + hi) / 2; + if (timer < transitions[i]) + hi = i; + else + lo = i; + } + i = hi; + + found: + /* assert (timer >= transitions[i - 1] && timer < transitions[i]); */ + __tzname[types[type_idxs[i - 1]].isdst] + = __tzstring (&zone_names[types[type_idxs[i - 1]].idx]); + size_t j = i; + while (j < num_transitions) { - __tzname[dst] = __tzstring (&zone_names[idx]); + int type = type_idxs[j]; + int dst = types[type].isdst; + int idx = types[type].idx; + + if (__tzname[dst] == NULL) + { + __tzname[dst] = __tzstring (&zone_names[idx]); + + if (__tzname[1 - dst] != NULL) + break; + } - if (__tzname[1 - dst] != NULL) - break; + ++j; } + + i = type_idxs[i - 1]; } + + struct ttinfo *info = &types[i]; + __daylight = rule_stdoff != rule_dstoff; + __timezone = -rule_stdoff; + if (__tzname[0] == NULL) { /* This should only happen if there are no transition rules. @@ -647,7 +705,8 @@ __tzfile_compute (time_t timer, int use_localtime, /* There is no daylight saving time. */ __tzname[1] = __tzname[0]; tp->tm_isdst = info->isdst; - tp->tm_zone = __tzstring (&zone_names[info->idx]); + assert (strcmp (&zone_names[info->idx], __tzname[tp->tm_isdst]) == 0); + tp->tm_zone = __tzname[tp->tm_isdst]; tp->tm_gmtoff = info->offset; } diff --git a/libc/time/tzset.c b/libc/time/tzset.c index 0479abb38..27efef0f7 100644 --- a/libc/time/tzset.c +++ b/libc/time/tzset.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2002,2003,2004 Free Software Foundation, Inc. +/* Copyright (C) 1991-2002,2003,2004,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -70,7 +70,6 @@ static tz_rule tz_rules[2]; static void compute_change (tz_rule *rule, int year) __THROW internal_function; -static void tz_compute (const struct tm *tm) __THROW internal_function; static void tzset_internal (int always, int explicit) __THROW internal_function; @@ -92,7 +91,7 @@ __tzstring (const char *s) { char *p; struct tzstring_l *t, *u, *new; - size_t len = strlen(s); + size_t len = strlen (s); /* Walk the list and look for a match. If this string is the same as the end of an already-allocated string, it can share space. */ @@ -140,80 +139,34 @@ __tzname_max () static char *old_tz; -/* Interpret the TZ envariable. */ static void internal_function -tzset_internal (always, explicit) - int always; - int explicit; +update_vars (void) +{ + __daylight = tz_rules[0].offset != tz_rules[1].offset; + __timezone = -tz_rules[0].offset; + __tzname[0] = (char *) tz_rules[0].name; + __tzname[1] = (char *) tz_rules[1].name; + + /* Keep __tzname_cur_max up to date. */ + size_t len0 = strlen (__tzname[0]); + size_t len1 = strlen (__tzname[1]); + if (len0 > __tzname_cur_max) + __tzname_cur_max = len0; + if (len1 > __tzname_cur_max) + __tzname_cur_max = len1; +} + +/* Parse the POSIX TZ-style string. */ +void +__tzset_parse_tz (tz) + const char *tz; { - static int is_initialized; - register const char *tz; register size_t l; char *tzbuf; unsigned short int hh, mm, ss; unsigned short int whichrule; - if (is_initialized && !always) - return; - is_initialized = 1; - - /* Examine the TZ environment variable. */ - tz = getenv ("TZ"); - if (tz == NULL && !explicit) - /* Use the site-wide default. This is a file name which means we - would not see changes to the file if we compare only the file - name for change. We want to notice file changes if tzset() has - been called explicitly. Leave TZ as NULL in this case. */ - tz = TZDEFAULT; - if (tz && *tz == '\0') - /* User specified the empty string; use UTC explicitly. */ - tz = "Universal"; - - /* A leading colon means "implementation defined syntax". - We ignore the colon and always use the same algorithm: - try a data file, and if none exists parse the 1003.1 syntax. */ - if (tz && *tz == ':') - ++tz; - - /* Check whether the value changes since the last run. */ - if (old_tz != NULL && tz != NULL && strcmp (tz, old_tz) == 0) - /* No change, simply return. */ - return; - - if (tz == NULL) - /* No user specification; use the site-wide default. */ - tz = TZDEFAULT; - - tz_rules[0].name = NULL; - tz_rules[1].name = NULL; - - /* Save the value of `tz'. */ - if (old_tz != NULL) - free (old_tz); - old_tz = tz ? __strdup (tz) : NULL; - - /* Try to read a data file. */ - __tzfile_read (tz, 0, NULL); - if (__use_tzfile) - return; - - /* No data file found. Default to UTC if nothing specified. */ - - if (tz == NULL || *tz == '\0' - || (TZDEFAULT != NULL && strcmp (tz, TZDEFAULT) == 0)) - { - tz_rules[0].name = tz_rules[1].name = "UTC"; - tz_rules[0].type = tz_rules[1].type = J0; - tz_rules[0].m = tz_rules[0].n = tz_rules[0].d = 0; - tz_rules[1].m = tz_rules[1].n = tz_rules[1].d = 0; - tz_rules[0].secs = tz_rules[1].secs = 0; - tz_rules[0].offset = tz_rules[1].offset = 0L; - tz_rules[0].change = tz_rules[1].change = (time_t) -1; - tz_rules[0].computed_for = tz_rules[1].computed_for = 0; - goto out; - } - /* Clear out old state and reset to unnamed UTC. */ memset (tz_rules, 0, sizeof tz_rules); tz_rules[0].name = tz_rules[1].name = ""; @@ -413,20 +366,81 @@ tzset_internal (always, explicit) } out: - __daylight = tz_rules[0].offset != tz_rules[1].offset; - __timezone = -tz_rules[0].offset; - __tzname[0] = (char *) tz_rules[0].name; - __tzname[1] = (char *) tz_rules[1].name; + update_vars (); +} - { - /* Keep __tzname_cur_max up to date. */ - size_t len0 = strlen (__tzname[0]); - size_t len1 = strlen (__tzname[1]); - if (len0 > __tzname_cur_max) - __tzname_cur_max = len0; - if (len1 > __tzname_cur_max) - __tzname_cur_max = len1; - } +/* Interpret the TZ envariable. */ +static void +internal_function +tzset_internal (always, explicit) + int always; + int explicit; +{ + static int is_initialized; + register const char *tz; + + if (is_initialized && !always) + return; + is_initialized = 1; + + /* Examine the TZ environment variable. */ + tz = getenv ("TZ"); + if (tz == NULL && !explicit) + /* Use the site-wide default. This is a file name which means we + would not see changes to the file if we compare only the file + name for change. We want to notice file changes if tzset() has + been called explicitly. Leave TZ as NULL in this case. */ + tz = TZDEFAULT; + if (tz && *tz == '\0') + /* User specified the empty string; use UTC explicitly. */ + tz = "Universal"; + + /* A leading colon means "implementation defined syntax". + We ignore the colon and always use the same algorithm: + try a data file, and if none exists parse the 1003.1 syntax. */ + if (tz && *tz == ':') + ++tz; + + /* Check whether the value changes since the last run. */ + if (old_tz != NULL && tz != NULL && strcmp (tz, old_tz) == 0) + /* No change, simply return. */ + return; + + if (tz == NULL) + /* No user specification; use the site-wide default. */ + tz = TZDEFAULT; + + tz_rules[0].name = NULL; + tz_rules[1].name = NULL; + + /* Save the value of `tz'. */ + if (old_tz != NULL) + free (old_tz); + old_tz = tz ? __strdup (tz) : NULL; + + /* Try to read a data file. */ + __tzfile_read (tz, 0, NULL); + if (__use_tzfile) + return; + + /* No data file found. Default to UTC if nothing specified. */ + + if (tz == NULL || *tz == '\0' + || (TZDEFAULT != NULL && strcmp (tz, TZDEFAULT) == 0)) + { + tz_rules[0].name = tz_rules[1].name = "UTC"; + tz_rules[0].type = tz_rules[1].type = J0; + tz_rules[0].m = tz_rules[0].n = tz_rules[0].d = 0; + tz_rules[1].m = tz_rules[1].n = tz_rules[1].d = 0; + tz_rules[0].secs = tz_rules[1].secs = 0; + tz_rules[0].offset = tz_rules[1].offset = 0L; + tz_rules[0].change = tz_rules[1].change = (time_t) -1; + tz_rules[0].computed_for = tz_rules[1].computed_for = 0; + update_vars (); + return; + } + + __tzset_parse_tz (tz); } /* Figure out the exact time (as a time_t) in YEAR @@ -523,13 +537,34 @@ compute_change (rule, year) /* Figure out the correct timezone for TM and set `__tzname', `__timezone', and `__daylight' accordingly. */ -static void +void internal_function -tz_compute (tm) - const struct tm *tm; +__tz_compute (timer, tm, use_localtime) + time_t timer; + struct tm *tm; + int use_localtime; { compute_change (&tz_rules[0], 1900 + tm->tm_year); compute_change (&tz_rules[1], 1900 + tm->tm_year); + + if (use_localtime) + { + int isdst; + + /* We have to distinguish between northern and southern + hemisphere. For the latter the daylight saving time + ends in the next year. */ + if (__builtin_expect (tz_rules[0].change + > tz_rules[1].change, 0)) + isdst = (timer < tz_rules[1].change + || timer >= tz_rules[0].change); + else + isdst = (timer >= tz_rules[0].change + && timer < tz_rules[1].change); + tm->tm_isdst = isdst; + tm->tm_zone = __tzname[isdst]; + tm->tm_gmtoff = tz_rules[isdst].offset; + } } /* Reinterpret the TZ environment variable and set `tzname'. */ @@ -583,35 +618,14 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp) if (! __offtime (timer, 0, tp)) tp = NULL; else - tz_compute (tp); + __tz_compute (*timer, tp, use_localtime); leap_correction = 0L; leap_extra_secs = 0; } if (tp) { - if (use_localtime) - { - if (!__use_tzfile) - { - int isdst; - - /* We have to distinguish between northern and southern - hemisphere. For the latter the daylight saving time - ends in the next year. */ - if (__builtin_expect (tz_rules[0].change - > tz_rules[1].change, 0)) - isdst = (*timer < tz_rules[1].change - || *timer >= tz_rules[0].change); - else - isdst = (*timer >= tz_rules[0].change - && *timer < tz_rules[1].change); - tp->tm_isdst = isdst; - tp->tm_zone = __tzname[isdst]; - tp->tm_gmtoff = tz_rules[isdst].offset; - } - } - else + if (! use_localtime) { tp->tm_isdst = 0; tp->tm_zone = "GMT"; diff --git a/libc/timezone/tst-timezone.c b/libc/timezone/tst-timezone.c index 4c879163c..00f899b85 100644 --- a/libc/timezone/tst-timezone.c +++ b/libc/timezone/tst-timezone.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2000, 2005 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2000, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 1998. @@ -44,7 +44,6 @@ static const struct test_times tests[] = { "America/Chicago", 1, 21600, {"CST", "CDT" }}, { "America/Indiana/Indianapolis", 1, 18000, {"EST", "EDT" }}, { "America/Los_Angeles", 1, 28800, {"PST", "PDT" }}, - { "Asia/Tokyo", 1, -32400, {"JST", "JDT" }}, { "Pacific/Auckland", 1, -43200, { "NZST", "NZDT" }}, { NULL, 0, 0 } }; |