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

ruby-changes:19503

From: usa <ko1@a...>
Date: Fri, 13 May 2011 15:24:43 +0900 (JST)
Subject: [ruby-changes:19503] usa:r31543 (trunk): * win32/win32.c (rb_w32_select): check invalid handle before doing

usa	2011-05-13 15:24:36 +0900 (Fri, 13 May 2011)

  New Revision: 31543

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31543

  Log:
    * win32/win32.c (rb_w32_select): check invalid handle before doing
      select operations.  see [ruby-dev:43513], [ruby-dev:43535]

  Modified files:
    trunk/ChangeLog
    trunk/win32/win32.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 31542)
+++ ChangeLog	(revision 31543)
@@ -1,3 +1,8 @@
+Fri May 13 15:22:34 2011  NAKAMURA Usaku  <usa@r...>
+
+	* win32/win32.c (rb_w32_select): check invalid handle before doing
+	  select operations.  see [ruby-dev:43513], [ruby-dev:43535]
+
 Fri May 13 08:34:00 2011  Eric Hodel  <drbrain@s...>
 
 	* lib/rdoc/rdoc.rb:  Output summary after documentation report.
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 31542)
+++ win32/win32.c	(revision 31543)
@@ -2391,34 +2391,41 @@
 extract_fd(rb_fdset_t *dst, fd_set *src, int (*func)(SOCKET))
 {
     unsigned int s = 0;
-    if (!src || !dst) return 0;
+    unsigned int m = 0;
+    if (!src) return 0;
 
     while (s < src->fd_count) {
         SOCKET fd = src->fd_array[s];
 
-	if (!func || (*func)(fd)) { /* move it to dst */
-	    unsigned int d;
+	if (!func || (*func)(fd)) {
+	    if (dst) { /* move it to dst */
+		unsigned int d;
 
-	    for (d = 0; d < dst->fdset->fd_count; d++) {
-		if (dst->fdset->fd_array[d] == fd)
-		    break;
-	    }
-	    if (d == dst->fdset->fd_count) {
-		if ((int)dst->fdset->fd_count >= dst->capa) {
-		    dst->capa = (dst->fdset->fd_count / FD_SETSIZE + 1) * FD_SETSIZE;
-		    dst->fdset = xrealloc(dst->fdset, sizeof(unsigned int) + sizeof(SOCKET) * dst->capa);
+		for (d = 0; d < dst->fdset->fd_count; d++) {
+		    if (dst->fdset->fd_array[d] == fd)
+			break;
 		}
-		dst->fdset->fd_array[dst->fdset->fd_count++] = fd;
+		if (d == dst->fdset->fd_count) {
+		    if ((int)dst->fdset->fd_count >= dst->capa) {
+			dst->capa = (dst->fdset->fd_count / FD_SETSIZE + 1) * FD_SETSIZE;
+			dst->fdset = xrealloc(dst->fdset, sizeof(unsigned int) + sizeof(SOCKET) * dst->capa);
+		    }
+		    dst->fdset->fd_array[dst->fdset->fd_count++] = fd;
+		}
+		memmove(
+		    &src->fd_array[s],
+		    &src->fd_array[s+1],
+		    sizeof(src->fd_array[0]) * (--src->fd_count - s));
 	    }
-	    memmove(
-		&src->fd_array[s],
-		&src->fd_array[s+1],
-		sizeof(src->fd_array[0]) * (--src->fd_count - s));
+	    else {
+		m++;
+		s++;
+	    }
 	}
 	else s++;
     }
 
-    return dst->fdset->fd_count;
+    return dst ? dst->fdset->fd_count : m;
 }
 
 static int
@@ -2515,6 +2522,12 @@
 }
 
 static int
+is_invalid_handle(SOCKET sock)
+{
+    return (HANDLE)sock == INVALID_HANDLE_VALUE;
+}
+
+static int
 do_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
             struct timeval *timeout)
 {
@@ -2625,15 +2638,24 @@
     rb_fd_init(&else_rd);
     nonsock += extract_fd(&else_rd, rd, is_not_socket);
 
+    rb_fd_init(&else_wr);
+    nonsock += extract_fd(&else_wr, wr, is_not_socket);
+
+    // check invalid handles
+    if (extract_fd(NULL, else_rd.fdset, is_invalid_handle) > 0 ||
+	extract_fd(NULL, else_wr.fdset, is_invalid_handle) > 0) {
+	rb_fd_term(&else_wr);
+	rb_fd_term(&else_rd);
+	errno = EBADF;
+	return -1;
+    }
+
     rb_fd_init(&pipe_rd);
     extract_fd(&pipe_rd, else_rd.fdset, is_pipe); // should not call is_pipe for socket
 
     rb_fd_init(&cons_rd);
     extract_fd(&cons_rd, else_rd.fdset, is_console); // ditto
 
-    rb_fd_init(&else_wr);
-    nonsock += extract_fd(&else_wr, wr, is_not_socket);
-
     rb_fd_init(&except);
     extract_fd(&except, ex, is_not_socket); // drop only
 
@@ -2694,9 +2716,9 @@
     }
 
     rb_fd_term(&except);
-    rb_fd_term(&else_wr);
     rb_fd_term(&cons_rd);
     rb_fd_term(&pipe_rd);
+    rb_fd_term(&else_wr);
     rb_fd_term(&else_rd);
 
     return r;

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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