Update.
authorUlrich Drepper <drepper@redhat.com>
Thu, 23 Mar 2000 21:34:58 +0000 (21:34 +0000)
committerUlrich Drepper <drepper@redhat.com>
Thu, 23 Mar 2000 21:34:58 +0000 (21:34 +0000)
2000-03-23  Bruno Haible  <haible@clisp.cons.org>

* iconv/gconv_simple.c (internal_ucs4_loop, internal_ucs4le_loop):
Remove no-op pointer increment.

ChangeLog
iconv/gconv_simple.c
inet/getnameinfo.c
inet/netinet/in.h
linuxthreads/ChangeLog
linuxthreads/manager.c
resolv/netdb.h
sysdeps/posix/getaddrinfo.c

index 4cc3efb..81d0653 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2000-03-23  Bruno Haible  <haible@clisp.cons.org>
+
+       * iconv/gconv_simple.c (internal_ucs4_loop, internal_ucs4le_loop):
+       Remove no-op pointer increment.
+
 2000-03-23  Andreas Jaeger  <aj@suse.de>
 
        * stdio-common/tst-cookie.c (cookieseek): Change prototype to
index 89c0384..96a1efc 100644 (file)
@@ -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;
 }
 
index 9a07092..6ee3d4d 100644 (file)
@@ -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 <sys/types.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#include <sys/un.h>
-#include <sys/utsname.h>
-#include <netdb.h>
+#include <alloca.h>
 #include <errno.h>
-#include <string.h>
+#include <netdb.h>
 #include <stdio.h>
+#include <string.h>
 #include <unistd.h>
-#include <alloca.h>
-#include <bits/libc-lock.h>
 #include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/utsname.h>
+#include <bits/libc-lock.h>
 
 #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;
 
index 13c2767..fb668a2 100644 (file)
@@ -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.  */
index 6d28f90..2a9683e 100644 (file)
@@ -1,3 +1,8 @@
+2000-03-23  Ulrich Drepper  <drepper@redhat.com>
+
+       * manager.c (pthread_handle_create): Store ID of new thread before
+       clone call.
+
 2000-03-21  Ulrich Drepper  <drepper@redhat.com>
 
        * attr.c: Use new macros from shlib-compat.h to define versions.
index 4aa598b..6e585be 100644 (file)
@@ -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;
 }
 
index 354d9dd..508e7c4 100644 (file)
@@ -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;
index 4bb80c8..be36c6a 100644 (file)
@@ -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 <sys/types.h>
+#include <assert.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
+#include <arpa/inet.h>
 #include <sys/socket.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/utsname.h>
-#include <sys/un.h>
 #include <netinet/in.h>
-#include <netdb.h>
-#include <errno.h>
-#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/utsname.h>
 
 #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));
              }