I'm trying to set up a simple web server on Mac OS X, and I keep getting an error when I run bind. Here's what I'm running (this transcript uses GNU Guile, but just as a convenient interface to posix). (define addr (inet-aton '127.0.0.1')); get internal representation of 127.0.0.1 (define sockaddr (make-socket-address AFINET addr 8080)); make a struct sockaddr (define sock (socket PFINET SOCKSTREAM 0)); make a socket (bind sock sockaddr); bind the socket to the address That gives me the error In procedure bind: can't assign requested address. So I tried it again allowing any address. (define anyaddr (make-socket-address AFINET INADDRANY 8080)); allow any address (bind sock anyaddr) And that works fine.
But it's weird, because ifconfig lo0 says lo0: flags=8049 mtu 16384 inet6::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 inet 127.0.0.1 netmask 0xff000000 So the loopback device is assigned to 127.0.0.1. So my question is, why can't I bind to that address?
Update: the output of route get 127.0.0.1 is route to: localhost destination: localhost interface: lo0 flags: recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire 2 0 0 0 0 16384 0. This isn't exactly an answer, since it doens't directly solve you problem.but it looks as if your problem is particular to guile. That is, on my OS X 10.6 system, I have the same problem you do using the guile code from you example. On the other hand, the following works just fine: import socket s = socket.socket(socket.AFINET, socket.SOCKSTREAM) s.setsockopt(socket.SOLSOCKET, socket.SOREUSEADDR, 1) s.bind(('127.0.0.1', 8080)) s.listen(5) c, addr = s.accept c.send('hello n') c.close If I run this code, I can see the socket listening: netstat -f inet -an grep 8080 tcp4 0 0 127.0.0.1.8080. LISTEN And connecting to port 8080 does what you would expect: $ telnet localhost 8080 Trying 127.0.0.1. Connected to localhost.
Escape character is '^'. Hello Connection closed by foreign host. Indeed, in my case, the problem is with the uninitialized fields in the structure which have nothing to do with the semantic socket address. I added a memset(&sa, 0, sizeof sa) and now it binds. It is almost certainly the case that the Guile implementation was running into the same issue: initializing just the documented fields of struct sockaddrin. The symptoms were exactly the same, in any case: INADDRANY binding, yet INADDRLOOPBACK refusing with the same errno. Edit: sorry if I'm unclear; I'm referring to something I added to the question which someone removed.
Namely, I ran into exactly the same problem in the implementation of (by sheer coincidence) another Lisp dialect. I added my observations, along with some gdb debug session traces showing the contents of the struct sockaddrin before the bind call. The address showed correctly initialized sinfamily, sinaddr and sinport fields. However, the sinlen field at the head of the structure (present on Darwin, absent on other platforms) was uninitialized, as well as a sinzero padding array at the end.