diff --git a/ChangeLog b/ChangeLog index 117bd074a8..c5ac925b61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Mon Oct 24 08:18:14 2011 Tanaka Akira + + * io.c (copy_stream_fallback_body): check nil for EOF of read method. + patch by Eric Wong. [ruby-core:39134] [Bug #5237] + Sun Oct 23 18:21:23 2011 Kazuki Tsujimoto * ext/tk/MANUAL_tcltklib.eng: fix typo. diff --git a/io.c b/io.c index c9a33f3aad..15e2ec982b 100644 --- a/io.c +++ b/io.c @@ -8998,7 +8998,10 @@ copy_stream_fallback_body(VALUE arg) l = buflen < rest ? buflen : (long)rest; } if (stp->src_fd == -1) { - rb_funcall(stp->src, read_method, 2, INT2FIX(l), buf); + VALUE rc = rb_funcall(stp->src, read_method, 2, INT2FIX(l), buf); + + if (read_method == id_read && NIL_P(rc)) + break; } else { ssize_t ss; diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index e3bbd245ed..c2eecb7397 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -826,6 +826,28 @@ class TestIO < Test::Unit::TestCase } end + class Bug5237 + attr_reader :count + def initialize + @count = 0 + end + + def read(bytes, buffer) + @count += 1 + buffer.replace "this is a test" + nil + end + end + + def test_copy_stream_broken_src_read_eof + src = Bug5237.new + dst = StringIO.new + assert_equal 0, src.count + th = Thread.new { IO.copy_stream(src, dst) } + flunk("timeout") unless th.join(10) + assert_equal 1, src.count + end + def test_copy_stream_dst_rbuf mkcdtmpdir { pipe(proc do |w|