mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* io.c (rb_io_s_pipe): Close pipes if io_encoding_set() raises an
exception. (io_encoding_set_v): New function. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46225 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2ad2007307
commit
be4d1fd953
4 changed files with 115 additions and 65 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
Thu May 29 19:47:08 2014 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* 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@fsij.org>
|
Thu May 29 19:42:49 2014 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* lib/csv.rb (CSV.open): Close the opened file when an exception
|
* lib/csv.rb (CSV.open): Close the opened file when an exception
|
||||||
|
|
29
io.c
29
io.c
|
@ -9384,6 +9384,21 @@ io_encoding_set(rb_io_t *fptr, VALUE v1, VALUE v2, VALUE opt)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static VALUE
|
||||||
pipe_pair_close(VALUE rw)
|
pipe_pair_close(VALUE rw)
|
||||||
{
|
{
|
||||||
|
@ -9458,6 +9473,7 @@ rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
|
||||||
VALUE r, w, args[3], v1, v2;
|
VALUE r, w, args[3], v1, v2;
|
||||||
VALUE opt;
|
VALUE opt;
|
||||||
rb_io_t *fptr, *fptr2;
|
rb_io_t *fptr, *fptr2;
|
||||||
|
struct io_encoding_set_args ies_args;
|
||||||
int fmode = 0;
|
int fmode = 0;
|
||||||
VALUE ret;
|
VALUE ret;
|
||||||
|
|
||||||
|
@ -9475,7 +9491,18 @@ rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
|
||||||
rb_jump_tag(state);
|
rb_jump_tag(state);
|
||||||
}
|
}
|
||||||
GetOpenFile(r, fptr);
|
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[1] = INT2NUM(pipes[1]);
|
||||||
args[2] = INT2FIX(O_WRONLY);
|
args[2] = INT2FIX(O_WRONLY);
|
||||||
w = rb_protect(io_new_instance, (VALUE)args, &state);
|
w = rb_protect(io_new_instance, (VALUE)args, &state);
|
||||||
|
|
|
@ -1087,13 +1087,17 @@ class TestIO < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_dup
|
def test_dup
|
||||||
ruby do |f|
|
ruby do |f|
|
||||||
f2 = f.dup
|
begin
|
||||||
f.puts "foo"
|
f2 = f.dup
|
||||||
f2.puts "bar"
|
f.puts "foo"
|
||||||
f.close_write
|
f2.puts "bar"
|
||||||
f2.close_write
|
f.close_write
|
||||||
assert_equal("foo\nbar\n", f.read)
|
f2.close_write
|
||||||
assert_equal("", f2.read)
|
assert_equal("foo\nbar\n", f.read)
|
||||||
|
assert_equal("", f2.read)
|
||||||
|
ensure
|
||||||
|
f2.close
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1396,18 +1400,22 @@ class TestIO < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_pid
|
def test_pid
|
||||||
r, w = IO.pipe
|
IO.pipe {|r, w|
|
||||||
assert_equal(nil, r.pid)
|
assert_equal(nil, r.pid)
|
||||||
assert_equal(nil, w.pid)
|
assert_equal(nil, w.pid)
|
||||||
|
}
|
||||||
|
|
||||||
pipe = IO.popen(EnvUtil.rubybin, "r+")
|
begin
|
||||||
pid1 = pipe.pid
|
pipe = IO.popen(EnvUtil.rubybin, "r+")
|
||||||
pipe.puts "p $$"
|
pid1 = pipe.pid
|
||||||
pipe.close_write
|
pipe.puts "p $$"
|
||||||
pid2 = pipe.read.chomp.to_i
|
pipe.close_write
|
||||||
assert_equal(pid2, pid1)
|
pid2 = pipe.read.chomp.to_i
|
||||||
assert_equal(pid2, pipe.pid)
|
assert_equal(pid2, pid1)
|
||||||
pipe.close
|
assert_equal(pid2, pipe.pid)
|
||||||
|
ensure
|
||||||
|
pipe.close
|
||||||
|
end
|
||||||
assert_raise(IOError) { pipe.pid }
|
assert_raise(IOError) { pipe.pid }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2382,6 +2390,7 @@ End
|
||||||
t.close
|
t.close
|
||||||
1.times do
|
1.times do
|
||||||
io = open(path,"w")
|
io = open(path,"w")
|
||||||
|
io.instance_variable_set(:@test_flush_in_finalizer2, true)
|
||||||
io.print "hoge"
|
io.print "hoge"
|
||||||
end
|
end
|
||||||
assert_nothing_raised(TypeError, bug3910) do
|
assert_nothing_raised(TypeError, bug3910) do
|
||||||
|
@ -2389,6 +2398,12 @@ End
|
||||||
end
|
end
|
||||||
t.close!
|
t.close!
|
||||||
}
|
}
|
||||||
|
ensure
|
||||||
|
ObjectSpace.each_object(File) {|f|
|
||||||
|
if f.instance_variables.include?(:@test_flush_in_finalizer2)
|
||||||
|
f.close
|
||||||
|
end
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_readlines_limit_0
|
def test_readlines_limit_0
|
||||||
|
@ -2999,41 +3014,41 @@ End
|
||||||
bug8669 = '[ruby-core:56121] [Bug #8669]'
|
bug8669 = '[ruby-core:56121] [Bug #8669]'
|
||||||
|
|
||||||
str = ""
|
str = ""
|
||||||
r, = IO.pipe
|
IO.pipe {|r,|
|
||||||
t = Thread.new { r.read(nil, str) }
|
t = Thread.new { r.read(nil, str) }
|
||||||
sleep 0.1 until t.stop?
|
sleep 0.1 until t.stop?
|
||||||
t.raise
|
t.raise
|
||||||
sleep 0.1 while t.alive?
|
sleep 0.1 while t.alive?
|
||||||
assert_nothing_raised(RuntimeError, bug8669) { str.clear }
|
assert_nothing_raised(RuntimeError, bug8669) { str.clear }
|
||||||
ensure
|
assert_raise(RuntimeError) { t.join }
|
||||||
t.kill
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_readpartial_unlocktmp_ensure
|
def test_readpartial_unlocktmp_ensure
|
||||||
bug8669 = '[ruby-core:56121] [Bug #8669]'
|
bug8669 = '[ruby-core:56121] [Bug #8669]'
|
||||||
|
|
||||||
str = ""
|
str = ""
|
||||||
r, = IO.pipe
|
IO.pipe {|r, w|
|
||||||
t = Thread.new { r.readpartial(4096, str) }
|
t = Thread.new { r.readpartial(4096, str) }
|
||||||
sleep 0.1 until t.stop?
|
sleep 0.1 until t.stop?
|
||||||
t.raise
|
t.raise
|
||||||
sleep 0.1 while t.alive?
|
sleep 0.1 while t.alive?
|
||||||
assert_nothing_raised(RuntimeError, bug8669) { str.clear }
|
assert_nothing_raised(RuntimeError, bug8669) { str.clear }
|
||||||
ensure
|
assert_raise(RuntimeError) { t.join }
|
||||||
t.kill
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_sysread_unlocktmp_ensure
|
def test_sysread_unlocktmp_ensure
|
||||||
bug8669 = '[ruby-core:56121] [Bug #8669]'
|
bug8669 = '[ruby-core:56121] [Bug #8669]'
|
||||||
|
|
||||||
str = ""
|
str = ""
|
||||||
r, = IO.pipe
|
IO.pipe {|r, w|
|
||||||
t = Thread.new { r.sysread(4096, str) }
|
t = Thread.new { r.sysread(4096, str) }
|
||||||
sleep 0.1 until t.stop?
|
sleep 0.1 until t.stop?
|
||||||
t.raise
|
t.raise
|
||||||
sleep 0.1 while t.alive?
|
sleep 0.1 while t.alive?
|
||||||
assert_nothing_raised(RuntimeError, bug8669) { str.clear }
|
assert_nothing_raised(RuntimeError, bug8669) { str.clear }
|
||||||
ensure
|
assert_raise(RuntimeError) { t.join }
|
||||||
t.kill
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2142,32 +2142,34 @@ EOT
|
||||||
|
|
||||||
def test_textmode_paragraph_nonasciicompat
|
def test_textmode_paragraph_nonasciicompat
|
||||||
bug3534 = ['[ruby-dev:41803]', '[Bug #3534]']
|
bug3534 = ['[ruby-dev:41803]', '[Bug #3534]']
|
||||||
r, w = IO.pipe
|
IO.pipe {|r, w|
|
||||||
[Encoding::UTF_32BE, Encoding::UTF_32LE,
|
[Encoding::UTF_32BE, Encoding::UTF_32LE,
|
||||||
Encoding::UTF_16BE, Encoding::UTF_16LE,
|
Encoding::UTF_16BE, Encoding::UTF_16LE,
|
||||||
Encoding::UTF_8].each do |e|
|
Encoding::UTF_8].each do |e|
|
||||||
r.set_encoding(Encoding::US_ASCII, e)
|
r.set_encoding(Encoding::US_ASCII, e)
|
||||||
wthr = Thread.new{ w.print(bug3534[0], "\n\n\n\n", bug3534[1], "\n") }
|
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[0]+"\n\n").encode(e), r.gets(""), bug3534[0])
|
||||||
assert_equal((bug3534[1]+"\n").encode(e), r.gets(), bug3534[1])
|
assert_equal((bug3534[1]+"\n").encode(e), r.gets(), bug3534[1])
|
||||||
wthr.join
|
wthr.join
|
||||||
end
|
end
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_binmode_paragraph_nonasciicompat
|
def test_binmode_paragraph_nonasciicompat
|
||||||
bug3534 = ['[ruby-dev:41803]', '[Bug #3534]']
|
bug3534 = ['[ruby-dev:41803]', '[Bug #3534]']
|
||||||
r, w = IO.pipe
|
IO.pipe {|r, w|
|
||||||
r.binmode
|
r.binmode
|
||||||
w.binmode
|
w.binmode
|
||||||
[Encoding::UTF_32BE, Encoding::UTF_32LE,
|
[Encoding::UTF_32BE, Encoding::UTF_32LE,
|
||||||
Encoding::UTF_16BE, Encoding::UTF_16LE,
|
Encoding::UTF_16BE, Encoding::UTF_16LE,
|
||||||
Encoding::UTF_8].each do |e|
|
Encoding::UTF_8].each do |e|
|
||||||
r.set_encoding(Encoding::US_ASCII, e)
|
r.set_encoding(Encoding::US_ASCII, e)
|
||||||
wthr = Thread.new{ w.print(bug3534[0], "\n\n\n\n", bug3534[1], "\n") }
|
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[0]+"\n\n").encode(e), r.gets(""), bug3534[0])
|
||||||
assert_equal((bug3534[1]+"\n").encode(e), r.gets(), bug3534[1])
|
assert_equal((bug3534[1]+"\n").encode(e), r.gets(), bug3534[1])
|
||||||
wthr.join
|
wthr.join
|
||||||
end
|
end
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_puts_widechar
|
def test_puts_widechar
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue