[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]