[gambit-list] open-tcp-client won't connect to Emacs server?
Taylor R Campbell
campbell at mumble.net
Fri Oct 2 12:07:39 EDT 2009
Date: Fri, 2 Oct 2009 11:34:20 -0400
From: James Long <longster at gmail.com>
> lack of a :sentinel.
I figured it out. The Emacs server was using ipv6 and Gambit was
using ipv4. I have to tell either one to use the correct one. In my
case, adding ":family 'ipv4" or setting the host to "127.0.0.1" fixed
There are three problems here:
1. GNU Emacs's MAKE-NETWORK-PROCESS (if it is GNU Emacs that you're
using) fails to do the right thing with what getaddrinfo returns
for `localhost': rather than opening listening sockets for all of
the address info records returned, it chooses the first one that
works, which happens to be for IPv6. This is a bug in GNU Emacs.
Gambit probably has a similar bug.
2. Gambit's OPEN-TCP-CLIENT fails to use getaddrinfo, and instead uses
the now ten-years deprecated gethostbyname. This means that it
can't find correct information about a hostname: it will be limited
to IPv4 socket addresses, and not, for example, IPv6 socket
addresses. This has other bad consequences not related to IPv6;
see, e.g., <http://udrepper.livejournal.com/16116.html>.
Not only this, but OPEN-TCP-CLIENT fails to do the right thing with
the list of addresses returned by the ##OS-HOST-INFO procedure:
rather than trying to connect to the addresses in sequence, using
the first one that accepts the connection, it just chooses the
first address in the list, whether or not that one works. This is
a bug, or rather two, in Gambit.
3. Now you have sprinkled needless protocol-dependence in your code as
a consequence of the interaction between these bugs in GNU Emacs
Although this is the wrong place to suggest fixing GNU Emacs, it would
be nice if Gambit didn't exhibit these bugs. Fixing either GNU Emacs
or Gambit in this case would solve jlongster's problem without
requiring him to change any of his code!
Not only does getaddrinfo behave much better than gethostbyname, but
it is easier to use, too. The getaddrinfo(3) man page on BSD systems
shows how to use it both ways, for connecting sockets and listening
sockets: <http://netbsd.gw.com/cgi-bin/man-cgi?getaddrinfo>. Observe
that none of the code says anything about address/protocol families or
particular kinds of sockaddr_* or *_addr structs: you just call
getaddrinfo, and zip through the list of address info records, which
tell you exactly what arguments you need to pass to the socket, bind,
and connect system calls.
More information about the Gambit-list