From: shyouhei@... Date: 2017-04-07T04:31:12+00:00 Subject: [ruby-core:80603] [Ruby trunk Bug#13405][Open] IO#close raises "stream closed" Issue #13405 has been updated by shyouhei (Shyouhei Urabe). Status changed from Rejected to Open Let me reopen. ---------------------------------------- Bug #13405: IO#close raises "stream closed" https://bugs.ruby-lang.org/issues/13405#change-64110 * Author: matthewd (Matthew Draper) * Status: Open * Priority: Normal * Assignee: * Target version: * ruby -v: * Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN ---------------------------------------- IO#close is supposed to ignore an IOError indicating the stream is already closed. Since #10153, however, it can raise the `ruby_error_closed_stream` special exception, because that exception's message is ["stream closed"](https://github.com/ruby/ruby/blob/6d77e28763ed17f75edf3b4072701b4dbd7644bb/thread.c#L4886) instead of ["closed stream"](https://github.com/ruby/ruby/blob/6d77e28763ed17f75edf3b4072701b4dbd7644bb/io.c#L4517). The fix seems easy -- the mismatched string should be updated to use the more common spelling, with something like: ~~~ diff diff --git a/test/lib/test/unit.rb b/test/lib/test/unit.rb index 6cb22e725a..d1efa5dcfd 100644 --- a/test/lib/test/unit.rb +++ b/test/lib/test/unit.rb @@ -228,7 +228,7 @@ def run(task,type) rescue Errno::EPIPE died rescue IOError - raise unless ["stream closed","closed stream"].include? $!.message + raise unless $!.message == "closed stream" died end end diff --git a/test/lib/test/unit/parallel.rb b/test/lib/test/unit/parallel.rb index 50d4427189..09a5530b04 100644 --- a/test/lib/test/unit/parallel.rb +++ b/test/lib/test/unit/parallel.rb @@ -61,7 +61,7 @@ def _run_suite(suite, type) # :nodoc: begin th.join rescue IOError - raise unless ["stream closed","closed stream"].include? $!.message + raise unless $!.message == "closed stream" end i.close diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index ca3f1e2d3b..5775e31dde 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -3411,7 +3411,7 @@ def test_race_closed_stream end sleep 0.01 r.close - assert_raise_with_message(IOError, /stream closed/) do + assert_raise_with_message(IOError, /closed stream/) do thread.join end assert_equal(true, closed, "#{bug13158}: stream should be closed") diff --git a/thread.c b/thread.c index 5d27681b40..4e6faf6dc8 100644 --- a/thread.c +++ b/thread.c @@ -4883,7 +4883,7 @@ Init_Thread(void) rb_define_method(rb_cThread, "name=", rb_thread_setname, 1); rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0); - rb_vm_register_special_exception(ruby_error_closed_stream, rb_eIOError, "stream closed"); + rb_vm_register_special_exception(ruby_error_closed_stream, rb_eIOError, "closed stream"); cThGroup = rb_define_class("ThreadGroup", rb_cObject); rb_define_alloc_func(cThGroup, thgroup_s_alloc); ~~~ ---- I can't work out how to prove this fixes the problem, however. :( [The existing test in `test_io.rb`](https://github.com/ruby/ruby/blob/6d77e28763ed17f75edf3b4072701b4dbd7644bb/test/ruby/test_io.rb#L3400) shows how to cause the special exception to be raised from `gets`, but I haven't managed to synthetically force `close` to raise it. I know it's possible, though: we're seeing this problem semi-frequently in the Rails test suite (e.g. https://travis-ci.org/rails/rails/jobs/218895049#L499) -- though it's partly hidden by #13239 when it occurs on 2.2 and 2.3. -- https://bugs.ruby-lang.org/ Unsubscribe: