ruby-changes:19384
From: kosaki <ko1@a...>
Date: Wed, 4 May 2011 11:44:36 +0900 (JST)
Subject: [ruby-changes:19384] Ruby:r31424 (trunk): * ext/socket/init.c (wait_connectable): fix error handling code.
kosaki 2011-05-04 11:44:28 +0900 (Wed, 04 May 2011) New Revision: 31424 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31424 Log: * ext/socket/init.c (wait_connectable): fix error handling code. RB_WAITFD_OUT is turned on even though an error occur. Modified files: trunk/ChangeLog trunk/ext/socket/init.c Index: ChangeLog =================================================================== --- ChangeLog (revision 31423) +++ ChangeLog (revision 31424) @@ -1,3 +1,8 @@ +Wed May 4 11:42:47 2011 KOSAKI Motohiro <kosaki.motohiro@g...> + + * ext/socket/init.c (wait_connectable): fix error handling code. + RB_WAITFD_OUT is turned on even though an error occur. + Wed May 4 10:12:39 2011 KOSAKI Motohiro <kosaki.motohiro@g...> * ext/readline/readline.c (readline_event): use rb_wait_for_single_fd(). Index: ext/socket/init.c =================================================================== --- ext/socket/init.c (revision 31423) +++ ext/socket/init.c (revision 31424) @@ -258,22 +258,42 @@ { int sockerr; socklen_t sockerrlen; - int r; + int revents; + int ret; for (;;) { - r = rb_wait_for_single_fd(fd, RB_WAITFD_OUT|RB_WAITFD_PRI, NULL); - if ((r > 0) && (r & RB_WAITFD_OUT)) - return 0; + /* + * Stevens book says, succuessful finish turn on RB_WAITFD_OUT and + * failure finish turn on both RB_WAITFD_IN and RB_WAITFD_OUT. + */ + revents = rb_wait_for_single_fd(fd, RB_WAITFD_IN|RB_WAITFD_OUT, NULL); - sockerrlen = (socklen_t)sizeof(sockerr); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, - &sockerrlen) == 0) { + if (revents & (RB_WAITFD_IN|RB_WAITFD_OUT)) { + sockerrlen = (socklen_t)sizeof(sockerr); + ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen); + + /* + * Solaris getsockopt(SO_ERROR) return -1 and set errno + * in getsockopt(). Let's return immediately. + */ + if (ret < 0) + break; if (sockerr == 0) continue; /* workaround for winsock */ + + /* BSD and Linux use sockerr. */ errno = sockerr; + ret = -1; + break; } - return -1; + + if ((revents & (RB_WAITFD_IN|RB_WAITFD_OUT)) == RB_WAITFD_OUT) { + ret = 0; + break; + } } + + return ret; } #ifdef __CYGWIN__ -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/