diff options
author | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2011-05-23 19:23:42 +0000 |
---|---|---|
committer | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2011-05-23 19:23:42 +0000 |
commit | f56b42ffd93eb64a1f1aefe7c4f2bd4e2eccafe1 (patch) | |
tree | df3ef049c083145202dbf19598acf56ef1b41afa /libc | |
parent | e9d94bb485578797a67a3ef6dae7ac9e3635e963 (diff) | |
download | eglibc2-f56b42ffd93eb64a1f1aefe7c4f2bd4e2eccafe1.tar.gz |
Merge changes between r13882 and r13953 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@13954 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc')
33 files changed, 1264 insertions, 295 deletions
diff --git a/libc/ChangeLog b/libc/ChangeLog index c427a2f96..5f359bbba 100644 --- a/libc/ChangeLog +++ b/libc/ChangeLog @@ -1,3 +1,97 @@ +2011-05-20 Andreas Schwab <schwab@redhat.com> + + * stdlib/longlong.h: Update from GCC. + +2011-05-23 Andreas Schwab <schwab@redhat.com> + + * sysdeps/unix/sysv/linux/ia64/sysconf.c (HAS_CPUCLOCK): Add + parameter name. + * sysdeps/unix/sysv/linux/sysconf.c (has_cpuclock, HAS_CPUCLOCK): + Add parameter name. + (__sysconf): Pass it down. + +2011-05-22 Ulrich Drepper <drepper@gmail.com> + + [BZ #12671] + * nis/nss_nis/nis-alias.c (_nss_nis_getaliasbyname_r): Use malloc in + some situations. + * nscd/nscd_getserv_r.c (nscd_getserv_r): Likewise. + * posix/glob.c (glob_in_dir): Take additional parameter alloca_used. + add in in __libc_use_alloca calls. Adjust callers. + (glob): Use malloc in some situations. + + * elf/dl-runtime.c (_dl_profile_fixup): Also store LA_SYMB_NOPLTENTER + and LA_SYMB_NOPLTEXIT in flags which are passed to pltenter and + pltexit. + +2011-05-21 Ulrich Drepper <drepper@gmail.com> + + * sysdeps/unix/sysv/linux/bits/time.h: Define CLOCK_REALTIME_ALARM + and CLOCK_BOOTTIME_ALARM. + + [BZ #12782] + * string/xpg-strerror.c (__xpg_strerror_r): Fill buffer even if error + is returned. + + * string/_strerror.c (__strerror_r): Print negative errors as signed + numbers. + + [BZ #12777] + * iconvdata/cp1258.c (comp_table_data): Remove entry 0x00A5 0xEC. + (decomp_table): Change U0385 entry to emit 0xA5 0xEC. + * iconvdata/CP1258.irreversible: Adjust entry 0xA8EC. + + * configure.in: Fix typo in redirection and correct removal of test + files in two cases. + + [BZ #12788] + * locale/setlocale.c (new_composite_name): Fix test to check for + identical name of all categories. + + [BZ #12792] + * libio/filedoalloc.c (local_isatty): New function. + (_IO_file_doallocate): Use local_isatty. + * stdio-common/perror.c (perror): In case a new stream is used + forward the stream error. + * stdio-common/vfprintf.c (ARGCHECK): For read-only streams also set + error flag. + +2011-05-20 Ulrich Drepper <drepper@gmail.com> + + [BZ #11869] + * sysdeps/posix/getaddrinfo.c (gaih_inet): Don't unconditionally use + alloca. + * include/alloca.h (extend_alloca_account): Define. + + [BZ #11857] + * posix/regex.h: Fix comments with documentation of user-accessible + fields after compilation and describe correct free'ing of pattern + after re_compile_pattern. + Patch by Reuben Thomas <rrt@sc3d.org>. + +2011-05-18 Ryan S. Arnold <rsa@us.ibm.com> + + * sysdeps/powerpc/powerpc64/Makefile (no-special-regs): Add -mno-vsx + and -mno-altivec to prevent the compiler from using Altivec and/or + VSX instructions when the corresponding registers are not available. + +2011-05-19 Andreas Schwab <schwab@redhat.com> + + * grp/compat-initgroups.c (__libc_use_alloca): Don't define. + +2011-05-19 Ulrich Drepper <drepper@gmail.com> + + * libio/freopen.c (freopen): Use __dup2, not dup2. + * libio/freopen64.c (freopen64): Likewise. + +2011-05-17 H.J. Lu <hongjiu.lu@intel.com> + + [BZ #12775] + * sysdeps/x86_64/fpu/e_powl.S: Fix a typo. + * math/Makefile (tests): Add test-powl. + (CFLAGS-test-powl.c): Define. + * math/test-powl.c: New file. + 2011-05-16 H.J. Lu <hongjiu.lu@intel.com> * fileops.c (_IO_new_file_fopen): Get fd from _IO_fileno. @@ -1,4 +1,4 @@ -GNU C Library NEWS -- history of user-visible changes. 2011-5-17 +GNU C Library NEWS -- history of user-visible changes. 2011-5-22 Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc. See the end for copying conditions. @@ -10,13 +10,14 @@ Version 2.14 * The following bugs are resolved with this release: 386, 6420, 7101, 9730, 9732, 9809, 10138, 10149, 10157, 11257, 11258, - 11487, 11532, 11578, 11653, 11668, 11697, 11724, 11820, 11837, 11892, - 11895, 11901, 11945, 11947, 11952, 11987, 12052, 12083, 12158, 12178, - 12200, 12346, 12393, 12420, 12432, 12445, 12449, 12453, 12454, 12460, - 12469, 12489, 12509, 12510, 12511, 12518, 12527, 12541, 12545, 12551, - 12582, 12583, 12587, 12597, 12601, 12611, 12625, 12626, 12631, 12650, - 12653, 12655, 12660, 12681, 12685, 12711, 12713, 12714, 12717, 12723, - 12724, 12734, 12738, 12746, 12766 + 11487, 11532, 11578, 11653, 11668, 11697, 11724, 11820, 11837, 11857, + 11869, 11892, 11895, 11901, 11945, 11947, 11952, 11987, 12052, 12083, + 12158, 12178, 12200, 12346, 12393, 12420, 12432, 12445, 12449, 12453, + 12454, 12460, 12469, 12489, 12509, 12510, 12511, 12518, 12527, 12541, + 12545, 12551, 12582, 12583, 12587, 12597, 12601, 12611, 12625, 12626, + 12631, 12650, 12653, 12655, 12660, 12671, 12681, 12685, 12711, 12713, + 12714, 12717, 12723, 12724, 12734, 12738, 12746, 12766, 12775, 12777, + 12782, 12788, 12792 * The RPC implementation in libc is obsoleted. Old programs keep working but new programs cannot be linked with the routines in libc anymore. diff --git a/libc/configure b/libc/configure index fe51bc31b..4a2649770 100755 --- a/libc/configure +++ b/libc/configure @@ -6258,7 +6258,7 @@ EOF fi fi fi - rm -f conftest.cs + rm -f conftest.{c,s} fi { $as_echo "$as_me:$LINENO: result: $libc_cv_visibility_attribute" >&5 @@ -6282,7 +6282,7 @@ else int bar (int x) { return x; } EOF libc_cv_broken_visibility_attribute=yes - if { ac_try='${CC-cc} -Werror -S conftest.c -o conftest.s1>&5' + if { ac_try='${CC-cc} -Werror -S conftest.c -o conftest.s 1>&5' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6942,7 +6942,7 @@ EOF else libc_cv_have_section_quotes=unknown fi - rm -f conftest.cs + rm -f conftest.{c,s} fi { $as_echo "$as_me:$LINENO: result: $libc_cv_have_section_quotes" >&5 diff --git a/libc/configure.in b/libc/configure.in index 9b5230cd9..1c2f9f91a 100644 --- a/libc/configure.in +++ b/libc/configure.in @@ -1426,7 +1426,7 @@ EOF fi fi fi - rm -f conftest.[cs] + rm -f conftest.{c,s} ]) if test $libc_cv_visibility_attribute != yes; then AC_MSG_ERROR(compiler support for visibility attribute is required) @@ -1442,7 +1442,7 @@ EOF int bar (int x) { return x; } EOF libc_cv_broken_visibility_attribute=yes - if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s1>&AS_MESSAGE_LOG_FD); then + if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then changequote(,)dnl if grep '\.hidden[ _]foo' conftest.s >/dev/null; then changequote([,])dnl @@ -1830,7 +1830,7 @@ EOF else libc_cv_have_section_quotes=unknown fi - rm -f conftest.[cs] + rm -f conftest.{c,s} ]) if test $libc_cv_have_section_quotes = yes; then AC_DEFINE(HAVE_SECTION_QUOTES) @@ -2104,7 +2104,7 @@ fi if test -n "$submachine"; then AC_CACHE_CHECK([for compiler option for CPU variant], - libc_cv_cc_submachine, [dnl + libc_cv_cc_submachine, [dnl libc_cv_cc_submachine=no for opt in "-march=$submachine" "-mcpu=$submachine"; do if AC_TRY_COMMAND([${CC-cc} $opt -xc /dev/null -S -o /dev/null]); then diff --git a/libc/elf/dl-runtime.c b/libc/elf/dl-runtime.c index ae2d05c77..b27cfbf20 100644 --- a/libc/elf/dl-runtime.c +++ b/libc/elf/dl-runtime.c @@ -271,7 +271,7 @@ _dl_profile_fixup ( interested in auditing. */ if ((l->l_audit_any_plt | result->l_audit_any_plt) != 0) { - unsigned int altvalue = 0; + unsigned int flags = 0; struct audit_ifaces *afct = GLRO(dl_audit); /* Synthesize a symbol record where the st_value field is the result. */ @@ -294,7 +294,6 @@ _dl_profile_fixup ( if ((l->l_audit[cnt].bindflags & LA_FLG_BINDFROM) != 0 && (result->l_audit[cnt].bindflags & LA_FLG_BINDTO) != 0) { - unsigned int flags = altvalue; if (afct->symbind != NULL) { uintptr_t new_value @@ -305,7 +304,7 @@ _dl_profile_fixup ( strtab2 + defsym->st_name); if (new_value != (uintptr_t) sym.st_value) { - altvalue = LA_SYMB_ALTVALUE; + flags |= LA_SYMB_ALTVALUE; sym.st_value = new_value; } } @@ -328,7 +327,7 @@ _dl_profile_fixup ( afct = afct->next; } - reloc_result->flags = altvalue; + reloc_result->flags = flags; value = DL_FIXUP_ADDR_VALUE (sym.st_value); } else @@ -366,7 +365,7 @@ _dl_profile_fixup ( const char *symname = strtab + sym.st_name; /* Keep track of overwritten addresses. */ - unsigned int altvalue = reloc_result->flags; + unsigned int flags = reloc_result->flags; struct audit_ifaces *afct = GLRO(dl_audit); for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) @@ -375,7 +374,6 @@ _dl_profile_fixup ( && (reloc_result->enterexit & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0) { - unsigned int flags = altvalue; long int new_framesize = -1; uintptr_t new_value = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx, @@ -385,7 +383,7 @@ _dl_profile_fixup ( &new_framesize); if (new_value != (uintptr_t) sym.st_value) { - altvalue = LA_SYMB_ALTVALUE; + flags |= LA_SYMB_ALTVALUE; sym.st_value = new_value; } diff --git a/libc/grp/compat-initgroups.c b/libc/grp/compat-initgroups.c index 7bcc203fe..260c4826c 100644 --- a/libc/grp/compat-initgroups.c +++ b/libc/grp/compat-initgroups.c @@ -8,12 +8,6 @@ typedef enum nss_status (*end_function) (void); typedef enum nss_status (*get_function) (struct group *, char *, size_t, int *); -/* This file is also used in nscd where __libc_alloca_cutoff is not - available. */ -#ifdef NOT_IN_libc -# define __libc_use_alloca(size) ((size) < __MAX_ALLOCA_CUTOFF * 4) -#endif - static enum nss_status compat_call (service_user *nip, const char *user, gid_t group, long int *start, diff --git a/libc/iconvdata/CP1258.irreversible b/libc/iconvdata/CP1258.irreversible index 68a54812d..cec138244 100644 --- a/libc/iconvdata/CP1258.irreversible +++ b/libc/iconvdata/CP1258.irreversible @@ -96,8 +96,8 @@ 0x79F2 0x1EF5 0x7AEC 0x017A 0x7AF2 0x1E93 -0xA5EC 0x0385 0xA8CC 0x1FED +0xA8EC 0x0385 0xA8EC 0x1FEE 0xC2CC 0x1EA6 0xC2D2 0x1EA8 diff --git a/libc/iconvdata/cp1258.c b/libc/iconvdata/cp1258.c index d1b2be412..2b741ba96 100644 --- a/libc/iconvdata/cp1258.c +++ b/libc/iconvdata/cp1258.c @@ -1,5 +1,5 @@ /* Conversion from and to CP1258. - Copyright (C) 1998, 2001, 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 1998, 2001, 2002, 2004, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998, and Bruno Haible <haible@clisp.cons.org>, 2001. @@ -92,7 +92,7 @@ static const uint16_t to_ucs4[128] = 0x20AC, 0, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0, 0x2039, 0x0152, 0, 0, 0, /* 0x90 */ - 0, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0, 0x203A, 0x0153, 0, 0, 0x0178, /* 0xA0 */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, @@ -162,7 +162,7 @@ static const struct { 0x01AF, 0x1EEA }, { 0x01B0, 0x1EEB }, #define COMP_TABLE_IDX_0301 (COMP_TABLE_IDX_0300 + COMP_TABLE_LEN_0300) -#define COMP_TABLE_LEN_0301 60 +#define COMP_TABLE_LEN_0301 59 { 0x0041, 0x00C1 }, { 0x0043, 0x0106 }, { 0x0045, 0x00C9 }, @@ -197,7 +197,7 @@ static const struct { 0x0077, 0x1E83 }, { 0x0079, 0x00FD }, { 0x007A, 0x017A }, - { 0x00A5, 0x0385 }, + /* { 0x00A5, 0x0385 }, Wrong, A5 is Yen sign */ { 0x00A8, 0x1FEE }, { 0x00C2, 0x1EA4 }, { 0x00C5, 0x01FA }, @@ -505,7 +505,7 @@ static const struct static const unsigned char from_ucs4[] = { #define FROM_IDX_00 0 - 0xc4, 0xc5, 0xc6, 0xc7, /* 0x00c4-0x00c7 */ + 0xc4, 0xc5, 0xc6, 0xc7, /* 0x00c4-0x00c7 */ 0xc8, 0xc9, 0xca, 0xcb, 0x00, 0xcd, 0xce, 0xcf, /* 0x00c8-0x00cf */ 0x00, 0xd1, 0x00, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0x00d0-0x00d7 */ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0x00d8-0x00df */ @@ -517,7 +517,7 @@ static const unsigned char from_ucs4[] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0108-0x010f */ 0xd0, 0xf0, /* 0x0110-0x0111 */ #define FROM_IDX_01 (FROM_IDX_00 + 78) - 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0x0152-0x0157 */ + 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0x0152-0x0157 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0158-0x015f */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0160-0x0167 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0168-0x016f */ @@ -531,7 +531,7 @@ static const unsigned char from_ucs4[] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, /* 0x01a8-0x01af */ 0xfd, /* 0x01b0-0x01b0 */ #define FROM_IDX_02 (FROM_IDX_01 + 95) - 0x88, 0x00, /* 0x02c6-0x02c7 */ + 0x88, 0x00, /* 0x02c6-0x02c7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02c8-0x02cf */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02d0-0x02d7 */ 0x00, 0x00, 0x00, 0x00, 0x98, /* 0x02d8-0x02dc */ @@ -542,7 +542,7 @@ static const unsigned char from_ucs4[] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0318-0x031f */ 0x00, 0x00, 0x00, 0xf2, /* 0x0320-0x0323 */ #define FROM_IDX_20 (FROM_IDX_03 + 36) - 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x2013-0x2017 */ + 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x2013-0x2017 */ 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x2018-0x201f */ 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x2020-0x2027 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2028-0x202f */ @@ -619,7 +619,7 @@ static const struct { 0x01fd, 0xe6, 0xec }, { 0x01fe, 0xd8, 0xec }, { 0x01ff, 0xf8, 0xec }, - { 0x0385, 0xa5, 0xec }, + { 0x0385, 0xa8, 0xec }, { 0x1e04, 0x42, 0xf2 }, { 0x1e05, 0x62, 0xf2 }, { 0x1e08, 0xc7, 0xec }, diff --git a/libc/include/alloca.h b/libc/include/alloca.h index b99c3d152..83504135f 100644 --- a/libc/include/alloca.h +++ b/libc/include/alloca.h @@ -49,15 +49,24 @@ libc_hidden_proto (__libc_alloca_cutoff) #if defined stackinfo_get_sp && defined stackinfo_sub_sp # define alloca_account(size, avar) \ - ({ void *old__ = stackinfo_get_sp (); \ - void *m__ = __alloca (size); \ - avar += stackinfo_sub_sp (old__); \ + ({ void *old__ = stackinfo_get_sp (); \ + void *m__ = __alloca (size); \ + avar += stackinfo_sub_sp (old__); \ + m__; }) +# define extend_alloca_account(buf, len, newlen, avar) \ + ({ void *old__ = stackinfo_get_sp (); \ + void *m__ = extend_alloca (buf, len, newlen); \ + avar += stackinfo_sub_sp (old__); \ m__; }) #else # define alloca_account(size, avar) \ - ({ size_t s__ = (size); \ - avar += s__; \ + ({ size_t s__ = (size); \ + avar += s__; \ __alloca (s__); }) +# define extend_alloca_account(buf, len, newlen, avar) \ + ({ size_t s__ = (newlen); \ + avar += s__; \ + extend_alloca (buf, len, s__); }) #endif #endif diff --git a/libc/libio/filedoalloc.c b/libc/libio/filedoalloc.c index ca02dbeb3..4f62dcd91 100644 --- a/libc/libio/filedoalloc.c +++ b/libc/libio/filedoalloc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1997, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1997, 2001, 2002, 2011 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 @@ -41,7 +41,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 @@ -74,6 +74,17 @@ # include <device-nrs.h> #endif + +static int +local_isatty (int fd) +{ + int save_errno = errno; + int res = isatty (fd); + __set_errno (save_errno); + return res; +} + + /* * Allocate a file buffer, or switch to unbuffered I/O. * Per the ANSI C standard, ALL tty devices default to line buffered. @@ -109,7 +120,7 @@ _IO_file_doallocate (fp) #ifdef DEV_TTY_P DEV_TTY_P (&st) || #endif - isatty (fp->_fileno)) + local_isatty (fp->_fileno)) fp->_flags |= _IO_LINE_BUF; } #if _IO_HAVE_ST_BLKSIZE diff --git a/libc/libio/freopen.c b/libc/libio/freopen.c index 20eda9d0f..ee98b6e58 100644 --- a/libc/libio/freopen.c +++ b/libc/libio/freopen.c @@ -102,7 +102,7 @@ freopen (filename, mode, fp) if (errno == ENOSYS) __have_dup3 = -1; - dup2 (_IO_fileno (result), fd); + __dup2 (_IO_fileno (result), fd); if ((result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0) __fcntl (fd, F_SETFD, FD_CLOEXEC); } diff --git a/libc/libio/freopen64.c b/libc/libio/freopen64.c index 99045c641..6c4a20f9a 100644 --- a/libc/libio/freopen64.c +++ b/libc/libio/freopen64.c @@ -86,7 +86,7 @@ freopen64 (filename, mode, fp) if (errno == ENOSYS) __have_dup3 = -1; - dup2 (_IO_fileno (result), fd); + __dup2 (_IO_fileno (result), fd); if ((result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0) __fcntl (fd, F_SETFD, FD_CLOEXEC); } diff --git a/libc/locale/setlocale.c b/libc/locale/setlocale.c index 58daaf1f5..8d14d9ec9 100644 --- a/libc/locale/setlocale.c +++ b/libc/locale/setlocale.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1995-2000, 2002, 2003, 2004, 2006, 2008, 2010 +/* Copyright (C) 1991, 1992, 1995-2000, 2002, 2003, 2004, 2006, 2008, 2010, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -125,7 +125,7 @@ new_composite_name (int category, const char *newnames[__LC_LAST]) _nl_global_locale.__names[i]); last_len = strlen (name); cumlen += _nl_category_name_sizes[i] + 1 + last_len + 1; - if (i > 0 && same && strcmp (name, newnames[0]) != 0) + if (same && name != newnames[0] && strcmp (name, newnames[0]) != 0) same = 0; } diff --git a/libc/localedata/ChangeLog b/libc/localedata/ChangeLog index 705c351ec..78965fbd0 100644 --- a/libc/localedata/ChangeLog +++ b/libc/localedata/ChangeLog @@ -1,3 +1,9 @@ +2011-05-21 Ulrich Drepper <drepper@gmail.com> + + [BZ #12788] + * bug-setlocale1.c: New file. + * Makefile: Add rules to build and run bug-setlocale1. + 2011-05-17 Ulrich Drepper <drepper@gmail.com> [BZ #11837] diff --git a/libc/localedata/Makefile b/libc/localedata/Makefile index ac1bed760..7818a26ce 100644 --- a/libc/localedata/Makefile +++ b/libc/localedata/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1996-2003,2005,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 1996-2003,2005,2007,2008,2009,2011 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 @@ -109,7 +109,7 @@ locale_test_suite := tst_iswalnum tst_iswalpha tst_iswcntrl \ tests-$(OPTION_EGLIBC_LOCALE_CODE) \ += $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \ tst-leaks tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \ - tst-strfmon1 tst-sscanf tst-strptime + tst-strfmon1 tst-sscanf tst-strptime bug-setlocale1 ifeq (yesy,$(build-shared)$(OPTION_EGLIBC_LOCALE_CODE)) ifneq (no,$(PERL)) tests: $(objpfx)mtrace-tst-leaks @@ -330,5 +330,8 @@ tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace \ $(objpfx)mtrace-tst-leaks: $(objpfx)tst-leaks.out $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@ +bug-setlocale1-ENV = LOCPATH=$(common-objpfx)localedata +bug-setlocale1-ARGS = $(common-objpfx) + $(objdir)/iconvdata/gconv-modules: $(MAKE) -C ../iconvdata subdir=iconvdata $@ diff --git a/libc/localedata/bug-setlocale1.c b/libc/localedata/bug-setlocale1.c new file mode 100644 index 000000000..cf787be02 --- /dev/null +++ b/libc/localedata/bug-setlocale1.c @@ -0,0 +1,132 @@ +// BZ 12788 +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +static int +do_test (int argc, char *argv[]) +{ + if (argc > 1) + { + char *newargv[5]; + asprintf (&newargv[0], "%self/ld.so", argv[1]); + if (newargv[0] == NULL) + { + puts ("asprintf failed"); + return 1; + } + newargv[1] = (char *) "--library-path"; + newargv[2] = argv[1]; + newargv[3] = argv[0]; + newargv[4] = NULL; + + char *env[3]; + env[0] = (char *) "LC_CTYPE=de_DE.UTF-8"; + char *loc = getenv ("LOCPATH"); + if (loc == NULL || loc[0] == '\0') + { + puts ("LOCPATH not set"); + return 1; + } + asprintf (&env[1], "LOCPATH=%s", loc); + if (newargv[0] == NULL) + { + puts ("second asprintf failed"); + return 1; + } + env[2] = NULL; + + execve (newargv[0], newargv, env); + + puts ("execve returned"); + return 1; + } + + int result = 0; + + char *a = setlocale (LC_ALL, ""); + printf ("setlocale(LC_ALL, \"\") = %s\n", a); + if (a == NULL) + return 1; + a = strdupa (a); + + char *b = setlocale (LC_CTYPE, ""); + printf ("setlocale(LC_CTYPE, \"\") = %s\n", b); + if (b == NULL) + return 1; + + char *c = setlocale (LC_ALL, NULL); + printf ("setlocale(LC_ALL, NULL) = %s\n", c); + if (c == NULL) + return 1; + c = strdupa (c); + + if (strcmp (a, c) != 0) + { + puts ("*** first and third result do not match"); + result = 1; + } + + char *d = setlocale (LC_NUMERIC, ""); + printf ("setlocale(LC_NUMERIC, \"\") = %s\n", d); + if (d == NULL) + return 1; + + if (strcmp (d, "C") != 0) + { + puts ("*** LC_NUMERIC not C"); + result = 1; + } + + char *e = setlocale (LC_ALL, NULL); + printf ("setlocale(LC_ALL, NULL) = %s\n", e); + if (e == NULL) + return 1; + + if (strcmp (a, e) != 0) + { + puts ("*** first and fifth result do not match"); + result = 1; + } + + char *f = setlocale (LC_ALL, "C"); + printf ("setlocale(LC_ALL, \"C\") = %s\n", f); + if (f == NULL) + return 1; + + if (strcmp (f, "C") != 0) + { + puts ("*** LC_ALL not C"); + result = 1; + } + + char *g = setlocale (LC_ALL, NULL); + printf ("setlocale(LC_ALL, NULL) = %s\n", g); + if (g == NULL) + return 1; + + if (strcmp (g, "C") != 0) + { + puts ("*** LC_ALL not C"); + result = 1; + } + + char *h = setlocale (LC_CTYPE, NULL); + printf ("setlocale(LC_CTYPE, NULL) = %s\n", h); + if (h == NULL) + return 1; + + if (strcmp (h, "C") != 0) + { + puts ("*** LC_CTYPE not C"); + result = 1; + } + + return result; +} + +#define TEST_FUNCTION do_test (argc, argv) +#include "../test-skeleton.c" diff --git a/libc/math/Makefile b/libc/math/Makefile index 3d5a00c95..7900a8470 100644 --- a/libc/math/Makefile +++ b/libc/math/Makefile @@ -93,7 +93,7 @@ distribute += $(filter-out $(generated),$(long-m-yes:=.c) $(long-c-yes:=.c)) tests = test-matherr test-fenv basic-test \ test-misc test-fpucw tst-definitions test-tgmath test-tgmath-ret \ bug-nextafter bug-nexttoward bug-tgmath1 test-tgmath-int test-tgmath2 \ - test-dbl-wrap + test-dbl-wrap test-powl tests-$(OPTION_EGLIBC_LIBM_BIG) += atest-exp atest-sincos atest-exp2 # We do the `long double' tests only if this data type is available and # distinct from `double'. @@ -138,6 +138,7 @@ CFLAGS-test-ldouble.c = -fno-inline -ffloat-store -fno-builtin CFLAGS-test-tgmath.c = -fno-builtin CFLAGS-test-tgmath2.c = -fno-builtin CFLAGS-test-tgmath-ret.c = -fno-builtin +CFLAGS-test-powl.c = -fno-builtin CPPFLAGS-test-ifloat.c = -U__LIBC_INTERNAL_MATH_INLINES -D__FAST_MATH__ \ -DTEST_FAST_MATH -fno-builtin CPPFLAGS-test-idouble.c = -U__LIBC_INTERNAL_MATH_INLINES -D__FAST_MATH__ \ diff --git a/libc/math/test-powl.c b/libc/math/test-powl.c new file mode 100644 index 000000000..c464d78e4 --- /dev/null +++ b/libc/math/test-powl.c @@ -0,0 +1,51 @@ +/* Test for powl + Copyright (C) 2011 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stdio.h> +#include <math.h> +#include <float.h> +#include <ieee754.h> + +int +main (void) +{ + int result = 0; + +#ifndef NO_LONG_DOUBLE +# if LDBL_MANT_DIG == 64 + { + long double x = 1e-20; + union ieee854_long_double u; + u.ieee.mantissa0 = 1; + u.ieee.mantissa1 = 1; + u.ieee.exponent = 0; + u.ieee.negative = 0; + (void) powl (0.2, u.d); + x = powl (x, 1.5); + if (fabsl (x - 1e-30) > 1e-10) + { + printf ("powl (1e-20, 1.5): wrong result: %Lg\n", x); + result = 1; + } + } +# endif +#endif + + return result; +} diff --git a/libc/nis/nss_nis/nis-alias.c b/libc/nis/nss_nis/nis-alias.c index 9286e36ba..cfe4097ec 100644 --- a/libc/nis/nss_nis/nis-alias.c +++ b/libc/nis/nss_nis/nis-alias.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2002, 2003, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1996-2002, 2003, 2006, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996. @@ -142,10 +142,10 @@ internal_nis_getaliasent_r (struct aliasent *alias, char *buffer, int yperr; if (new_start) - yperr = yp_first (domain, "mail.aliases", &outkey, &keylen, &result, + yperr = yp_first (domain, "mail.aliases", &outkey, &keylen, &result, &len); else - yperr = yp_next (domain, "mail.aliases", oldkey, oldkeylen, &outkey, + yperr = yp_next (domain, "mail.aliases", oldkey, oldkeylen, &outkey, &keylen, &result, &len); if (__builtin_expect (yperr != YPERR_SUCCESS, 0)) @@ -153,20 +153,20 @@ internal_nis_getaliasent_r (struct aliasent *alias, char *buffer, enum nss_status retval = yperr2nss (yperr); if (retval == NSS_STATUS_TRYAGAIN) - *errnop = errno; - return retval; - } + *errnop = errno; + return retval; + } if (__builtin_expect ((size_t) (len + 1) > buflen, 0)) - { + { free (result); - *errnop = ERANGE; - return NSS_STATUS_TRYAGAIN; - } + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } char *p = strncpy (buffer, result, len); buffer[len] = '\0'; while (isspace (*p)) - ++p; + ++p; free (result); parse_res = _nss_nis_parse_aliasent (outkey, p, alias, buffer, @@ -213,13 +213,25 @@ _nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias, return NSS_STATUS_UNAVAIL; } - size_t namlen = strlen (name); - char name2[namlen + 1]; - char *domain; if (__builtin_expect (yp_get_default_domain (&domain), 0)) return NSS_STATUS_UNAVAIL; + size_t namlen = strlen (name); + char *name2; + int use_alloca = __libc_use_alloca (namlen + 1); + if (use_alloca) + name2 = __alloca (namlen + 1); + else + { + name2 = malloc (namlen + 1); + if (name2 == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + } + /* Convert name to lowercase. */ size_t i; for (i = 0; i < namlen; ++i) @@ -230,6 +242,9 @@ _nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias, int len; int yperr = yp_match (domain, "mail.aliases", name2, namlen, &result, &len); + if (!use_alloca) + free (name2); + if (__builtin_expect (yperr != YPERR_SUCCESS, 0)) { enum nss_status retval = yperr2nss (yperr); diff --git a/libc/nscd/nscd_getserv_r.c b/libc/nscd/nscd_getserv_r.c index dce416548..de96a5757 100644 --- a/libc/nscd/nscd_getserv_r.c +++ b/libc/nscd/nscd_getserv_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007, 2009 Free Software Foundation, Inc. +/* Copyright (C) 2007, 2009, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2007. @@ -17,6 +17,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <assert.h> #include <errno.h> #include <string.h> #include <not-cancel.h> @@ -80,6 +81,7 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto, { int gc_cycle; int nretries = 0; + size_t alloca_used = 0; /* If the mapping is available, try to search there instead of communicating with the nscd. */ @@ -88,13 +90,23 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto, &gc_cycle); size_t protolen = proto == NULL ? 0 : strlen (proto); size_t keylen = critlen + 1 + protolen + 1; - char *key = alloca (keylen); + int alloca_key = __libc_use_alloca (keylen); + char *key; + if (alloca_key) + key = alloca_account (keylen, alloca_used); + else + { + key = malloc (keylen); + if (key == NULL) + return -1; + } memcpy (__mempcpy (__mempcpy (key, crit, critlen), "/", 1), proto ?: "", protolen + 1); retry:; const char *s_name = NULL; const char *s_proto = NULL; + int alloca_aliases_len = 0; const uint32_t *aliases_len = NULL; const char *aliases_list = NULL; int retval = -1; @@ -136,8 +148,22 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto, if (((uintptr_t) aliases_len & (__alignof__ (*aliases_len) - 1)) != 0) { - uint32_t *tmp = alloca (serv_resp.s_aliases_cnt - * sizeof (uint32_t)); + uint32_t *tmp; + alloca_aliases_len + = __libc_use_alloca (alloca_used + + (serv_resp.s_aliases_cnt + * sizeof (uint32_t))); + if (alloca_aliases_len) + tmp = __alloca (serv_resp.s_aliases_cnt * sizeof (uint32_t)); + else + { + tmp = malloc (serv_resp.s_aliases_cnt * sizeof (uint32_t)); + if (tmp == NULL) + { + retval = ENOMEM; + goto out; + } + } aliases_len = memcpy (tmp, aliases_len, serv_resp.s_aliases_cnt * sizeof (uint32_t)); @@ -217,8 +243,24 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto, if (serv_resp.s_aliases_cnt > 0) { - aliases_len = alloca (serv_resp.s_aliases_cnt - * sizeof (uint32_t)); + assert (alloca_aliases_len == 0); + alloca_aliases_len + = __libc_use_alloca (alloca_used + + (serv_resp.s_aliases_cnt + * sizeof (uint32_t))); + if (alloca_aliases_len) + aliases_len = alloca (serv_resp.s_aliases_cnt + * sizeof (uint32_t)); + else + { + aliases_len = malloc (serv_resp.s_aliases_cnt + * sizeof (uint32_t)); + if (aliases_len == NULL) + { + retval = ENOMEM; + goto out_close; + } + } vec[n].iov_base = (void *) aliases_len; vec[n].iov_len = serv_resp.s_aliases_cnt * sizeof (uint32_t); @@ -329,5 +371,10 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto, goto retry; } + if (!alloca_aliases_len) + free ((void *) aliases_len); + if (!alloca_key) + free (key); + return retval; } diff --git a/libc/posix/glob.c b/libc/posix/glob.c index 017180a27..df0861f6e 100644 --- a/libc/posix/glob.c +++ b/libc/posix/glob.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 +/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -202,7 +202,7 @@ static const char *next_brace_sub (const char *begin, int flags) __THROW; static int glob_in_dir (const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), - glob_t *pglob); + glob_t *pglob, size_t alloca_used); extern int __glob_pattern_type (const char *pattern, int quote) attribute_hidden; @@ -256,13 +256,18 @@ glob (pattern, flags, errfunc, pglob) glob_t *pglob; { const char *filename; - const char *dirname; + char *dirname = NULL; size_t dirlen; int status; size_t oldcount; int meta; int dirname_modified; + int malloc_dirname = 0; glob_t dirs; + int retval = 0; +#ifdef _LIBC + size_t alloca_used = 0; +#endif if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) { @@ -311,20 +316,26 @@ glob (pattern, flags, errfunc, pglob) const char *next; const char *rest; size_t rest_len; -#ifdef __GNUC__ - char onealt[strlen (pattern) - 1]; -#else - char *onealt = (char *) malloc (strlen (pattern) - 1); - if (onealt == NULL) + char *onealt; + size_t pattern_len = strlen (pattern) - 1; +#ifdef _LIBC + int alloca_onealt = __libc_use_alloca (alloca_used + pattern_len); + if (alloca_onealt) + onealt = alloca_account (pattern_len, alloca_used); + else +#endif { - if (!(flags & GLOB_APPEND)) + onealt = (char *) malloc (pattern_len); + if (onealt == NULL) { - pglob->gl_pathc = 0; - pglob->gl_pathv = NULL; + if (!(flags & GLOB_APPEND)) + { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + } + return GLOB_NOSPACE; } - return GLOB_NOSPACE; } -#endif /* We know the prefix for all sub-patterns. */ alt_start = mempcpy (onealt, pattern, begin - pattern); @@ -335,9 +346,11 @@ glob (pattern, flags, errfunc, pglob) if (next == NULL) { /* It is an illegal expression. */ -#ifndef __GNUC__ - free (onealt); + illegal_brace: +#ifdef _LIBC + if (__builtin_expect (!alloca_onealt, 0)) #endif + free (onealt); return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); } @@ -347,13 +360,8 @@ glob (pattern, flags, errfunc, pglob) { rest = next_brace_sub (rest + 1, flags); if (rest == NULL) - { - /* It is an illegal expression. */ -#ifndef __GNUC__ - free (onealt); -#endif - return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); - } + /* It is an illegal expression. */ + goto illegal_brace; } /* Please note that we now can be sure the brace expression is well-formed. */ @@ -389,9 +397,10 @@ glob (pattern, flags, errfunc, pglob) /* If we got an error, return it. */ if (result && result != GLOB_NOMATCH) { -#ifndef __GNUC__ - free (onealt); +#ifdef _LIBC + if (__builtin_expect (!alloca_onealt, 0)) #endif + free (onealt); if (!(flags & GLOB_APPEND)) { globfree (pglob); @@ -409,9 +418,10 @@ glob (pattern, flags, errfunc, pglob) assert (next != NULL); } -#ifndef __GNUC__ - free (onealt); +#ifdef _LIBC + if (__builtin_expect (!alloca_onealt, 0)) #endif + free (onealt); if (pglob->gl_pathc != firstc) /* We found some entries. */ @@ -458,7 +468,7 @@ glob (pattern, flags, errfunc, pglob) case is nothing but a notation for a directory. */ if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~') { - dirname = pattern; + dirname = (char *) pattern; dirlen = strlen (pattern); /* Set FILENAME to NULL as a special flag. This is ugly but @@ -476,9 +486,9 @@ glob (pattern, flags, errfunc, pglob) filename = pattern; #ifdef _AMIGA - dirname = ""; + dirname = (char *) ""; #else - dirname = "."; + dirname = (char *) "."; #endif dirlen = 0; } @@ -488,7 +498,7 @@ glob (pattern, flags, errfunc, pglob) && (flags & GLOB_NOESCAPE) == 0)) { /* "/pattern" or "\\/pattern". */ - dirname = "/"; + dirname = (char *) "/"; dirlen = 1; ++filename; } @@ -514,7 +524,17 @@ glob (pattern, flags, errfunc, pglob) from "d:/", since "d:" and "d:/" are not the same.*/ } #endif - newp = (char *) __alloca (dirlen + 1); +#ifdef _LIBC + if (__libc_use_alloca (alloca_used + dirlen + 1)) + newp = alloca_account (dirlen + 1, alloca_used); + else +#endif + { + newp = malloc (dirlen + 1); + if (newp == NULL) + return GLOB_NOSPACE; + malloc_dirname = 1; + } *((char *) mempcpy (newp, pattern, dirlen)) = '\0'; dirname = newp; ++filename; @@ -554,7 +574,8 @@ glob (pattern, flags, errfunc, pglob) oldcount = pglob->gl_pathc + pglob->gl_offs; goto no_matches; } - return val; + retval = val; + goto out; } } @@ -566,7 +587,8 @@ glob (pattern, flags, errfunc, pglob) && (dirname[2] == '\0' || dirname[2] == '/'))) { /* Look up home directory. */ - const char *home_dir = getenv ("HOME"); + char *home_dir = getenv ("HOME"); + int malloc_home_dir = 0; # ifdef _AMIGA if (home_dir == NULL || home_dir[0] == '\0') home_dir = "SYS:"; @@ -586,7 +608,7 @@ glob (pattern, flags, errfunc, pglob) /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try a moderate value. */ buflen = 20; - name = (char *) __alloca (buflen); + name = alloca_account (buflen, alloca_used); success = getlogin_r (name, buflen) == 0; if (success) @@ -596,6 +618,7 @@ glob (pattern, flags, errfunc, pglob) long int pwbuflen = GETPW_R_SIZE_MAX (); char *pwtmpbuf; struct passwd pwbuf; + int malloc_pwtmpbuf = 0; int save = errno; # ifndef _LIBC @@ -604,7 +627,18 @@ glob (pattern, flags, errfunc, pglob) Try a moderate value. */ pwbuflen = 1024; # endif - pwtmpbuf = (char *) __alloca (pwbuflen); + if (__libc_use_alloca (alloca_used + pwbuflen)) + pwtmpbuf = alloca_account (pwbuflen, alloca_used); + else + { + pwtmpbuf = malloc (pwbuflen); + if (pwtmpbuf == NULL) + { + retval = GLOB_NOSPACE; + goto out; + } + malloc_pwtmpbuf = 1; + } while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p) != 0) @@ -614,47 +648,116 @@ glob (pattern, flags, errfunc, pglob) p = NULL; break; } -# ifdef _LIBC - pwtmpbuf = extend_alloca (pwtmpbuf, pwbuflen, + + if (!malloc_pwtmpbuf + && __libc_use_alloca (alloca_used + + 2 * pwbuflen)) + pwtmpbuf = extend_alloca_account (pwtmpbuf, pwbuflen, + 2 * pwbuflen, + alloca_used); + else + { + char *newp = realloc (malloc_pwtmpbuf + ? pwtmpbuf : NULL, 2 * pwbuflen); -# else - pwbuflen *= 2; - pwtmpbuf = (char *) __alloca (pwbuflen); -# endif + if (newp == NULL) + { + if (__builtin_expect (malloc_pwtmpbuf, 0)) + free (pwtmpbuf); + retval = GLOB_NOSPACE; + goto out; + } + pwtmpbuf = newp; + pwbuflen = 2 * pwbuflen; + malloc_pwtmpbuf = 1; + } __set_errno (save); } # else p = getpwnam (name); # endif if (p != NULL) - home_dir = p->pw_dir; + { + if (!malloc_pwtmpbuf) + home_dir = p->pw_dir; + else + { + size_t home_dir_len = strlen (p->pw_dir) + 1; + if (__libc_use_alloca (alloca_used + home_dir_len)) + home_dir = alloca_account (home_dir_len, + alloca_used); + else + { + home_dir = malloc (home_dir_len); + if (home_dir == NULL) + { + free (pwtmpbuf); + retval = GLOB_NOSPACE; + goto out; + } + malloc_home_dir = 1; + } + memcpy (home_dir, p->pw_dir, home_dir_len); + + free (pwtmpbuf); + } + } } } # endif /* ! _LIBC || __OPTION_EGLIBC_GETLOGIN */ if (home_dir == NULL || home_dir[0] == '\0') { if (flags & GLOB_TILDE_CHECK) - return GLOB_NOMATCH; + { + if (__builtin_expect (malloc_home_dir, 0)) + free (home_dir); + retval = GLOB_NOMATCH; + goto out; + } else - home_dir = "~"; /* No luck. */ + home_dir = (char *) "~"; /* No luck. */ } # endif /* WINDOWS32 */ # endif /* Now construct the full directory. */ if (dirname[1] == '\0') { + if (__builtin_expect (malloc_dirname, 0)) + free (dirname); + dirname = home_dir; dirlen = strlen (dirname); + malloc_dirname = malloc_home_dir; } else { char *newp; size_t home_len = strlen (home_dir); - newp = (char *) __alloca (home_len + dirlen); + int use_alloca = __libc_use_alloca (alloca_used + + home_len + dirlen); + if (use_alloca) + newp = alloca_account (home_len + dirlen, alloca_used); + else + { + newp = malloc (home_len + dirlen); + if (newp == NULL) + { + if (__builtin_expect (malloc_home_dir, 0)) + free (home_dir); + retval = GLOB_NOSPACE; + goto out; + } + } + mempcpy (mempcpy (newp, home_dir, home_len), &dirname[1], dirlen); + + if (__builtin_expect (malloc_dirname, 0)) + free (dirname); + dirname = newp; dirlen += home_len - 1; + malloc_dirname = !use_alloca; } dirname_modified = 1; } @@ -662,7 +765,8 @@ glob (pattern, flags, errfunc, pglob) else { char *end_name = strchr (dirname, '/'); - const char *user_name; + char *user_name; + int malloc_user_name = 0; const char *home_dir; char *unescape = NULL; @@ -682,7 +786,18 @@ glob (pattern, flags, errfunc, pglob) else { char *newp; - newp = (char *) __alloca (end_name - dirname); + if (__libc_use_alloca (alloca_used + (end_name - dirname))) + newp = alloca_account (end_name - dirname, alloca_used); + else + { + newp = malloc (end_name - dirname); + if (newp == NULL) + { + retval = GLOB_NOSPACE; + goto out; + } + malloc_user_name = 1; + } if (unescape != NULL) { char *p = mempcpy (newp, dirname + 1, @@ -719,6 +834,7 @@ glob (pattern, flags, errfunc, pglob) # if defined HAVE_GETPWNAM_R || defined _LIBC long int buflen = GETPW_R_SIZE_MAX (); char *pwtmpbuf; + int malloc_pwtmpbuf = 0; struct passwd pwbuf; int save = errno; @@ -728,7 +844,21 @@ glob (pattern, flags, errfunc, pglob) moderate value. */ buflen = 1024; # endif - pwtmpbuf = (char *) __alloca (buflen); + if (__libc_use_alloca (alloca_used + buflen)) + pwtmpbuf = alloca_account (buflen, alloca_used); + else + { + pwtmpbuf = malloc (buflen); + if (pwtmpbuf == NULL) + { + nomem_getpw: + if (__builtin_expect (malloc_user_name, 0)) + free (user_name); + retval = GLOB_NOSPACE; + goto out; + } + malloc_pwtmpbuf = 1; + } while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0) { @@ -737,40 +867,77 @@ glob (pattern, flags, errfunc, pglob) p = NULL; break; } -# ifdef _LIBC - pwtmpbuf = extend_alloca (pwtmpbuf, buflen, 2 * buflen); -# else - buflen *= 2; - pwtmpbuf = __alloca (buflen); -# endif + if (!malloc_pwtmpbuf + && __libc_use_alloca (alloca_used + 2 * buflen)) + pwtmpbuf = extend_alloca_account (pwtmpbuf, buflen, + 2 * buflen, alloca_used); + else + { + char *newp = realloc (malloc_pwtmpbuf ? pwtmpbuf : NULL, + 2 * buflen); + if (newp == NULL) + { + if (__builtin_expect (malloc_pwtmpbuf, 0)) + free (pwtmpbuf); + goto nomem_getpw; + } + pwtmpbuf = newp; + malloc_pwtmpbuf = 1; + } __set_errno (save); } # else p = getpwnam (user_name); # endif + + if (__builtin_expect (malloc_user_name, 0)) + free (user_name); + + /* If we found a home directory use this. */ if (p != NULL) - home_dir = p->pw_dir; + { + size_t home_len = strlen (p->pw_dir); + size_t rest_len = end_name == NULL ? 0 : strlen (end_name); + + if (__builtin_expect (malloc_dirname, 0)) + free (dirname); + malloc_dirname = 0; + + if (__libc_use_alloca (alloca_used + home_len + rest_len + 1)) + dirname = alloca_account (home_len + rest_len + 1, + alloca_used); + else + { + dirname = malloc (home_len + rest_len + 1); + if (dirname == NULL) + { + if (__builtin_expect (malloc_pwtmpbuf, 0)) + free (pwtmpbuf); + retval = GLOB_NOSPACE; + goto out; + } + malloc_dirname = 1; + } + *((char *) mempcpy (mempcpy (dirname, p->pw_dir, home_len), + end_name, rest_len)) = '\0'; + + dirlen = home_len + rest_len; + dirname_modified = 1; + + if (__builtin_expect (malloc_pwtmpbuf, 0)) + free (pwtmpbuf); + } else - home_dir = NULL; + { + if (__builtin_expect (malloc_pwtmpbuf, 0)) + free (pwtmpbuf); + + if (flags & GLOB_TILDE_CHECK) + /* We have to regard it as an error if we cannot find the + home directory. */ + return GLOB_NOMATCH; + } } - /* If we found a home directory use this. */ - if (home_dir != NULL) - { - char *newp; - size_t home_len = strlen (home_dir); - size_t rest_len = end_name == NULL ? 0 : strlen (end_name); - newp = (char *) __alloca (home_len + rest_len + 1); - *((char *) mempcpy (mempcpy (newp, home_dir, home_len), - end_name, rest_len)) = '\0'; - dirname = newp; - dirlen = home_len + rest_len; - dirname_modified = 1; - } - else - if (flags & GLOB_TILDE_CHECK) - /* We have to regard it as an error if we cannot find the - home directory. */ - return GLOB_NOMATCH; } # endif /* Not Amiga && not WINDOWS32. */ } @@ -904,7 +1071,7 @@ glob (pattern, flags, errfunc, pglob) status = glob_in_dir (filename, dirs.gl_pathv[i], ((flags | GLOB_APPEND) & ~(GLOB_NOCHECK | GLOB_NOMAGIC)), - errfunc, pglob); + errfunc, pglob, alloca_used); if (status == GLOB_NOMATCH) /* No matches in this directory. Try the next. */ continue; @@ -1005,7 +1172,8 @@ glob (pattern, flags, errfunc, pglob) } if (dirname_modified) flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC); - status = glob_in_dir (filename, dirname, flags, errfunc, pglob); + status = glob_in_dir (filename, dirname, flags, errfunc, pglob, + alloca_used); if (status != 0) { if (status == GLOB_NOMATCH && flags != orig_flags @@ -1068,7 +1236,11 @@ glob (pattern, flags, errfunc, pglob) sizeof (char *), collated_compare); } - return 0; + out: + if (__builtin_expect (malloc_dirname, 0)) + free (dirname); + + return retval; } #if defined _LIBC && !defined glob libc_hidden_def (glob) @@ -1278,7 +1450,7 @@ link_exists2_p (const char *dir, size_t dirlen, const char *fname, static int glob_in_dir (const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), - glob_t *pglob) + glob_t *pglob, size_t alloca_used) { size_t dirlen = strlen (directory); void *stream = NULL; @@ -1293,11 +1465,12 @@ glob_in_dir (const char *pattern, const char *directory, int flags, struct globnames *names = &init_names; struct globnames *names_alloca = &init_names; size_t nfound = 0; - size_t allocasize = sizeof (init_names); size_t cur = 0; int meta; int save; + alloca_used += sizeof (init_names); + init_names.next = NULL; init_names.count = INITIAL_COUNT; @@ -1313,20 +1486,36 @@ glob_in_dir (const char *pattern, const char *directory, int flags, { /* Since we use the normal file functions we can also use stat() to verify the file is there. */ - struct stat st; - struct_stat64 st64; + union + { + struct stat st; + struct_stat64 st64; + } ust; size_t patlen = strlen (pattern); - char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1); + int alloca_fullname = __libc_use_alloca (alloca_used + + dirlen + 1 + patlen + 1); + char *fullname; + if (alloca_fullname) + fullname = alloca_account (dirlen + 1 + patlen + 1, alloca_used); + else + { + fullname = malloc (dirlen + 1 + patlen + 1); + if (fullname == NULL) + return GLOB_NOSPACE; + } mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), "/", 1), pattern, patlen + 1); if ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) - ? (*pglob->gl_stat) (fullname, &st) - : __stat64 (fullname, &st64)) == 0) + ? (*pglob->gl_stat) (fullname, &ust.st) + : __stat64 (fullname, &ust.st64)) == 0) /* We found this file to be existing. Now tell the rest of the function to copy this name into the result. */ flags |= GLOB_NOCHECK; + + if (__builtin_expect (!alloca_fullname, 0)) + free (fullname); } else { @@ -1414,9 +1603,9 @@ glob_in_dir (const char *pattern, const char *directory, int flags, size_t size = (sizeof (struct globnames) + ((count - INITIAL_COUNT) * sizeof (char *))); - allocasize += size; - if (__libc_use_alloca (allocasize)) - newnames = names_alloca = __alloca (size); + if (__libc_use_alloca (alloca_used + size)) + newnames = names_alloca + = alloca_account (size, alloca_used); else if ((newnames = malloc (size)) == NULL) goto memory_error; diff --git a/libc/posix/regex.h b/libc/posix/regex.h index 58d4ba815..4ffde3325 100644 --- a/libc/posix/regex.h +++ b/libc/posix/regex.h @@ -350,9 +350,9 @@ typedef enum /* This data structure represents a compiled pattern. Before calling the pattern compiler, the fields `buffer', `allocated', `fastmap', - `translate', and `no_sub' can be set. After the pattern has been - compiled, the `re_nsub' field is available. All other fields are - private to the regex routines. */ + and `translate' can be set. After the pattern has been compiled, + the fields `re_nsub', `not_bol' and `not_eol' are available. All + other fields are private to the regex routines. */ #ifndef RE_TRANSLATE_TYPE # define __RE_TRANSLATE_TYPE unsigned char * @@ -477,7 +477,12 @@ extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax); /* Compile the regular expression PATTERN, with length LENGTH and syntax given by the global `re_syntax_options', into the buffer - BUFFER. Return NULL if successful, and an error string if not. */ + BUFFER. Return NULL if successful, and an error string if not. + + To free the allocated storage, you must call `regfree' on BUFFER. + Note that the translate table must either have been initialised by + `regcomp', with a malloc'ed value, or set to NULL before calling + `regfree'. */ extern const char *re_compile_pattern (const char *__pattern, size_t __length, struct re_pattern_buffer *__buffer); diff --git a/libc/stdio-common/perror.c b/libc/stdio-common/perror.c index 3ee61520f..dedc922cc 100644 --- a/libc/stdio-common/perror.c +++ b/libc/stdio-common/perror.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991-1993,1997,1998,2000-2005 Free Software Foundation, Inc. +/* Copyright (C) 1991-1993,1997,1998,2000-2005,2011 + 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 @@ -73,6 +74,10 @@ perror (const char *s) position. Since the stderr stream wasn't used so far we just write to the descriptor. */ perror_internal (fp, s, errnum); + + if (_IO_ferror_unlocked (fp)) + stderr->_flags |= _IO_ERR_SEEN; + /* Close the stream. */ fclose (fp); } diff --git a/libc/stdio-common/vfprintf.c b/libc/stdio-common/vfprintf.c index db7b35e9a..41f09a16e 100644 --- a/libc/stdio-common/vfprintf.c +++ b/libc/stdio-common/vfprintf.c @@ -53,6 +53,7 @@ CHECK_FILE (S, -1); \ if (S->_flags & _IO_NO_WRITES) \ { \ + S->_flags |= _IO_ERR_SEEN; \ __set_errno (EBADF); \ return -1; \ } \ diff --git a/libc/stdlib/longlong.h b/libc/stdlib/longlong.h index e7d6099c7..5937a4855 100644 --- a/libc/stdlib/longlong.h +++ b/libc/stdlib/longlong.h @@ -1,6 +1,7 @@ /* longlong.h -- definitions for mixed size 32/64 bit arithmetic. Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2002, 2003, 2004, 2005, 2006, 2009 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -9,6 +10,15 @@ License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + 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 @@ -16,8 +26,8 @@ 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. */ + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ /* You have to define the following before including this file: @@ -45,6 +55,11 @@ #define UDWtype UDItype #endif +/* Used in glibc only. */ +#ifndef attribute_hidden +#define attribute_hidden +#endif + extern const UQItype __clz_tab[256] attribute_hidden; /* Define auxiliary asm macros. @@ -303,6 +318,7 @@ UDItype __umulsidi3 (USItype, USItype); #endif #if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32 +#if !defined (__zarch__) #define smul_ppmm(xh, xl, m0, m1) \ do { \ union {DItype __ll; \ @@ -324,6 +340,28 @@ UDItype __umulsidi3 (USItype, USItype); : "0" (__x.__ll), "r" (d)); \ (q) = __x.__i.__l; (r) = __x.__i.__h; \ } while (0) +#else +#define smul_ppmm(xh, xl, m0, m1) \ + do { \ + register SItype r0 __asm__ ("0"); \ + register SItype r1 __asm__ ("1") = m0; \ + \ + __asm__ ("mr\t%%r0,%3" \ + : "=r" (r0), "=r" (r1) \ + : "r" (r1), "r" (m1)); \ + (xh) = r1; (xl) = r0; \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + register SItype r0 __asm__ ("0") = n0; \ + register SItype r1 __asm__ ("1") = n1; \ + \ + __asm__ ("dr\t%%r0,%3" \ + : "=r" (r0), "=r" (r1) \ + : "r" (r0), "r" (r1), "r" (d)); \ + (q) = r0; (r) = r1; \ + } while (0) +#endif /* __zarch__ */ #endif #if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 @@ -417,6 +455,55 @@ UDItype __umulsidi3 (USItype, USItype); __w; }) #endif /* __i960__ */ +#if defined (__ia64) && W_TYPE_SIZE == 64 +/* This form encourages gcc (pre-release 3.4 at least) to emit predicated + "sub r=r,r" and "sub r=r,r,1", giving a 2 cycle latency. The generic + code using "al<bl" arithmetically comes out making an actual 0 or 1 in a + register, which takes an extra cycle. */ +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) - (bl); \ + if ((al) < (bl)) \ + (sh) = (ah) - (bh) - 1; \ + else \ + (sh) = (ah) - (bh); \ + (sl) = __x; \ + } while (0) + +/* Do both product parts in assembly, since that gives better code with + all gcc versions. Some callers will just use the upper part, and in + that situation we waste an instruction, but not any cycles. */ +#define umul_ppmm(ph, pl, m0, m1) \ + __asm__ ("xma.hu %0 = %2, %3, f0\n\txma.l %1 = %2, %3, f0" \ + : "=&f" (ph), "=f" (pl) \ + : "f" (m0), "f" (m1)) +#define count_leading_zeros(count, x) \ + do { \ + UWtype _x = (x), _y, _a, _c; \ + __asm__ ("mux1 %0 = %1, @rev" : "=r" (_y) : "r" (_x)); \ + __asm__ ("czx1.l %0 = %1" : "=r" (_a) : "r" (-_y | _y)); \ + _c = (_a - 1) << 3; \ + _x >>= _c; \ + if (_x >= 1 << 4) \ + _x >>= 4, _c += 4; \ + if (_x >= 1 << 2) \ + _x >>= 2, _c += 2; \ + _c += _x >> 1; \ + (count) = W_TYPE_SIZE - 1 - _c; \ + } while (0) +/* similar to what gcc does for __builtin_ffs, but 0 based rather than 1 + based, and we don't need a special case for x==0 here */ +#define count_trailing_zeros(count, x) \ + do { \ + UWtype __ctz_x = (x); \ + __asm__ ("popcnt %0 = %1" \ + : "=r" (count) \ + : "r" ((__ctz_x-1) & ~__ctz_x)); \ + } while (0) +#define UMUL_TIME 14 +#endif + #if defined (__M32R__) && W_TYPE_SIZE == 32 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ /* The cmp clears the condition bit. */ \ @@ -631,6 +718,43 @@ UDItype __umulsidi3 (USItype, USItype); #endif /* __mc88110__ */ #endif /* __m88000__ */ +#if defined (__mn10300__) +# if defined (__AM33__) +# define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) +# define umul_ppmm(w1, w0, u, v) \ + asm("mulu %3,%2,%1,%0" : "=r"(w0), "=r"(w1) : "r"(u), "r"(v)) +# define smul_ppmm(w1, w0, u, v) \ + asm("mul %3,%2,%1,%0" : "=r"(w0), "=r"(w1) : "r"(u), "r"(v)) +# else +# define umul_ppmm(w1, w0, u, v) \ + asm("nop; nop; mulu %3,%0" : "=d"(w0), "=z"(w1) : "%0"(u), "d"(v)) +# define smul_ppmm(w1, w0, u, v) \ + asm("nop; nop; mul %3,%0" : "=d"(w0), "=z"(w1) : "%0"(u), "d"(v)) +# endif +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + DWunion __s, __a, __b; \ + __a.s.low = (al); __a.s.high = (ah); \ + __b.s.low = (bl); __b.s.high = (bh); \ + __s.ll = __a.ll + __b.ll; \ + (sl) = __s.s.low; (sh) = __s.s.high; \ + } while (0) +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + DWunion __s, __a, __b; \ + __a.s.low = (al); __a.s.high = (ah); \ + __b.s.low = (bl); __b.s.high = (bh); \ + __s.ll = __a.ll - __b.ll; \ + (sl) = __s.s.low; (sh) = __s.s.high; \ + } while (0) +# define udiv_qrnnd(q, r, nh, nl, d) \ + asm("divu %2,%0" : "=D"(q), "=z"(r) : "D"(d), "0"(nl), "1"(nh)) +# define sdiv_qrnnd(q, r, nh, nl, d) \ + asm("div %2,%0" : "=D"(q), "=z"(r) : "D"(d), "0"(nl), "1"(nh)) +# define UMUL_TIME 3 +# define UDIV_TIME 38 +#endif + #if defined (__mips__) && W_TYPE_SIZE == 32 #define umul_ppmm(w1, w0, u, v) \ do { \ @@ -926,8 +1050,7 @@ UDItype __umulsidi3 (USItype, USItype); #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("clrt;subc %5,%1; subc %4,%0" \ : "=r" (sh), "=r" (sl) \ - : "0" (ah), "1" (al), "r" (bh), "r" (bl) \ - : "t") + : "0" (ah), "1" (al), "r" (bh), "r" (bl) : "t") #endif /* __sh__ */ @@ -1261,6 +1384,28 @@ UDItype __umulsidi3 (USItype, USItype); #define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) #endif /* __xtensa__ */ +#if defined xstormy16 +extern UHItype __stormy16_count_leading_zeros (UHItype); +#define count_leading_zeros(count, x) \ + do \ + { \ + UHItype size; \ + \ + /* We assume that W_TYPE_SIZE is a multiple of 16... */ \ + for ((count) = 0, size = W_TYPE_SIZE; size; size -= 16) \ + { \ + UHItype c; \ + \ + c = __clzhi2 ((x) >> (size - 16)); \ + (count) += c; \ + if (c != 16) \ + break; \ + } \ + } \ + while (0) +#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE +#endif + #if defined (__z8000__) && W_TYPE_SIZE == 16 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ diff --git a/libc/string/_strerror.c b/libc/string/_strerror.c index cb5d9e360..ad9b14810 100644 --- a/libc/string/_strerror.c +++ b/libc/string/_strerror.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,93,95,96,97,98,2000,2002,2006 +/* Copyright (C) 1991,93,95,96,97,98,2000,2002,2006,2011 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -18,7 +18,9 @@ 02111-1307 USA. */ #include <libintl.h> +#include <stdbool.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <sys/param.h> #include <stdio-common/_itoa.h> @@ -43,15 +45,21 @@ __strerror_r (int errnum, char *buf, size_t buflen) `int' of 8 bytes we never need more than 20 digits. */ char numbuf[21]; const char *unk = _("Unknown error "); - const size_t unklen = strlen (unk); + size_t unklen = strlen (unk); char *p, *q; + bool negative = errnum < 0; numbuf[20] = '\0'; - p = _itoa_word (errnum, &numbuf[20], 10, 0); + p = _itoa_word (abs (errnum), &numbuf[20], 10, 0); /* Now construct the result while taking care for the destination buffer size. */ q = __mempcpy (buf, unk, MIN (unklen, buflen)); + if (negative && unklen < buflen) + { + *q++ = '-'; + ++unklen; + } if (unklen < buflen) memcpy (q, p, MIN ((size_t) (&numbuf[21] - p), buflen - unklen)); diff --git a/libc/string/xpg-strerror.c b/libc/string/xpg-strerror.c index 8d898122d..10fc1bf99 100644 --- a/libc/string/xpg-strerror.c +++ b/libc/string/xpg-strerror.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2010 +/* Copyright (C) 1991, 1993, 1995-1998, 2000, 2002, 2004, 2010, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -17,36 +17,32 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <assert.h> #include <errno.h> -#include <libintl.h> #include <stdio.h> #include <string.h> #include <sys/param.h> -#include <stdio-common/_itoa.h> -/* It is critical here that we always use the `dcgettext' function for - the message translation. Since <libintl.h> only defines the macro - `dgettext' to use `dcgettext' for optimizing programs this is not - always guaranteed. */ -#ifndef dgettext -# include <locale.h> /* We need LC_MESSAGES. */ -# define dgettext(domainname, msgid) dcgettext (domainname, msgid, LC_MESSAGES) -#endif /* Fill buf with a string describing the errno code in ERRNUM. */ int __xpg_strerror_r (int errnum, char *buf, size_t buflen) { - if (errnum < 0 || errnum >= _sys_nerr_internal - || _sys_errlist_internal[errnum] == NULL) - return EINVAL; - - const char *estr = (const char *) _(_sys_errlist_internal[errnum]); - size_t estrlen = strlen (estr) + 1; - - if (buflen < estrlen) - return ERANGE; - - memcpy (buf, estr, estrlen); - return 0; + const char *estr = __strerror_r (errnum, buf, buflen); + size_t estrlen = strlen (estr); + + if (estr == buf) + { + assert (errnum < 0 || errnum >= _sys_nerr_internal + || _sys_errlist_internal[errnum] == NULL); + return EINVAL; + } + assert (errnum >= 0 && errnum < _sys_nerr_internal + && _sys_errlist_internal[errnum] != NULL); + + /* Terminate the string in any case. */ + if (buflen > 0) + *((char *) __mempcpy (buf, estr, MIN (buflen - 1, estrlen))) = '\0'; + + return buflen <= estrlen ? ERANGE : 0; } diff --git a/libc/sysdeps/posix/getaddrinfo.c b/libc/sysdeps/posix/getaddrinfo.c index 7bd89c45c..5ddda889c 100644 --- a/libc/sysdeps/posix/getaddrinfo.c +++ b/libc/sysdeps/posix/getaddrinfo.c @@ -278,6 +278,7 @@ gaih_inet (const char *name, const struct gaih_service *service, bool got_ipv6 = false; const char *canon = NULL; const char *orig_name = name; + size_t alloca_used = 0; if (req->ai_protocol || req->ai_socktype) { @@ -310,7 +311,7 @@ gaih_inet (const char *name, const struct gaih_service *service, if (tp->name[0]) { st = (struct gaih_servtuple *) - __alloca (sizeof (struct gaih_servtuple)); + alloca_account (sizeof (struct gaih_servtuple), alloca_used); if ((rc = gaih_inet_serv (service->name, tp, req, st))) return rc; @@ -334,7 +335,8 @@ gaih_inet (const char *name, const struct gaih_service *service, continue; newp = (struct gaih_servtuple *) - __alloca (sizeof (struct gaih_servtuple)); + alloca_account (sizeof (struct gaih_servtuple), + alloca_used); if ((rc = gaih_inet_serv (service->name, tp, req, newp))) { @@ -362,7 +364,7 @@ gaih_inet (const char *name, const struct gaih_service *service, if (req->ai_socktype || req->ai_protocol) { - st = __alloca (sizeof (struct gaih_servtuple)); + st = alloca_account (sizeof (struct gaih_servtuple), alloca_used); st->next = NULL; st->socktype = tp->socktype; st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) @@ -379,7 +381,8 @@ gaih_inet (const char *name, const struct gaih_service *service, { struct gaih_servtuple *newp; - newp = __alloca (sizeof (struct gaih_servtuple)); + newp = alloca_account (sizeof (struct gaih_servtuple), + alloca_used); newp->next = NULL; newp->socktype = tp->socktype; newp->protocol = tp->protocol; @@ -391,10 +394,17 @@ gaih_inet (const char *name, const struct gaih_service *service, } } + bool malloc_name = false; + bool malloc_addrmem = false; + struct gaih_addrtuple *addrmem = NULL; + bool malloc_canonbuf = false; + char *canonbuf = NULL; + bool malloc_tmpbuf = false; + char *tmpbuf = NULL; + int result = 0; if (name != NULL) { - at = __alloca (sizeof (struct gaih_addrtuple)); - + at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); at->family = AF_UNSPEC; at->scopeid = 0; at->next = NULL; @@ -412,6 +422,7 @@ gaih_inet (const char *name, const struct gaih_service *service, rc = __idna_to_ascii_lz (name, &p, idn_flags); if (rc != IDNA_SUCCESS) { + /* No need to jump to free_and_return here. */ if (rc == IDNA_MALLOC_ERROR) return -EAI_MEMORY; if (rc == IDNA_DLOPEN_ERROR) @@ -421,10 +432,7 @@ gaih_inet (const char *name, const struct gaih_service *service, /* In case the output string is the same as the input string no new string has been allocated. */ if (p != name) - { - name = strdupa (p); - free (p); - } + malloc_name = true; } #endif @@ -441,23 +449,59 @@ gaih_inet (const char *name, const struct gaih_service *service, at->family = AF_INET6; } else - return -EAI_ADDRFAMILY; + { + result = -EAI_ADDRFAMILY; + goto free_and_return; + } if (req->ai_flags & AI_CANONNAME) canon = name; } else if (at->family == AF_UNSPEC) { - char *namebuf = (char *) name; char *scope_delim = strchr (name, SCOPE_DELIMITER); + int e; - if (__builtin_expect (scope_delim != NULL, 0)) - { - namebuf = alloca (scope_delim - name + 1); - *((char *) __mempcpy (namebuf, name, scope_delim - name)) = '\0'; - } + { + bool malloc_namebuf = false; + char *namebuf = (char *) name; - if (inet_pton (AF_INET6, namebuf, at->addr) > 0) + if (__builtin_expect (scope_delim != NULL, 0)) + { + if (malloc_name) + *scope_delim = '\0'; + else + { + if (__libc_use_alloca (alloca_used + + scope_delim - name + 1)) + { + namebuf = alloca_account (scope_delim - name + 1, + alloca_used); + *((char *) __mempcpy (namebuf, name, + scope_delim - name)) = '\0'; + } + else + { + namebuf = strndup (name, scope_delim - name); + if (namebuf == NULL) + { + assert (!malloc_name); + return -EAI_MEMORY; + } + malloc_namebuf = true; + } + } + } + + e = inet_pton (AF_INET6, namebuf, at->addr); + + if (malloc_namebuf) + free (namebuf); + else if (scope_delim != NULL && malloc_name) + /* Undo what we did above. */ + *scope_delim = SCOPE_DELIMITER; + } + if (e > 0) { if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) at->family = AF_INET6; @@ -468,7 +512,10 @@ gaih_inet (const char *name, const struct gaih_service *service, at->family = AF_INET; } else - return -EAI_ADDRFAMILY; + { + result = -EAI_ADDRFAMILY; + goto free_and_return; + } if (scope_delim != NULL) { @@ -490,7 +537,10 @@ gaih_inet (const char *name, const struct gaih_service *service, at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end, 10); if (*end != '\0') - return GAIH_OKIFUNSPEC | -EAI_NONAME; + { + result = GAIH_OKIFUNSPEC | -EAI_NONAME; + goto free_and_return; + } } } @@ -517,7 +567,8 @@ gaih_inet (const char *name, const struct gaih_service *service, { int family = req->ai_family; size_t tmpbuflen = 512; - char *tmpbuf = alloca (tmpbuflen); + assert (tmpbuf == NULL); + tmpbuf = alloca_account (tmpbuflen, alloca_used); int rc; struct hostent th; struct hostent *h; @@ -529,50 +580,95 @@ gaih_inet (const char *name, const struct gaih_service *service, tmpbuflen, &h, &herrno); if (rc != ERANGE || herrno != NETDB_INTERNAL) break; - tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); + + if (!malloc_tmpbuf + && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) + tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, + 2 * tmpbuflen, + alloca_used); + else + { + char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, + 2 * tmpbuflen); + if (newp == NULL) + { + result = -EAI_MEMORY; + goto free_and_return; + } + tmpbuf = newp; + malloc_tmpbuf = true; + tmpbuflen = 2 * tmpbuflen; + } } if (rc == 0) { if (h != NULL) - /* We found data, now convert it into the list. */ - for (int i = 0; h->h_addr_list[i]; ++i) - { - if (*pat == NULL) - { - *pat = __alloca (sizeof (struct gaih_addrtuple)); - (*pat)->scopeid = 0; - } - (*pat)->next = NULL; - (*pat)->family = req->ai_family; - if (family == req->ai_family) - memcpy ((*pat)->addr, h->h_addr_list[i], - h->h_length); - else - { - uint32_t *addr = (uint32_t *) (*pat)->addr; - addr[3] = *(uint32_t *) h->h_addr_list[i]; - addr[2] = htonl (0xffff); - addr[1] = 0; - addr[0] = 0; - } - pat = &((*pat)->next); - } + { + int i; + /* We found data, count the number of addresses. */ + for (i = 0; h->h_addr_list[i]; ++i) + ; + if (i > 0 && *pat != NULL) + --i; + + if (__libc_use_alloca (alloca_used + + i * sizeof (struct gaih_addrtuple))) + addrmem = alloca_account (i * sizeof (struct gaih_addrtuple), + alloca_used); + else + { + addrmem = malloc (i + * sizeof (struct gaih_addrtuple)); + if (addrmem == NULL) + { + result = -EAI_MEMORY; + goto free_and_return; + } + malloc_addrmem = true; + } + + /* Now convert it into the list. */ + struct gaih_addrtuple *addrfree = addrmem; + for (i = 0; h->h_addr_list[i]; ++i) + { + if (*pat == NULL) + { + *pat = addrfree++; + (*pat)->scopeid = 0; + } + (*pat)->next = NULL; + (*pat)->family = req->ai_family; + if (family == req->ai_family) + memcpy ((*pat)->addr, h->h_addr_list[i], + h->h_length); + else + { + uint32_t *addr = (uint32_t *) (*pat)->addr; + addr[3] = *(uint32_t *) h->h_addr_list[i]; + addr[2] = htonl (0xffff); + addr[1] = 0; + addr[0] = 0; + } + pat = &((*pat)->next); + } + } } else { if (herrno == NETDB_INTERNAL) { __set_h_errno (herrno); - return -EAI_SYSTEM; + result = -EAI_SYSTEM; } - if (herrno == TRY_AGAIN) - { - return -EAI_AGAIN; - } - /* We made requests but they turned out no data. - The name is known, though. */ - return GAIH_OKIFUNSPEC | -EAI_NODATA; + else if (herrno == TRY_AGAIN) + result = -EAI_AGAIN; + else + /* We made requests but they turned out no data. + The name is known, though. */ + result = GAIH_OKIFUNSPEC | -EAI_NODATA; + + goto free_and_return; } goto process_list; @@ -596,21 +692,56 @@ gaih_inet (const char *name, const struct gaih_service *service, bool added_canon = (req->ai_flags & AI_CANONNAME) == 0; char *addrs = air->addrs; + if (__libc_use_alloca (alloca_used + + air->naddrs * sizeof (struct gaih_addrtuple))) + addrmem = alloca_account (air->naddrs + * sizeof (struct gaih_addrtuple), + alloca_used); + else + { + addrmem = malloc (air->naddrs + * sizeof (struct gaih_addrtuple)); + if (addrmem == NULL) + { + result = -EAI_MEMORY; + goto free_and_return; + } + malloc_addrmem = true; + } + + struct gaih_addrtuple *addrfree = addrmem; for (int i = 0; i < air->naddrs; ++i) { socklen_t size = (air->family[i] == AF_INET ? INADDRSZ : IN6ADDRSZ); if (*pat == NULL) { - *pat = __alloca (sizeof (struct gaih_addrtuple)); + *pat = addrfree++; (*pat)->scopeid = 0; } uint32_t *pataddr = (*pat)->addr; (*pat)->next = NULL; if (added_canon || air->canon == NULL) (*pat)->name = NULL; - else - canon = (*pat)->name = strdupa (air->canon); + else if (canonbuf == NULL) + { + size_t canonlen = strlen (air->canon) + 1; + if ((req->ai_flags & AI_CANONIDN) != 0 + && __libc_use_alloca (alloca_used + canonlen)) + canonbuf = alloca_account (canonlen, alloca_used); + else + { + canonbuf = malloc (canonlen); + if (canonbuf == NULL) + { + result = -EAI_MEMORY; + goto free_and_return; + } + malloc_canonbuf = true; + } + canon = (*pat)->name = memcpy (canonbuf, air->canon, + canonlen); + } if (air->family[i] == AF_INET && req->ai_family == AF_INET6 @@ -640,20 +771,26 @@ gaih_inet (const char *name, const struct gaih_service *service, free (air); if (at->family == AF_UNSPEC) - return GAIH_OKIFUNSPEC | -EAI_NONAME; + { + result = GAIH_OKIFUNSPEC | -EAI_NONAME; + goto free_and_return; + } goto process_list; } else if (err == 0) /* The database contains a negative entry. */ - return 0; + goto free_and_return; else if (__nss_not_use_nscd_hosts == 0) { if (herrno == NETDB_INTERNAL && errno == ENOMEM) - return -EAI_MEMORY; - if (herrno == TRY_AGAIN) - return -EAI_AGAIN; - return -EAI_SYSTEM; + result = -EAI_MEMORY; + else if (herrno == TRY_AGAIN) + result = -EAI_AGAIN; + else + result = -EAI_SYSTEM; + + goto free_and_return; } } #endif @@ -682,7 +819,19 @@ gaih_inet (const char *name, const struct gaih_service *service, _res.options &= ~RES_USE_INET6; size_t tmpbuflen = 1024; - char *tmpbuf = alloca (tmpbuflen); + malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen); + assert (tmpbuf == NULL); + if (malloc_tmpbuf) + tmpbuf = alloca_account (tmpbuflen, alloca_used); + else + { + tmpbuf = malloc (tmpbuflen); + if (tmpbuf == NULL) + { + result = -EAI_MEMORY; + goto free_and_return; + } + } while (!no_more) { @@ -711,8 +860,25 @@ gaih_inet (const char *name, const struct gaih_service *service, no_data = herrno == NO_DATA; break; } - tmpbuf = extend_alloca (tmpbuf, - tmpbuflen, 2 * tmpbuflen); + + if (!malloc_tmpbuf + && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) + tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, + 2 * tmpbuflen, + alloca_used); + else + { + char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, + 2 * tmpbuflen); + if (newp == NULL) + { + result = -EAI_MEMORY; + goto free_and_return; + } + tmpbuf = newp; + malloc_tmpbuf = true; + tmpbuflen = 2 * tmpbuflen; + } } no_inet6_data = no_data; @@ -787,18 +953,40 @@ gaih_inet (const char *name, const struct gaih_service *service, if (cfct != NULL) { const size_t max_fqdn_len = 256; - char *buf = alloca (max_fqdn_len); + if ((req->ai_flags & AI_CANONIDN) != 0 + && __libc_use_alloca (alloca_used + + max_fqdn_len)) + canonbuf = alloca_account (max_fqdn_len, + alloca_used); + else + { + canonbuf = malloc (max_fqdn_len); + if (canonbuf == NULL) + { + result = -EAI_MEMORY; + goto free_and_return; + } + malloc_canonbuf = true; + } char *s; if (DL_CALL_FCT (cfct, (at->name ?: name, - buf, max_fqdn_len, + canonbuf, + max_fqdn_len, &s, &rc, &herrno)) == NSS_STATUS_SUCCESS) canon = s; else - /* Set to name now to avoid using - gethostbyaddr. */ - canon = name; + { + /* Set to name now to avoid using + gethostbyaddr. */ + if (malloc_canonbuf) + { + free (canonbuf); + malloc_canonbuf = false; + } + canon = name; + } } } status = NSS_STATUS_SUCCESS; @@ -833,22 +1021,27 @@ gaih_inet (const char *name, const struct gaih_service *service, { /* If both requests timed out report this. */ if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN) - return -EAI_AGAIN; + result = -EAI_AGAIN; + else + /* We made requests but they turned out no data. The name + is known, though. */ + result = GAIH_OKIFUNSPEC | -EAI_NODATA; - /* We made requests but they turned out no data. The name - is known, though. */ - return GAIH_OKIFUNSPEC | -EAI_NODATA; + goto free_and_return; } } process_list: if (at->family == AF_UNSPEC) - return GAIH_OKIFUNSPEC | -EAI_NONAME; + { + result = GAIH_OKIFUNSPEC | -EAI_NONAME; + goto free_and_return; + } } else { struct gaih_addrtuple *atr; - atr = at = __alloca (sizeof (struct gaih_addrtuple)); + atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); memset (at, '\0', sizeof (struct gaih_addrtuple)); if (req->ai_family == AF_UNSPEC) @@ -887,30 +1080,56 @@ gaih_inet (const char *name, const struct gaih_service *service, /* Only the first entry gets the canonical name. */ if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0) { + char *tmpbuf2 = NULL; + bool malloc_tmpbuf2 = false; + if (canon == NULL) { struct hostent *h = NULL; int herrno; struct hostent th; - size_t tmpbuflen = 512; - char *tmpbuf = NULL; + size_t tmpbuf2len = 512; do { - tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2); + if (__libc_use_alloca (alloca_used + 2 * tmpbuf2len)) + tmpbuf2 = extend_alloca_account (tmpbuf2, tmpbuf2len, + tmpbuf2len * 2, + alloca_used); + else + { + char *newp = realloc (malloc_tmpbuf2 ? tmpbuf2 : NULL, + 2 * tmpbuf2len); + if (newp == NULL) + { + if (malloc_tmpbuf2) + free (tmpbuf2); + result = -EAI_MEMORY; + goto free_and_return; + } + + tmpbuf2 = newp; + tmpbuf2len = 2 * tmpbuf2len; + malloc_tmpbuf2 = true; + } + rc = __gethostbyaddr_r (at2->addr, ((at2->family == AF_INET6) ? sizeof (struct in6_addr) : sizeof (struct in_addr)), - at2->family, &th, tmpbuf, - tmpbuflen, &h, &herrno); + at2->family, &th, tmpbuf2, + tmpbuf2len, &h, &herrno); } while (rc == ERANGE && herrno == NETDB_INTERNAL); if (rc != 0 && herrno == NETDB_INTERNAL) { + if (malloc_tmpbuf2) + free (tmpbuf2); + __set_h_errno (herrno); - return -EAI_SYSTEM; + result = -EAI_SYSTEM; + goto free_and_return; } if (h != NULL) @@ -937,11 +1156,16 @@ gaih_inet (const char *name, const struct gaih_service *service, int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags); if (rc != IDNA_SUCCESS) { + if (malloc_tmpbuf2) + free (tmpbuf2); + if (rc == IDNA_MALLOC_ERROR) - return -EAI_MEMORY; - if (rc == IDNA_DLOPEN_ERROR) - return -EAI_SYSTEM; - return -EAI_IDN_ENCODE; + result = -EAI_MEMORY; + else if (rc == IDNA_DLOPEN_ERROR) + result = -EAI_SYSTEM; + else + result = -EAI_IDN_ENCODE; + goto free_and_return; } /* In case the output string is the same as the input string no new string has been allocated and we @@ -956,10 +1180,25 @@ gaih_inet (const char *name, const struct gaih_service *service, #ifdef HAVE_LIBIDN make_copy: #endif - canon = strdup (canon); - if (canon == NULL) - return -EAI_MEMORY; + if (malloc_canonbuf) + /* We already allocated the string using malloc. */ + malloc_canonbuf = false; + else + { + canon = strdup (canon); + if (canon == NULL) + { + if (malloc_tmpbuf2) + free (tmpbuf2); + + result = -EAI_MEMORY; + goto free_and_return; + } + } } + + if (malloc_tmpbuf2) + free (tmpbuf2); } family = at2->family; @@ -985,7 +1224,8 @@ gaih_inet (const char *name, const struct gaih_service *service, if (ai == NULL) { free ((char *) canon); - return -EAI_MEMORY; + result = -EAI_MEMORY; + goto free_and_return; } ai->ai_flags = req->ai_flags; @@ -1038,7 +1278,18 @@ gaih_inet (const char *name, const struct gaih_service *service, at2 = at2->next; } } - return 0; + + free_and_return: + if (malloc_name) + free ((char *) name); + if (malloc_addrmem) + free (addrmem); + if (malloc_canonbuf) + free (canonbuf); + if (malloc_tmpbuf) + free (tmpbuf); + + return result; } diff --git a/libc/sysdeps/powerpc/powerpc64/Makefile b/libc/sysdeps/powerpc/powerpc64/Makefile index 78d4f07e5..136de3008 100644 --- a/libc/sysdeps/powerpc/powerpc64/Makefile +++ b/libc/sysdeps/powerpc/powerpc64/Makefile @@ -12,7 +12,10 @@ endif # These flags prevent FPU or Altivec registers from being used, # for code called in contexts that is not allowed to touch those registers. -# Stupid GCC requires us to pass all these ridiculous switches. +# Stupid GCC requires us to pass all these ridiculous switches. We need to +# pass the -mno-* switches as well to prevent the compiler from attempting +# to emit altivec or vsx instructions, especially when the registers aren't +# available. no-special-regs := $(sort $(foreach n,40 41 50 51 60 61 62 63 \ $(foreach m,2 3 4 5 6 7 8 9, \ 3$m 4$m 5$m),\ @@ -20,7 +23,7 @@ no-special-regs := $(sort $(foreach n,40 41 50 51 60 61 62 63 \ $(sort $(foreach n,$(foreach m,0 1 2 3 4 5 6 7 8 9,\ $m 1$m 2$m) 30 31,\ -ffixed-v$n)) \ - -ffixed-vrsave -ffixed-vscr + -ffixed-vrsave -ffixed-vscr -mno-altivec -mno-vsx ifeq ($(subdir),csu) sysdep_routines += hp-timing diff --git a/libc/sysdeps/unix/sysv/linux/bits/time.h b/libc/sysdeps/unix/sysv/linux/bits/time.h index a0d4b7823..40f9a64fa 100644 --- a/libc/sysdeps/unix/sysv/linux/bits/time.h +++ b/libc/sysdeps/unix/sysv/linux/bits/time.h @@ -73,6 +73,10 @@ extern long int __sysconf (int); # define CLOCK_MONOTONIC_COARSE 6 /* Monotonic system-wide clock that includes time spent in suspension. */ # define CLOCK_BOOTTIME 7 +/* Like CLOCK_REALTIME but also wakes suspended system. */ +# define CLOCK_REALTIME_ALARM 8 +/* Like CLOCK_BOOTTIME but also wakes suspended system. */ +# define CLOCK_BOOTTIME_ALARM 9 /* Flag to indicate time is absolute. */ # define TIMER_ABSTIME 1 diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sysconf.c b/libc/sysdeps/unix/sysv/linux/ia64/sysconf.c index 67b8251dd..732cc68ef 100644 --- a/libc/sysdeps/unix/sysv/linux/ia64/sysconf.c +++ b/libc/sysdeps/unix/sysv/linux/ia64/sysconf.c @@ -24,7 +24,7 @@ #include "has_cpuclock.c" -#define HAS_CPUCLOCK() (has_cpuclock () ? _POSIX_VERSION : -1) +#define HAS_CPUCLOCK(name) (has_cpuclock () ? _POSIX_VERSION : -1) /* Now the generic Linux version. */ diff --git a/libc/sysdeps/unix/sysv/linux/sysconf.c b/libc/sysdeps/unix/sysv/linux/sysconf.c index e44aa994e..6e6c69e12 100644 --- a/libc/sysdeps/unix/sysv/linux/sysconf.c +++ b/libc/sysdeps/unix/sysv/linux/sysconf.c @@ -37,7 +37,7 @@ static long int posix_sysconf (int name); #ifndef HAS_CPUCLOCK static long int -has_cpuclock (void) +has_cpuclock (int name) { # if defined __NR_clock_getres || HP_TIMING_AVAIL /* If we have HP_TIMING, we will fall back on that if the system @@ -59,7 +59,7 @@ has_cpuclock (void) return -1; # endif } -# define HAS_CPUCLOCK() has_cpuclock () +# define HAS_CPUCLOCK(name) has_cpuclock (name) #endif @@ -86,7 +86,7 @@ __sysconf (int name) case _SC_CPUTIME: case _SC_THREAD_CPUTIME: - return HAS_CPUCLOCK (); + return HAS_CPUCLOCK (name); case _SC_ARG_MAX: #if __LINUX_KERNEL_VERSION < 0x020617 diff --git a/libc/sysdeps/x86_64/fpu/e_powl.S b/libc/sysdeps/x86_64/fpu/e_powl.S index 4959bea7a..a0b1b1df1 100644 --- a/libc/sysdeps/x86_64/fpu/e_powl.S +++ b/libc/sysdeps/x86_64/fpu/e_powl.S @@ -1,5 +1,5 @@ /* ix87 specific implementation of pow function. - Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2007 + Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2007, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -154,7 +154,7 @@ ENTRY(__ieee754_powl) fucompp // 1.0 : x : y fnstsw fxch // x : 1.0 : y - test $4500,%eax + test $0x4500,%eax jz 7f fsub %st(1) // x-1 : 1.0 : y fyl2xp1 // log2(x) : y |