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

ruby-changes:53715

From: normal <ko1@a...>
Date: Fri, 23 Nov 2018 07:44:09 +0900 (JST)
Subject: [ruby-changes:53715] normal:r65931 (trunk): io.c: revalidate fptr->fd after rb_io_wait_readable

normal	2018-11-23 07:44:06 +0900 (Fri, 23 Nov 2018)

  New Revision: 65931

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=65931

  Log:
    io.c: revalidate fptr->fd after rb_io_wait_readable
    
    fptr->fd may become -1 while GVL is released in
    rb_wait_for_single_fd, so we must check it after reacquiring
    GVL.  This should avoid EBADF errors exposed by making pipes
    non-blocking by default:
    
    http://ci.rvm.jp/results/trunk-test@ruby-sky3/1473710
    
    [Bug #14968]

  Modified files:
    trunk/io.c
Index: io.c
===================================================================
--- io.c	(revision 65930)
+++ io.c	(revision 65931)
@@ -1997,6 +1997,16 @@ rb_io_rewind(VALUE io) https://github.com/ruby/ruby/blob/trunk/io.c#L1997
 }
 
 static int
+fptr_wait_readable(rb_io_t *fptr)
+{
+    int ret = rb_io_wait_readable(fptr->fd);
+
+    if (ret)
+        rb_io_check_closed(fptr);
+    return ret;
+}
+
+static int
 io_fillbuf(rb_io_t *fptr)
 {
     ssize_t r;
@@ -2016,7 +2026,7 @@ io_fillbuf(rb_io_t *fptr) https://github.com/ruby/ruby/blob/trunk/io.c#L2026
 	    r = rb_read_internal(fptr->fd, fptr->rbuf.ptr, fptr->rbuf.capa);
 	}
         if (r < 0) {
-            if (rb_io_wait_readable(fptr->fd))
+            if (fptr_wait_readable(fptr))
                 goto retry;
 	    {
 		int e = errno;
@@ -2363,7 +2373,7 @@ io_bufread(char *ptr, long len, rb_io_t https://github.com/ruby/ruby/blob/trunk/io.c#L2373
 	    c = rb_read_internal(fptr->fd, ptr+offset, n);
 	    if (c == 0) break;
 	    if (c < 0) {
-                if (rb_io_wait_readable(fptr->fd))
+                if (fptr_wait_readable(fptr))
                     goto again;
 		return -1;
 	    }
@@ -2788,7 +2798,7 @@ io_getpartial(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/io.c#L2798
 	n = arg.len;
         if (n < 0) {
 	    int e = errno;
-            if (!nonblock && rb_io_wait_readable(fptr->fd))
+            if (!nonblock && fptr_wait_readable(fptr))
                 goto again;
 	    if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) {
                 if (no_exception_p(opts))

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

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