From: nobu.nokada@... Date: 2003-05-16T12:05:32+09:00 Subject: Re: Fwd: ping.rb Hi, At Fri, 16 May 2003 10:47:12 +0900, J.Herre wrote: > Checking via getsockopt() seems to work. (Depending on how you read the > man page for connect() this may or may not be required.) Sounds great. > Does someone else want to test this and see if it screws up anything > else? Seems to always wait one second once EINPROGRESS is returned. Boolean may be enough as wait_in_progress if getsockopt() will return proper status. Index: ext/socket/socket.c =================================================================== RCS file: /cvs/ruby/src/ruby/ext/socket/socket.c,v retrieving revision 1.92 diff -u -2 -p -w -r1.92 socket.c --- ext/socket/socket.c 7 Apr 2003 06:58:31 -0000 1.92 +++ ext/socket/socket.c 16 May 2003 02:53:46 -0000 @@ -725,4 +725,11 @@ thread_write_select(fd) } +#ifdef __CYGWIN__ +#define WAIT_IN_PROGRESS 10 +#endif +#ifdef __APPLE__ +#define WAIT_IN_PROGRESS 10 +#endif + static int ruby_connect(fd, sockaddr, len, socks) @@ -734,5 +741,5 @@ ruby_connect(fd, sockaddr, len, socks) int status; int mode; -#if defined __CYGWIN__ +#ifdef WAIT_IN_PROGRESS int wait_in_progress = -1; #endif @@ -771,19 +778,34 @@ ruby_connect(fd, sockaddr, len, socks) #ifdef EINPROGRESS case EINPROGRESS: -#ifdef __CYGWIN__ +#endif +#ifdef EALREADY case EALREADY: - wait_in_progress = 10; #endif +#ifdef WAIT_IN_PROGRESS + wait_in_progress = WAIT_IN_PROGRESS; #endif thread_write_select(fd); continue; -#if defined __CYGWIN__ +#ifdef WAIT_IN_PROGRESS case EINVAL: if (wait_in_progress-- > 0) { + int sockerr; + int sockerrlen = sizeof(sockerr); + + /* + * connect() after EINPROGRESS returns EINVAL on + * some platforms, need to check true error + * status. + */ + status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &sockerrlen); + if (!status && !sockerr) { struct timeval tv = {0, 100000}; rb_thread_wait_for(tv); continue; } + status = -1; + errno = sockerr; + } break; #endif -- Nobu Nakada