ruby-changes:34144
From: akr <ko1@a...>
Date: Thu, 29 May 2014 20:29:56 +0900 (JST)
Subject: [ruby-changes:34144] akr:r46225 (trunk): * io.c (rb_io_s_pipe): Close pipes if io_encoding_set() raises an
akr 2014-05-29 20:29:47 +0900 (Thu, 29 May 2014) New Revision: 46225 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?revision=46225&view=revision Log: * io.c (rb_io_s_pipe): Close pipes if io_encoding_set() raises an exception. (io_encoding_set_v): New function. Modified files: trunk/ChangeLog trunk/io.c trunk/test/ruby/test_io.rb trunk/test/ruby/test_io_m17n.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 46224) +++ ChangeLog (revision 46225) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu May 29 19:47:08 2014 Tanaka Akira <akr@f...> + + * io.c (rb_io_s_pipe): Close pipes if io_encoding_set() raises an + exception. + (io_encoding_set_v): New function. + Thu May 29 19:42:49 2014 Tanaka Akira <akr@f...> * lib/csv.rb (CSV.open): Close the opened file when an exception Index: io.c =================================================================== --- io.c (revision 46224) +++ io.c (revision 46225) @@ -9384,6 +9384,21 @@ io_encoding_set(rb_io_t *fptr, VALUE v1, https://github.com/ruby/ruby/blob/trunk/io.c#L9384 } +struct io_encoding_set_args { + rb_io_t *fptr; + VALUE v1; + VALUE v2; + VALUE opt; +}; + +static VALUE +io_encoding_set_v(VALUE v) +{ + struct io_encoding_set_args *arg = (struct io_encoding_set_args *)v; + io_encoding_set(arg->fptr, arg->v1, arg->v2, arg->opt); + return Qnil; +} + static VALUE pipe_pair_close(VALUE rw) { @@ -9458,6 +9473,7 @@ rb_io_s_pipe(int argc, VALUE *argv, VALU https://github.com/ruby/ruby/blob/trunk/io.c#L9473 VALUE r, w, args[3], v1, v2; VALUE opt; rb_io_t *fptr, *fptr2; + struct io_encoding_set_args ies_args; int fmode = 0; VALUE ret; @@ -9475,7 +9491,18 @@ rb_io_s_pipe(int argc, VALUE *argv, VALU https://github.com/ruby/ruby/blob/trunk/io.c#L9491 rb_jump_tag(state); } GetOpenFile(r, fptr); - io_encoding_set(fptr, v1, v2, opt); + + ies_args.fptr = fptr; + ies_args.v1 = v1; + ies_args.v2 = v2; + ies_args.opt = opt; + rb_protect(io_encoding_set_v, (VALUE)&ies_args, &state); + if (state) { + close(pipes[1]); + io_close(r); + rb_jump_tag(state); + } + args[1] = INT2NUM(pipes[1]); args[2] = INT2FIX(O_WRONLY); w = rb_protect(io_new_instance, (VALUE)args, &state); Index: test/ruby/test_io_m17n.rb =================================================================== --- test/ruby/test_io_m17n.rb (revision 46224) +++ test/ruby/test_io_m17n.rb (revision 46225) @@ -2142,32 +2142,34 @@ EOT https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io_m17n.rb#L2142 def test_textmode_paragraph_nonasciicompat bug3534 = ['[ruby-dev:41803]', '[Bug #3534]'] - r, w = IO.pipe - [Encoding::UTF_32BE, Encoding::UTF_32LE, - Encoding::UTF_16BE, Encoding::UTF_16LE, - Encoding::UTF_8].each do |e| - r.set_encoding(Encoding::US_ASCII, e) - wthr = Thread.new{ w.print(bug3534[0], "\n\n\n\n", bug3534[1], "\n") } - assert_equal((bug3534[0]+"\n\n").encode(e), r.gets(""), bug3534[0]) - assert_equal((bug3534[1]+"\n").encode(e), r.gets(), bug3534[1]) - wthr.join - end + IO.pipe {|r, w| + [Encoding::UTF_32BE, Encoding::UTF_32LE, + Encoding::UTF_16BE, Encoding::UTF_16LE, + Encoding::UTF_8].each do |e| + r.set_encoding(Encoding::US_ASCII, e) + wthr = Thread.new{ w.print(bug3534[0], "\n\n\n\n", bug3534[1], "\n") } + assert_equal((bug3534[0]+"\n\n").encode(e), r.gets(""), bug3534[0]) + assert_equal((bug3534[1]+"\n").encode(e), r.gets(), bug3534[1]) + wthr.join + end + } end def test_binmode_paragraph_nonasciicompat bug3534 = ['[ruby-dev:41803]', '[Bug #3534]'] - r, w = IO.pipe - r.binmode - w.binmode - [Encoding::UTF_32BE, Encoding::UTF_32LE, - Encoding::UTF_16BE, Encoding::UTF_16LE, - Encoding::UTF_8].each do |e| - r.set_encoding(Encoding::US_ASCII, e) - wthr = Thread.new{ w.print(bug3534[0], "\n\n\n\n", bug3534[1], "\n") } - assert_equal((bug3534[0]+"\n\n").encode(e), r.gets(""), bug3534[0]) - assert_equal((bug3534[1]+"\n").encode(e), r.gets(), bug3534[1]) - wthr.join - end + IO.pipe {|r, w| + r.binmode + w.binmode + [Encoding::UTF_32BE, Encoding::UTF_32LE, + Encoding::UTF_16BE, Encoding::UTF_16LE, + Encoding::UTF_8].each do |e| + r.set_encoding(Encoding::US_ASCII, e) + wthr = Thread.new{ w.print(bug3534[0], "\n\n\n\n", bug3534[1], "\n") } + assert_equal((bug3534[0]+"\n\n").encode(e), r.gets(""), bug3534[0]) + assert_equal((bug3534[1]+"\n").encode(e), r.gets(), bug3534[1]) + wthr.join + end + } end def test_puts_widechar Index: test/ruby/test_io.rb =================================================================== --- test/ruby/test_io.rb (revision 46224) +++ test/ruby/test_io.rb (revision 46225) @@ -1087,13 +1087,17 @@ class TestIO < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L1087 def test_dup ruby do |f| - f2 = f.dup - f.puts "foo" - f2.puts "bar" - f.close_write - f2.close_write - assert_equal("foo\nbar\n", f.read) - assert_equal("", f2.read) + begin + f2 = f.dup + f.puts "foo" + f2.puts "bar" + f.close_write + f2.close_write + assert_equal("foo\nbar\n", f.read) + assert_equal("", f2.read) + ensure + f2.close + end end end @@ -1396,18 +1400,22 @@ class TestIO < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L1400 end def test_pid - r, w = IO.pipe - assert_equal(nil, r.pid) - assert_equal(nil, w.pid) - - pipe = IO.popen(EnvUtil.rubybin, "r+") - pid1 = pipe.pid - pipe.puts "p $$" - pipe.close_write - pid2 = pipe.read.chomp.to_i - assert_equal(pid2, pid1) - assert_equal(pid2, pipe.pid) - pipe.close + IO.pipe {|r, w| + assert_equal(nil, r.pid) + assert_equal(nil, w.pid) + } + + begin + pipe = IO.popen(EnvUtil.rubybin, "r+") + pid1 = pipe.pid + pipe.puts "p $$" + pipe.close_write + pid2 = pipe.read.chomp.to_i + assert_equal(pid2, pid1) + assert_equal(pid2, pipe.pid) + ensure + pipe.close + end assert_raise(IOError) { pipe.pid } end @@ -2382,6 +2390,7 @@ End https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L2390 t.close 1.times do io = open(path,"w") + io.instance_variable_set(:@test_flush_in_finalizer2, true) io.print "hoge" end assert_nothing_raised(TypeError, bug3910) do @@ -2389,6 +2398,12 @@ End https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L2398 end t.close! } + ensure + ObjectSpace.each_object(File) {|f| + if f.instance_variables.include?(:@test_flush_in_finalizer2) + f.close + end + } end def test_readlines_limit_0 @@ -2999,41 +3014,41 @@ End https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L3014 bug8669 = '[ruby-core:56121] [Bug #8669]' str = "" - r, = IO.pipe - t = Thread.new { r.read(nil, str) } - sleep 0.1 until t.stop? - t.raise - sleep 0.1 while t.alive? - assert_nothing_raised(RuntimeError, bug8669) { str.clear } - ensure - t.kill + IO.pipe {|r,| + t = Thread.new { r.read(nil, str) } + sleep 0.1 until t.stop? + t.raise + sleep 0.1 while t.alive? + assert_nothing_raised(RuntimeError, bug8669) { str.clear } + assert_raise(RuntimeError) { t.join } + } end def test_readpartial_unlocktmp_ensure bug8669 = '[ruby-core:56121] [Bug #8669]' str = "" - r, = IO.pipe - t = Thread.new { r.readpartial(4096, str) } - sleep 0.1 until t.stop? - t.raise - sleep 0.1 while t.alive? - assert_nothing_raised(RuntimeError, bug8669) { str.clear } - ensure - t.kill + IO.pipe {|r, w| + t = Thread.new { r.readpartial(4096, str) } + sleep 0.1 until t.stop? + t.raise + sleep 0.1 while t.alive? + assert_nothing_raised(RuntimeError, bug8669) { str.clear } + assert_raise(RuntimeError) { t.join } + } end def test_sysread_unlocktmp_ensure bug8669 = '[ruby-core:56121] [Bug #8669]' str = "" - r, = IO.pipe - t = Thread.new { r.sysread(4096, str) } - sleep 0.1 until t.stop? - t.raise - sleep 0.1 while t.alive? - assert_nothing_raised(RuntimeError, bug8669) { str.clear } - ensure - t.kill + IO.pipe {|r, w| + t = Thread.new { r.sysread(4096, str) } + sleep 0.1 until t.stop? + t.raise + sleep 0.1 while t.alive? + assert_nothing_raised(RuntimeError, bug8669) { str.clear } + assert_raise(RuntimeError) { t.join } + } end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/