Date: Fri, 2 Oct 2009 11:34:20 -0400 From: James Long longster@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 it.
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 and Gambit!
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.