[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[commits] r13914 - in /fsf/trunk/libc: ./ include/ libio/ locale/ localedata/ stdio-common/ sysdeps/posix/
- To: commits@xxxxxxxxxx
- Subject: [commits] r13914 - in /fsf/trunk/libc: ./ include/ libio/ locale/ localedata/ stdio-common/ sysdeps/posix/
- From: eglibc@xxxxxxxxxx
- Date: Sat, 21 May 2011 07:03:52 -0000
Author: eglibc
Date: Sat May 21 00:03:50 2011
New Revision: 13914
Log:
Import glibc-mainline for 2011-05-21
Added:
fsf/trunk/libc/localedata/bug-setlocale1.c (with props)
Modified:
fsf/trunk/libc/ChangeLog
fsf/trunk/libc/NEWS
fsf/trunk/libc/include/alloca.h
fsf/trunk/libc/libio/filedoalloc.c
fsf/trunk/libc/locale/setlocale.c
fsf/trunk/libc/localedata/ChangeLog
fsf/trunk/libc/localedata/Makefile
fsf/trunk/libc/stdio-common/perror.c
fsf/trunk/libc/stdio-common/vfprintf.c
fsf/trunk/libc/sysdeps/posix/getaddrinfo.c
Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Sat May 21 00:03:50 2011
@@ -1,4 +1,23 @@
+2011-05-21 Ulrich Drepper <drepper@xxxxxxxxx>
+
+ [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@xxxxxxxxx>
+
+ [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
Modified: fsf/trunk/libc/NEWS
==============================================================================
--- fsf/trunk/libc/NEWS (original)
+++ fsf/trunk/libc/NEWS Sat May 21 00:03:50 2011
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes. 2011-5-20
+GNU C Library NEWS -- history of user-visible changes. 2011-5-21
Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc.
See the end for copying conditions.
@@ -11,12 +11,12 @@
386, 6420, 7101, 9730, 9732, 9809, 10138, 10149, 10157, 11257, 11258,
11487, 11532, 11578, 11653, 11668, 11697, 11724, 11820, 11837, 11857,
- 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, 12775
+ 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, 12681, 12685, 12711, 12713, 12714,
+ 12717, 12723, 12724, 12734, 12738, 12746, 12766, 12775, 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.
Modified: fsf/trunk/libc/include/alloca.h
==============================================================================
--- fsf/trunk/libc/include/alloca.h (original)
+++ fsf/trunk/libc/include/alloca.h Sat May 21 00:03:50 2011
@@ -49,15 +49,24 @@
#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
Modified: fsf/trunk/libc/libio/filedoalloc.c
==============================================================================
--- fsf/trunk/libc/libio/filedoalloc.c (original)
+++ fsf/trunk/libc/libio/filedoalloc.c Sat May 21 00:03:50 2011
@@ -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
@@ -73,6 +73,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.
@@ -109,7 +120,7 @@
#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
Modified: fsf/trunk/libc/locale/setlocale.c
==============================================================================
--- fsf/trunk/libc/locale/setlocale.c (original)
+++ fsf/trunk/libc/locale/setlocale.c Sat May 21 00:03:50 2011
@@ -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.
@@ -155,7 +155,7 @@
_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;
}
Modified: fsf/trunk/libc/localedata/ChangeLog
==============================================================================
--- fsf/trunk/libc/localedata/ChangeLog (original)
+++ fsf/trunk/libc/localedata/ChangeLog Sat May 21 00:03:50 2011
@@ -1,3 +1,9 @@
+2011-05-21 Ulrich Drepper <drepper@xxxxxxxxx>
+
+ [BZ #12788]
+ * bug-setlocale1.c: New file.
+ * Makefile: Add rules to build and run bug-setlocale1.
+
2011-05-17 Ulrich Drepper <drepper@xxxxxxxxx>
[BZ #11837]
Modified: fsf/trunk/libc/localedata/Makefile
==============================================================================
--- fsf/trunk/libc/localedata/Makefile (original)
+++ fsf/trunk/libc/localedata/Makefile Sat May 21 00:03:50 2011
@@ -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
@@ -94,7 +94,7 @@
tests = $(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 (yes,$(build-shared))
ifneq (no,$(PERL))
tests: $(objpfx)mtrace-tst-leaks
@@ -301,5 +301,8 @@
$(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 $@
Added: fsf/trunk/libc/localedata/bug-setlocale1.c
==============================================================================
--- fsf/trunk/libc/localedata/bug-setlocale1.c (added)
+++ fsf/trunk/libc/localedata/bug-setlocale1.c Sat May 21 00:03:50 2011
@@ -1,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"
Propchange: fsf/trunk/libc/localedata/bug-setlocale1.c
------------------------------------------------------------------------------
svn:mime-type = text/cpp
Modified: fsf/trunk/libc/stdio-common/perror.c
==============================================================================
--- fsf/trunk/libc/stdio-common/perror.c (original)
+++ fsf/trunk/libc/stdio-common/perror.c Sat May 21 00:03:50 2011
@@ -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 @@
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);
}
Modified: fsf/trunk/libc/stdio-common/vfprintf.c
==============================================================================
--- fsf/trunk/libc/stdio-common/vfprintf.c (original)
+++ fsf/trunk/libc/stdio-common/vfprintf.c Sat May 21 00:03:50 2011
@@ -52,6 +52,7 @@
CHECK_FILE (S, -1); \
if (S->_flags & _IO_NO_WRITES) \
{ \
+ S->_flags |= _IO_ERR_SEEN; \
__set_errno (EBADF); \
return -1; \
} \
Modified: fsf/trunk/libc/sysdeps/posix/getaddrinfo.c
==============================================================================
--- fsf/trunk/libc/sysdeps/posix/getaddrinfo.c (original)
+++ fsf/trunk/libc/sysdeps/posix/getaddrinfo.c Sat May 21 00:03:50 2011
@@ -278,6 +278,7 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
}
}
+ 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 @@
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 @@
/* 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 @@
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);
-
- if (__builtin_expect (scope_delim != NULL, 0))
- {
- namebuf = alloca (scope_delim - name + 1);
- *((char *) __mempcpy (namebuf, name, scope_delim - name)) = '\0';
- }
-
- if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
+ int e;
+
+ {
+ bool malloc_namebuf = false;
+ char *namebuf = (char *) name;
+
+ 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 @@
at->family = AF_INET;
}
else
- return -EAI_ADDRFAMILY;
+ {
+ result = -EAI_ADDRFAMILY;
+ goto free_and_return;
+ }
if (scope_delim != NULL)
{
@@ -490,7 +537,10 @@
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 @@
{
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 @@
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 @@
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 @@
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 @@
_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 @@
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 @@
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 @@
{
/* If both requests timed out report this. */
if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
- return -EAI_AGAIN;
-
- /* We made requests but they turned out no data. The name
- is known, though. */
- return GAIH_OKIFUNSPEC | -EAI_NODATA;
+ 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;
}
}
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 @@
/* 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 @@
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 @@
#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 @@
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 @@
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;
}