Replying to myself once again,

> I wrote:
>
> I think it would work to just move the socket call into
> choose_address. That is an interface change that propagates to just
> half a dozen functions.

An untested patch is included below (also available at
http://www.lysator.liu.se/~nisse/misv/lsh-1.2.2-ipv6.patch). Let me
know if it works.

Regards,
/Niels

Index: io.c
===================================================================
RCS file: /lysator/cvsroot/nisse/lsh/src/io.c,v
retrieving revision 1.128.2.1
diff -u -r1.128.2.1 io.c
--- io.c        2001/04/12 15:53:56     1.128.2.1
+++ io.c        2001/05/16 12:15:52
@@ -1159,7 +1159,8 @@
 #if HAVE_GETADDRINFO
 static struct addrinfo *
 choose_address(struct addrinfo *list,
-              const int *preference)
+              const int *preference,
+              int *s)
 {
   int i;
   for (i = 0; preference[i]; i++)
@@ -1167,7 +1168,12 @@
       struct addrinfo *p;
       for (p = list; p; p = p->ai_next)
        if (preference[i] == p->ai_family)
-         return p;
+         {
+           *s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+           if (*s<0)
+             continue;
+           return p;
+         }
     }
   return NULL;
 }
@@ -1179,7 +1185,7 @@
 address_info2sockaddr(socklen_t *length,
                      struct address_info *a,
                      /* Preferred address families. Zero-terminated array. */
-                     const int *preference,
+                     int *s,
                      int lookup)
 {
   char *host;
@@ -1234,7 +1240,7 @@
       }
 
     chosen = choose_address(list,
-                           preference ? preference : default_preference);
+                           default_preference, s);
     if (!chosen)
       {
        freeaddrinfo(list);
@@ -1307,6 +1313,15 @@
              memcpy(&addr->sin_addr, hp->h_addr, hp->h_length);
            }
        }
+      if (addr)
+       {
+         *s = socket(AF_INET, SOCK_STREAM, 0);
+         if (*s < 0)
+           {
+             lsh_space_free(addr);
+             addr = NULL;
+           }
+       }
       return (struct sockaddr *) addr;
     }
 #endif /* !HAVE_GETADDRINFO */  
@@ -1376,16 +1391,15 @@
 /* Some code is taken from Thomas Bellman's tcputils. */
 struct lsh_fd *
 io_connect(struct io_backend *b,
+          int s,
           struct sockaddr *remote,
           socklen_t remote_length,
           struct command_continuation *c,
           struct exception_handler *e)
 {
-  int s = socket(remote->sa_family, SOCK_STREAM, 0);
   struct lsh_fd *fd;
   
-  if (s<0)
-    return NULL;
+  assert(s >= 0);
 
   trace("io.c: Connecting using fd %i\n", s);
   
@@ -1420,16 +1434,16 @@
 
 struct lsh_fd *
 io_listen(struct io_backend *b,
+         int s,
          struct sockaddr *local,
          socklen_t length,
          struct io_callback *callback,
          struct exception_handler *e)
 {
-  int s = socket(local->sa_family, SOCK_STREAM, 0);
+  /* int s = socket(local->sa_family, SOCK_STREAM, 0); */
   struct lsh_fd *fd;
-  
-  if (s<0)
-    return NULL;
+
+  assert(s >= 0);
 
   trace("io.c: Listening on fd %i\n", s);
   
@@ -1587,6 +1601,7 @@
   struct sockaddr_un *local;
   socklen_t local_length;
 
+  int s;
   struct lsh_fd *fd;
   
   assert(info->directory && NUL_TERMINATED(info->directory));
@@ -1627,7 +1642,10 @@
   old_umask = umask(0077);
 
   /* Bind and listen */
-  fd = io_listen(b, (struct sockaddr *) local, local_length, callback, e);
+  s = socket(AF_UNIX, SOCK_STREAM, 0);
+  fd = ( (s >= 0)
+        ? io_listen(b, s, (struct sockaddr *) local, local_length, callback, e)
+        : NULL);
   
   /* Ok, now we restore umask and cwd */
   umask(old_umask);
@@ -1649,6 +1667,7 @@
   struct sockaddr_un *addr;
   socklen_t addr_length;
 
+  int s;
   struct lsh_fd *fd;
   
   assert(info->directory && NUL_TERMINATED(info->directory));
@@ -1669,8 +1688,11 @@
   old_cd = safe_pushd(info->directory->data, 0);
   if (old_cd < 0)
     return NULL;
-  
-  fd = io_connect(b, (struct sockaddr *) addr, addr_length, c, e);
+
+  s = socket(AF_UNIX, SOCK_STREAM, 0);
+  fd = ( (s >= 0)
+        ? io_connect(b, s, (struct sockaddr *) addr, addr_length, c, e)
+        : NULL);
 
   safe_popd(old_cd, info->directory->data);
 
Index: io.h
===================================================================
RCS file: /lysator/cvsroot/nisse/lsh/src/io.h,v
retrieving revision 1.75.2.1
diff -u -r1.75.2.1 io.h
--- io.h        2001/04/12 15:53:57     1.75.2.1
+++ io.h        2001/05/16 11:51:48
@@ -256,7 +256,7 @@
 struct sockaddr *
 address_info2sockaddr(socklen_t *length,
                      struct address_info *a,
-                     const int *preference,
+                     int *socket,
                      int lookup);
 
 /* Returns an exception, if anything went wrong */
@@ -284,6 +284,7 @@
 
 struct lsh_fd *
 io_connect(struct io_backend *b,
+          int socket,
           struct sockaddr *remote,
           socklen_t remote_length,
           struct command_continuation *c,
@@ -291,6 +292,8 @@
 
 struct lsh_fd *
 io_listen(struct io_backend *b,
+         /* Should be an open socket of the right type. */
+         int socket,
          struct sockaddr *local,
          socklen_t length,
          struct io_callback *callback,
Index: io_commands.c
===================================================================
RCS file: /lysator/cvsroot/nisse/lsh/src/io_commands.c,v
retrieving revision 1.38
diff -u -r1.38 io_commands.c
--- io_commands.c       2001/03/25 12:16:25     1.38
+++ io_commands.c       2001/05/16 09:41:22
@@ -133,17 +133,18 @@
 {
   struct sockaddr *addr;
   socklen_t addr_length;
+  int socket;
   
   struct lsh_fd *fd;
 
-  addr = address_info2sockaddr(&addr_length, a, NULL, 0);
+  addr = address_info2sockaddr(&addr_length, a, &socket, 0);
   if (!addr)
     {
       EXCEPTION_RAISE(e, &resolve_exception);
       return;
     }
 
-  fd = io_listen(backend,
+  fd = io_listen(backend, socket,
                 addr, addr_length,
                 make_listen_callback(backend, accept_c, e),
                 e);
@@ -258,13 +259,14 @@
 {
   struct sockaddr *addr;
   socklen_t addr_length;
+  int socket;
   struct lsh_fd *fd;
 
   /* Address must specify a host */
   assert(a->ip);
 
   /* Performs dns lookups */
-  addr = address_info2sockaddr(&addr_length, a, NULL, 1);
+  addr = address_info2sockaddr(&addr_length, a, &socket, 1);
   if (!addr)
     {
       EXCEPTION_RAISE(e, &resolve_exception);
@@ -273,7 +275,7 @@
 
   /* If the name is canonicalized in any way, we should pass the
    * canonical name to make_connect_continuation .*/
-  fd = io_connect(backend, addr, addr_length, 
+  fd = io_connect(backend, socket, addr, addr_length, 
                  make_connect_continuation(a, c), e);
   lsh_space_free(addr);
 

Reply via email to