[MLton] Socket.connectNB on NetBSD
Stephen Weeks
MLton@mlton.org
Tue, 18 Nov 2003 18:51:26 -0800
> Could it just be that the failure is because you are getting EAGAIN because
> the connection hasn't completed yet?
The problem is that the connect on NetBSD is succeeding
(i.e. returning 0), while on Linux it is failing (i.e. returning -1).
> I have a vague recollection of some systems doing this, which really
> is the `right' thing to do because the connection takes a few
> exchanges and so can be slow. Did you try this code on a Sun?
I just did, and the code fails on Sun as well. So, it fails on
FreeBSD, NetBSD, and Sun, and works on Linux.
The man pages for Linux, NetBSD, and SunOS all agree that connect
should return -1 with EINPROGRESS when the socket is nonblocking and
the connect cannot be made. Perhaps the problem is that the fcntl
stuff isn't working right and the socket is not correctly being marked
nonblocking?
Here are the kernel traces for Linux, NetBSD, and SunOS.
------------------------------------------------------------
Linux
------------------------------------------------------------
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 5) = 0
getsockname(3, {sa_family=AF_INET, sin_port=htons(37900), sin_addr=inet_addr("0.0.0.0")}, [16]) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 4
fcntl64(4, F_GETFL) = 0x2 (flags O_RDWR)
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(37900), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EINPROGRESS (Operation now in progress)
fcntl64(4, F_SETFL, O_RDWR) = 0
write(1, "OK\n", 3) = 3
------------------------------------------------------------
NetBSD
------------------------------------------------------------
2898 z CALL socket(0x2,0x1,0)
2898 z RET socket 3
2898 z CALL bind(0x3,0xb8001d00,0x10)
2898 z RET bind 0
2898 z CALL listen(0x3,0x5)
2898 z RET listen 0
2898 z CALL getsockname(0x3,0xb8001d1c,0xb8001d8c)
2898 z RET getsockname 0
2898 z CALL socket(0x2,0x1,0)
2898 z RET socket 4
2898 z CALL fcntl(0x4,0x3,0x805dfe0)
2898 z RET fcntl 2
2898 z CALL fcntl(0x4,0x4,0x6)
2898 z RET fcntl 0
2898 z CALL connect(0x4,0xb8001d9c,0x10)
2898 z RET connect 0
2898 z CALL fcntl(0x4,0x4,0x2)
2898 z RET fcntl 0
2898 z CALL write(0x1,0xb8000574,0x6)
2898 z GIO fd 1 wrote 6 bytes
"WRONG
"
2898 z RET write 6
------------------------------------------------------------
Sun
------------------------------------------------------------
16493: so_socket(2, 2, 0, "", 1) = 4
16493: bind(4, 0xFF151F48, 16, 3) = 0
16493: listen(4, 5, 1) = 0
16493: getsockname(4, 0xFF151F68, 0xFF151FE0, 1) = 0
16493: so_socket(2, 2, 0, "", 1) = 5
16493: fcntl(5, F_GETFL, 0x00000005) = 2
16493: fstat64(5, 0xFFBEF938) = 0
16493: getsockopt(5, 65535, 8192, 0xFFBEFA38, 0xFFBEFA30, 0) = 0
16493: fstat64(5, 0xFFBEF938) = 0
16493: getsockopt(5, 65535, 8192, 0xFFBEFA38, 0xFFBEFA34, 0) = 0
16493: setsockopt(5, 65535, 8192, 0xFFBEFA38, 4, 0) = 0
16493: fcntl(5, F_SETFL, 0x00000082) = 0
16493: connect(5, 0xFF151FF0, 16, 1) = 0
16493: fstat64(5, 0xFFBEF938) = 0
16493: getsockopt(5, 65535, 8192, 0xFFBEFA38, 0xFFBEFA34, 0) = 0
16493: setsockopt(5, 65535, 8192, 0xFFBEFA38, 4, 0) = 0
16493: fcntl(5, F_SETFL, 0x00000002) = 0
16493: write(1, " W R O N G\n", 6) = 6