summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2011-05-23 19:23:42 +0000
committerjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2011-05-23 19:23:42 +0000
commitf56b42ffd93eb64a1f1aefe7c4f2bd4e2eccafe1 (patch)
treedf3ef049c083145202dbf19598acf56ef1b41afa /libc
parente9d94bb485578797a67a3ef6dae7ac9e3635e963 (diff)
downloadeglibc2-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')
-rw-r--r--libc/ChangeLog94
-rw-r--r--libc/NEWS17
-rwxr-xr-xlibc/configure6
-rw-r--r--libc/configure.in8
-rw-r--r--libc/elf/dl-runtime.c12
-rw-r--r--libc/grp/compat-initgroups.c6
-rw-r--r--libc/iconvdata/CP1258.irreversible2
-rw-r--r--libc/iconvdata/cp1258.c18
-rw-r--r--libc/include/alloca.h19
-rw-r--r--libc/libio/filedoalloc.c17
-rw-r--r--libc/libio/freopen.c2
-rw-r--r--libc/libio/freopen64.c2
-rw-r--r--libc/locale/setlocale.c4
-rw-r--r--libc/localedata/ChangeLog6
-rw-r--r--libc/localedata/Makefile7
-rw-r--r--libc/localedata/bug-setlocale1.c132
-rw-r--r--libc/math/Makefile3
-rw-r--r--libc/math/test-powl.c51
-rw-r--r--libc/nis/nss_nis/nis-alias.c43
-rw-r--r--libc/nscd/nscd_getserv_r.c59
-rw-r--r--libc/posix/glob.c363
-rw-r--r--libc/posix/regex.h13
-rw-r--r--libc/stdio-common/perror.c7
-rw-r--r--libc/stdio-common/vfprintf.c1
-rw-r--r--libc/stdlib/longlong.h155
-rw-r--r--libc/string/_strerror.c14
-rw-r--r--libc/string/xpg-strerror.c42
-rw-r--r--libc/sysdeps/posix/getaddrinfo.c433
-rw-r--r--libc/sysdeps/powerpc/powerpc64/Makefile7
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/time.h4
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sysconf.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sysconf.c6
-rw-r--r--libc/sysdeps/x86_64/fpu/e_powl.S4
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.
diff --git a/libc/NEWS b/libc/NEWS
index 6fe707449..f3150f2aa 100644
--- a/libc/NEWS
+++ b/libc/NEWS
@@ -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