From c0bc5f7b8fd62dfa566dd3adb91f3a1ee8db6aeb Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 23 Mar 2000 21:34:58 +0000 Subject: Update. 2000-03-23 Bruno Haible * iconv/gconv_simple.c (internal_ucs4_loop, internal_ucs4le_loop): Remove no-op pointer increment. --- ChangeLog | 5 +++ iconv/gconv_simple.c | 6 --- inet/getnameinfo.c | 107 ++++++++++++++++++++++++++++++++------------ inet/netinet/in.h | 3 +- linuxthreads/ChangeLog | 5 +++ linuxthreads/manager.c | 6 ++- resolv/netdb.h | 5 +++ sysdeps/posix/getaddrinfo.c | 75 +++++++++++++++++++++++-------- 8 files changed, 156 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4cc3efbf91..81d0653bb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2000-03-23 Bruno Haible + + * iconv/gconv_simple.c (internal_ucs4_loop, internal_ucs4le_loop): + Remove no-op pointer increment. + 2000-03-23 Andreas Jaeger * stdio-common/tst-cookie.c (cookieseek): Change prototype to diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c index 89c0384b8d..96a1efc96b 100644 --- a/iconv/gconv_simple.c +++ b/iconv/gconv_simple.c @@ -96,9 +96,6 @@ internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend, else result = __GCONV_INCOMPLETE_INPUT; - if (converted != NULL) - converted += n_convert; - return result; } @@ -151,9 +148,6 @@ internal_ucs4le_loop (const unsigned char **inptrp, const unsigned char *inend, else result = __GCONV_INCOMPLETE_INPUT; - if (converted != NULL) - converted += n_convert; - return result; } diff --git a/inet/getnameinfo.c b/inet/getnameinfo.c index 9a0709229e..6ee3d4d2cc 100644 --- a/inet/getnameinfo.c +++ b/inet/getnameinfo.c @@ -42,20 +42,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */ -#include -#include - -#include -#include -#include -#include +#include #include -#include +#include #include +#include #include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include #ifndef min # define min(x,y) (((x) > (y)) ? (y) : (x)) @@ -173,6 +174,7 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, char *tmpbuf = alloca (tmpbuflen); struct hostent th; socklen_t min_addrlen = 0; + int ok = 0; if (sa == NULL || addrlen < sizeof (sa_family_t)) return -1; @@ -257,36 +259,83 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, min(hostlen, (size_t) (c - h->h_name))); host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0'; - break; + ok = 1; + } + else + { + strncpy (host, h->h_name, hostlen); + ok = 1; } } strncpy (host, h->h_name, hostlen); - break; + ok = 1; } } - if (flags & NI_NAMEREQD) + if (!ok) { - __set_errno (serrno); - return -1; - } - else - { - const char *c; - if (sa->sa_family == AF_INET6) - c = inet_ntop (AF_INET6, - (void *) &(((struct sockaddr_in6 *) sa)->sin6_addr), - host, hostlen); - else - c = inet_ntop (AF_INET, - (void *) &(((struct sockaddr_in *) sa)->sin_addr), - host, hostlen); - - if (c == NULL) + if (flags & NI_NAMEREQD) { __set_errno (serrno); return -1; } + else + { + const char *c; + if (sa->sa_family == AF_INET6) + { + struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) sa; + uint32_t scopeid; + + c = inet_ntop (AF_INET6, + (void *) &sin6p->sin6_addr, host, hostlen); + if (addrlen > sizeof (struct sockaddr_in6) + && (scopeid = sin6p->sin6_scope_id)) + { + /* Buffer is >= IFNAMSIZ+1. */ + char scopebuf[MAXHOSTNAMELEN + 1]; + int ni_numericscope = 0; + + if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr) + || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) + { + if (if_indextoname (scopeid, scopebuf) == NULL) + ++ni_numericscope; + } + else + ++ni_numericscope; + + if (ni_numericscope) + { + char *scopeptr = &scopebuf[1]; + size_t real_hostlen; + size_t scopelen; + + scopebuf[0] = SCOPE_DELIMITER; + scopelen = 1 + snprintf (scopeptr, + (scopebuf + + sizeof scopebuf + - scopeptr), + "%u", scopeid); + + real_hostlen = __strnlen (host, hostlen); + if (real_hostlen + scopelen + 1 > hostlen) + return -1; + memcpy (host + real_hostlen, scopebuf, scopelen); + } + } + } + else + c = inet_ntop (AF_INET, + (void *) &(((struct sockaddr_in *) sa)->sin_addr), + host, hostlen); + if (c == NULL) + { + __set_errno (serrno); + return -1; + } + } + ok = 1; } break; diff --git a/inet/netinet/in.h b/inet/netinet/in.h index 13c2767d9a..fb668a204d 100644 --- a/inet/netinet/in.h +++ b/inet/netinet/in.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc. +/* Copyright (C) 1991-1999, 2000 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 @@ -209,6 +209,7 @@ struct sockaddr_in6 uint16_t sin6_port; /* Transport layer port # */ uint32_t sin6_flowinfo; /* IPv6 flow information */ struct in6_addr sin6_addr; /* IPv6 address */ + uint32_t sin6_scope_id; /* IPv6 scope-id */ }; /* IPv6 multicast request. */ diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 6d28f909c0..2a9683ec34 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,8 @@ +2000-03-23 Ulrich Drepper + + * manager.c (pthread_handle_create): Store ID of new thread before + clone call. + 2000-03-21 Ulrich Drepper * attr.c: Use new macros from shlib-compat.h to define versions. diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c index 4aa598bb9e..6e585be79c 100644 --- a/linuxthreads/manager.c +++ b/linuxthreads/manager.c @@ -415,6 +415,10 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, new_thread->p_start_args.start_routine = start_routine; new_thread->p_start_args.arg = arg; new_thread->p_start_args.mask = *mask; + /* Make the new thread ID available already now. If any of the later + functions fail we return an error value and the caller must not use + the stored thread ID. */ + *thread = new_thread_id; /* Raise priority of thread manager if needed */ __pthread_manager_adjust_prio(new_thread->p_priority); /* Do the cloning. We have to use two different functions depending @@ -487,8 +491,6 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, /* Set pid field of the new thread, in case we get there before the child starts. */ new_thread->p_pid = pid; - /* We're all set */ - *thread = new_thread_id; return 0; } diff --git a/resolv/netdb.h b/resolv/netdb.h index 354d9ddfdb..508e7c4692 100644 --- a/resolv/netdb.h +++ b/resolv/netdb.h @@ -80,6 +80,11 @@ __set_h_errno (int __err) type. */ #define NO_ADDRESS NO_DATA /* No address, look for MX record. */ +#ifdef __USE_GNU +/* Scope delimiter for getaddrinfo(), getnameinfo(). */ +# define SCOPE_DELIMITER '%' +#endif + /* Print error indicated by `h_errno' variable on standard error. STR if non-null is printed before the error string. */ extern void herror (__const char *__str) __THROW; diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 4bb80c8820..be36c6a25f 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -42,20 +42,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */ -/* getaddrinfo() v1.13 */ - -#include +#include +#include +#include +#include #include +#include #include +#include #include -#include -#include -#include -#include #include -#include -#include -#include +#include +#include +#include #define GAIH_OKIFUNSPEC 0x0100 #define GAIH_EAI ~(GAIH_OKIFUNSPEC) @@ -85,6 +84,7 @@ struct gaih_addrtuple struct gaih_addrtuple *next; int family; char addr[16]; + uint32_t scopeid; }; struct gaih_typeproto @@ -370,6 +370,7 @@ gaih_inet (const char *name, const struct gaih_service *service, at = __alloca (sizeof (struct gaih_addrtuple)); at->family = AF_UNSPEC; + at->scopeid = 0; at->next = NULL; if (inet_pton (AF_INET, name, at->addr) > 0) @@ -380,12 +381,48 @@ gaih_inet (const char *name, const struct gaih_service *service, return -EAI_ADDRFAMILY; } - if (at->family == AF_UNSPEC && inet_pton (AF_INET6, name, at->addr) > 0) + if (at->family == AF_UNSPEC) { - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) - at->family = AF_INET6; - else - return -EAI_ADDRFAMILY; + char *namebuf = strdupa (name); + char *scope_delim; + + scope_delim = strchr (namebuf, SCOPE_DELIMITER); + if (scope_delim != NULL) + *scope_delim = '\0'; + + if (inet_pton (AF_INET6, namebuf, at->addr) > 0) + { + int try_numericscope = 0; + + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) + at->family = AF_INET6; + else + return -EAI_ADDRFAMILY; + + if (scope_delim != NULL) + { + int try_numericscope = 0; + if (IN6_IS_ADDR_LINKLOCAL (at->addr) + || IN6_IS_ADDR_MC_LINKLOCAL (at->addr)) + { + at->scopeid = if_nametoindex (scope_delim + 1); + if (at->scopeid == 0) + try_numericscope = 1; + } + else + try_numericscope = 1; + + if (try_numericscope != 0) + { + char *end; + assert (sizeof (uint32_t) <= sizeof (unsigned long)); + at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end, + 10); + if (*end != '\0') + return GAIH_OKIFUNSPEC | -EAI_NONAME; + } + } + } } if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0) @@ -519,10 +556,9 @@ gaih_inet (const char *name, const struct gaih_service *service, (*pai)->ai_addrlen = socklen; (*pai)->ai_addr = (void *) (*pai) + sizeof(struct addrinfo); #if SALEN - ((struct sockaddr_in *) (*pai)->ai_addr)->sin_len = i; + (*pai)->ai_addr->sa_len = socklen; #endif /* SALEN */ - ((struct sockaddr_in *) (*pai)->ai_addr)->sin_family = at2->family; - ((struct sockaddr_in *) (*pai)->ai_addr)->sin_port = st2->port; + (*pai)->ai_addr->sa_family = at2->family; if (at2->family == AF_INET6) { @@ -532,6 +568,8 @@ gaih_inet (const char *name, const struct gaih_service *service, sin6p->sin6_flowinfo = 0; memcpy (&sin6p->sin6_addr, at2->addr, sizeof (struct in6_addr)); + sin6p->sin6_port = st2->port; + sin6p->sin6_scope_id = at2->scopeid; } else { @@ -539,6 +577,7 @@ gaih_inet (const char *name, const struct gaih_service *service, (struct sockaddr_in *) (*pai)->ai_addr; memcpy (&sinp->sin_addr, at2->addr, sizeof (struct in_addr)); + sinp->sin_port = st2->port; memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero)); } -- cgit v1.2.3