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);