[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